Skip to content

Commit

Permalink
Merge pull request #2498 from tangly1024/feat/theme-example-custom-co…
Browse files Browse the repository at this point in the history
…nfig

Example主题支持配置:标题栏背景、文章页布局
  • Loading branch information
tangly1024 committed Jun 14, 2024
2 parents e3ce491 + 45aec39 commit ef49780
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 75 deletions.
3 changes: 2 additions & 1 deletion themes/example/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { MenuList } from './MenuList'

/**
* 网站顶部
* LOGO 和 菜单
* @returns
*/
export const Header = props => {
return (
<header className='w-full px-6 bg-white dark:bg-black relative z-20'>
<div className='container mx-auto max-w-4xl md:flex justify-between items-center'>
<div className='mx-auto max-w-4xl md:flex justify-between items-center'>
<Link
href='/'
className='py-6 w-full text-center md:text-left md:w-auto text-gray-dark no-underline flex justify-center items-center'>
Expand Down
2 changes: 1 addition & 1 deletion themes/example/components/MenuList.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const MenuList = props => {

return (
<nav className='w-full bg-white md:pt-0 px-6 relative z-20 border-t border-b border-gray-light dark:border-hexo-black-gray dark:bg-black'>
<div className='container mx-auto max-w-4xl md:flex justify-between items-center text-sm md:text-md md:justify-start'>
<div className='mx-auto max-w-4xl md:flex justify-between items-center text-sm md:text-md md:justify-start'>
<ul className='w-full text-center md:text-left flex flex-wrap justify-center items-stretch md:justify-start md:items-start'>
{links.map((link, index) => (
<MenuItemDrop key={index} link={link} />
Expand Down
63 changes: 43 additions & 20 deletions themes/example/components/SideBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { siteConfig } from '@/lib/config'
import { useGlobal } from '@/lib/global'
import dynamic from 'next/dynamic'
import Link from 'next/link'
import CONFIG from '../config'
import Announcement from './Announcement'
const ExampleRecentComments = dynamic(
() => import('./RecentCommentListForExample')
Expand All @@ -13,10 +14,26 @@ const ExampleRecentComments = dynamic(
*/
export const SideBar = props => {
const { locale } = useGlobal()
const { latestPosts, categoryOptions, notice } = props
const { latestPosts, categoryOptions, notice, post } = props
// 评论相关
const COMMENT_WALINE_SERVER_URL = siteConfig(
'COMMENT_WALINE_SERVER_URL',
false
)
const COMMENT_WALINE_RECENT = siteConfig('COMMENT_WALINE_RECENT', false)

// 文章详情页特殊布局
const HIDDEN_NOTIFICATION =
post && siteConfig('EXAMPLE_ARTICLE_HIDDEN_NOTIFICATION', false, CONFIG)

// 文章详情页左右布局改为上下布局
const LAYOUT_VERTICAL =
post && siteConfig('EXAMPLE_ARTICLE_LAYOUT_VERTICAL', false, CONFIG)

return (
<div className='w-full md:w-64 sticky top-8'>
<aside className='rounded shadow overflow-hidden mb-6'>
<>
{/* 分类 */}
<aside className='w-full rounded shadow overflow-hidden mb-6'>
<h3 className='text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b'>
{locale.COMMON.CATEGORY}
</h3>
Expand All @@ -34,7 +51,7 @@ export const SideBar = props => {
{' '}
<a
href={`/category/${category.name}`}
className='text-gray-darkest text-sm'>
className='text-gray-darkest text-sm hover:underline'>
{category.name}({category.count})
</a>
</li>
Expand All @@ -44,7 +61,9 @@ export const SideBar = props => {
</ul>
</div>
</aside>
<aside className='rounded shadow overflow-hidden mb-6'>

{/* 最新文章 */}
<aside className='w-full rounded shadow overflow-hidden mb-6'>
<h3 className='text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b'>
{locale.COMMON.LATEST_POSTS}
</h3>
Expand All @@ -58,7 +77,7 @@ export const SideBar = props => {
{' '}
<a
href={`/${p.slug}`}
className='text-gray-darkest text-sm'>
className='text-gray-darkest text-sm hover:underline'>
{p.title}
</a>
</li>
Expand All @@ -68,25 +87,29 @@ export const SideBar = props => {
</ul>
</div>
</aside>

{/* 公告 */}
{/* 公告栏 */}
<Announcement post={notice} />
{!HIDDEN_NOTIFICATION && <Announcement post={notice} />}

{/* 最近评论 */}
{siteConfig('COMMENT_WALINE_SERVER_URL') &&
siteConfig('COMMENT_WALINE_RECENT') && (
<aside className='rounded shadow overflow-hidden mb-6'>
<h3 className='text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b'>
{locale.COMMON.RECENT_COMMENTS}
</h3>
{COMMENT_WALINE_SERVER_URL && COMMENT_WALINE_RECENT && (
<aside className='w-full rounded shadow overflow-hidden mb-6'>
<h3 className='text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b'>
{locale.COMMON.RECENT_COMMENTS}
</h3>

<div className='p-4'>
<ExampleRecentComments />
</div>
</aside>
)}

<div className='p-4'>
<ExampleRecentComments />
</div>
</aside>
)}
<aside className='rounded overflow-hidden mb-6'>
{/* 宠物挂件 */}
<aside
className={`rounded overflow-hidden mb-6 ${LAYOUT_VERTICAL ? 'hidden md:fixed right-4 bottom-20' : ''}`}>
<Live2D />
</aside>
</div>
</>
)
}
48 changes: 48 additions & 0 deletions themes/example/components/TitleBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import NotionIcon from '@/components/NotionIcon'
import { siteConfig } from '@/lib/config'
import { useGlobal } from '@/lib/global'
import CONFIG from '../config'

/**
* 标题栏
*/
export default function TitleBar(props) {
const { post } = props
const { fullWidth, siteInfo } = useGlobal()

const title = post?.title || siteConfig('TITLE')
const description = post?.description || siteConfig('AUTHOR')
const headerImage = post?.pageCoverThumbnail
? post.pageCoverThumbnail
: siteInfo?.pageCover

const TITLE_BG = siteConfig('EXAMPLE_TITLE_IMAGE', false, CONFIG)

return (
<>
{/* 标题栏 */}
{!fullWidth && (
<div className='relative overflow-hidden text-center px-6 py-12 mb-6 bg-gray-100 dark:bg-hexo-black-gray dark:border-hexo-black-gray border-b'>
<h1 className='title-1 relative text-xl md:text-4xl pb-4 z-10'>
{siteConfig('POST_TITLE_ICON') && (
<NotionIcon icon={post?.pageIcon} />
)}
{title}
</h1>
<p className='title-2 relative leading-loose text-gray-dark z-10'>
{description}
</p>
{TITLE_BG && (
<>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={headerImage}
className='absolute object-cover top-0 left-0 w-full h-full select-none opacity-70 z-0'
/>
</>
)}
</div>
)}
</>
)
}
7 changes: 6 additions & 1 deletion themes/example/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ const CONFIG = {
EXAMPLE_MENU_ARCHIVE: true, // 显示归档
EXAMPLE_MENU_SEARCH: true, // 显示搜索

EXAMPLE_POST_LIST_COVER: true // 列表显示文章封面
EXAMPLE_POST_LIST_COVER: true, // 列表显示文章封面

EXAMPLE_TITLE_IMAGE: false, // 标题栏,是否背景图片

// 文章页面布局
EXAMPLE_ARTICLE_LAYOUT_VERTICAL: false, // 文章详情,左右布局改为上下布局
EXAMPLE_ARTICLE_HIDDEN_NOTIFICATION: false // 文章详情隐藏公告
}
export default CONFIG
98 changes: 46 additions & 52 deletions themes/example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import Comment from '@/components/Comment'
import replaceSearchResult from '@/components/Mark'
import NotionIcon from '@/components/NotionIcon'
import NotionPage from '@/components/NotionPage'
import ShareBar from '@/components/ShareBar'
import { siteConfig } from '@/lib/config'
Expand All @@ -21,6 +20,7 @@ import { PostLock } from './components/PostLock'
import { PostMeta } from './components/PostMeta'
import SearchInput from './components/SearchInput'
import { SideBar } from './components/SideBar'
import TitleBar from './components/TitleBar'
import CONFIG from './config'
import { Style } from './style'

Expand All @@ -32,36 +32,15 @@ import { Style } from './style'
* @constructor
*/
const LayoutBase = props => {
const { children } = props
const { children, post } = props
const { onLoading, fullWidth, locale } = useGlobal()
const router = useRouter()
const { post, category, tag } = props

const title = post?.title || siteConfig('TITLE')
const description = post?.description || siteConfig('AUTHOR')
// 文章详情页左右布局改为上下布局
const LAYOUT_VERTICAL =
post && siteConfig('EXAMPLE_ARTICLE_LAYOUT_VERTICAL', false, CONFIG)

// 顶部如果是按照分类或标签查看文章列表,列表顶部嵌入一个横幅
// 如果是搜索,则列表顶部嵌入 搜索框
let slotTop = null
if (category) {
slotTop = (
<div className='pb-12'>
<i className='mr-1 fas fa-folder-open' />
{category}
</div>
)
} else if (tag) {
slotTop = <div className='pb-12'>#{tag}</div>
} else if (props.slotTop) {
slotTop = props.slotTop
} else if (router.route === '/search') {
// 嵌入一个搜索框在顶部
slotTop = (
<div className='pb-12'>
<SearchInput {...props} />
</div>
)
}
// 网站左右布局颠倒
const LAYOUT_SIDEBAR_REVERSE = siteConfig('LAYOUT_SIDEBAR_REVERSE', false)

return (
<div
Expand All @@ -71,33 +50,20 @@ const LayoutBase = props => {

{/* 页头 */}
<Header {...props} />
{/* 标题栏 */}
<TitleBar {...props} />

{/* 主体 */}
<div id='container-inner' className='w-full relative z-10'>
{/* 标题栏 */}
{!fullWidth && (
<div className='text-center px-6 py-12 mb-6 bg-gray-100 dark:bg-hexo-black-gray dark:border-hexo-black-gray border-b'>
<h1 className='text-xl md:text-4xl pb-4'>
{siteConfig('POST_TITLE_ICON') && (
<NotionIcon icon={post?.pageIcon} />
)}
{title}
</h1>
<p className='leading-loose text-gray-dark'>{description}</p>
</div>
)}

<div
id='container-wrapper'
className={
(JSON.parse(siteConfig('LAYOUT_SIDEBAR_REVERSE'))
? 'flex-row-reverse'
: '') +
'relative container mx-auto justify-center md:flex items-start py-8 px-2'
}>
className={`relative mx-auto justify-center md:flex py-8 px-2
${LAYOUT_SIDEBAR_REVERSE ? 'flex-row-reverse' : ''}
${LAYOUT_VERTICAL ? 'items-center flex-col' : 'items-start'}
`}>
{/* 内容 */}
<div
className={`w-full ${fullWidth ? '' : 'max-w-3xl'} xl:px-14 lg:px-4`}>
className={`${fullWidth ? '' : LAYOUT_VERTICAL ? 'max-w-5xl' : 'max-w-3xl'} w-full xl:px-14 lg:px-4`}>
<Transition
show={!onLoading}
appear={true}
Expand All @@ -109,13 +75,22 @@ const LayoutBase = props => {
leaveTo='opacity-0 -translate-y-16'
unmount={false}>
{/* 嵌入模块 */}
{slotTop}
{props.slotTop}
{children}
</Transition>
</div>

{/* 侧边栏 */}
{!fullWidth && <SideBar {...props} />}
{!fullWidth && (
<div
className={`${
LAYOUT_VERTICAL
? 'flex space-x-0 md:space-x-2 md:flex-row flex-col w-full max-w-5xl justify-center xl:px-14 lg:px-4'
: 'md:w-64 sticky top-8'
}`}>
<SideBar {...props} />
</div>
)}
</div>
</div>

Expand Down Expand Up @@ -150,8 +125,20 @@ const LayoutIndex = props => {
* @returns
*/
const LayoutPostList = props => {
const { category, tag } = props

return (
<>
{/* 显示分类 */}
{category && (
<div className='pb-12'>
<i className='mr-1 fas fa-folder-open' />
{category}
</div>
)}
{/* 显示标签 */}
{tag && <div className='pb-12'>#{tag}</div>}

{siteConfig('POST_LIST_STYLE') === 'page' ? (
<BlogListPage {...props} />
) : (
Expand Down Expand Up @@ -192,7 +179,7 @@ const LayoutSlug = props => {
{lock ? (
<PostLock validPassword={validPassword} />
) : (
<div id='article-wrapper' className='px-2'>
<div id='article-wrapper'>
<PostMeta post={post} />
<NotionPage post={post} />
<ShareBar post={post} />
Expand Down Expand Up @@ -237,7 +224,14 @@ const LayoutSearch = props => {
}
}, [router])

return <LayoutPostList {...props} />
return (
<>
<div className='pb-12'>
<SearchInput {...props} />
</div>
<LayoutPostList {...props} />
</>
)
}

/**
Expand Down

0 comments on commit ef49780

Please sign in to comment.