2.首页主题魔改:文章容器布局

2.首页主题魔改:文章容器布局

前言:功能介绍与重要提示

本指南将引导您修改 Anzhiyu 主题的首页文章列表布局,实现更具设计感的分栏卡片式效果(图片与信息左右分离),提供的效果图所示。

image-20250719192825811

警告: 这同样是一项“魔改”操作,会覆盖主题的核心文件。在开始前,强烈建议您备份 themes/anzhiyu 文件夹,以便在出现问题时可以随时恢复。


第一步:替换核心布局 Mixin 文件

此修改的核心是替换一个负责渲染文章卡片的模板。

  1. 找到目标文件
    themes/anzhiyu/layout/includes/mixins/post-ui.pug
  • (这个文件是一个 Pug 混入(mixin),可以理解为一个“可重用模板”,专门负责渲染文章列表中的每一个卡片项。)
  1. 替换内容:将这个文件的全部内容,用下面提供的完整代码进行覆盖。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    - let maxDate = 0
    each item in site.posts.data
    if item.date > maxDate
    - maxDate = item.date
    mixin postUI(posts)
    each article , index in page.posts.data
    - let link = article.link || article.path
    div(class = (index === 0 ? 'recent-post-item lastestpost-item' : 'recent-post-item') onclick=`pjax.loadUrl('${url_for(link)}')`)
    -
    let title = article.title || _p('no_title')
    const position = theme.cover.position
    let leftOrRight = position === 'both'
    ? index%2 == 0 ? 'left' : 'right'
    : position === 'left' ? 'left' : 'right'
    let post_cover = article.cover
    let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
    -
    - const new_post = is_current('/') && (maxDate === article.date)

    if post_cover && theme.cover.index_enable
    .post_cover(class=leftOrRight)
    .recent-post-info-top-tips(class=leftOrRight)
    if (is_home() && (article.top || article.sticky > 0))
    span.article-meta.sticky-warp
    i.anzhiyufont.anzhiyu-icon-thumbtack.sticky
    span.sticky= _p('sticky')
    if (theme.post_meta.page.categories && article.categories.data.length > 0)
    each item, index in article.categories.data
    .article-categories-original
    i.fas.fa-shapes
    =item.name
    if new_post
    span.newPost
    i.fas.fa-star
    span 最新
    a.unvisited-post(href=url_for(link) title=title) 未读
    a(href=url_for(link) title=title style='display: flex;height: 100%;')
    img.post_bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=title style='pointer-events: none')

    .recent-post-info(class=no_cover)
    .recent-post-info-top
    a.article-title(href=url_for(link) title=title)= title
    .article-meta-wrap
    if (theme.post_meta.page.date_type)
    span.post-meta-date
    if (theme.post_meta.page.date_type === 'both')
    i.anzhiyufont.anzhiyu-icon-calendar-alt(style=`${theme.post_meta.page.date_format==="simple" ? "display:none":""}`)
    span.article-meta-label=_p('post.created')
    time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date) time=full_date(article.date))=date(article.date, config.date_format)
    span.article-meta-separator
    i.anzhiyufont.anzhiyu-icon-history(style=`font-size: 15px; ${theme.post_meta.page.date_format==="simple" ? "display:none":""}`)
    span.article-meta-label=_p('post.updated')
    time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated) time=full_date(article.updated))=date(article.updated, config.date_format)
    else
    - let data_type_updated = theme.post_meta.page.date_type === 'updated'
    - let date_type = data_type_updated ? 'updated' : 'date'
    - let date_type_other = data_type_updated ? 'date' : 'updated'
    - let date_icon = data_type_updated ? 'anzhiyu-icon-history' :'anzhiyu-icon-calendar-days'
    - let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
    - let date_title_other = data_type_updated ? _p('post.created') : _p('post.updated')
    i.anzhiyufont(class=date_icon style=`font-size: 15px; ${theme.post_meta.page.date_format==="simple" ? "display:none":""}`)
    span.article-meta-label=date_title
    time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]) time=full_date(article[date_type]))=date(article[date_type], config.date_format)
    time(datetime=date_xml(article[date_type_other]), class="time_hidden", title=date_title_other + ' ' + full_date(article[date_type_other]) time=full_date(article[date_type_other]))=date(article[date_type_other], config.date_format)
    if (theme.post_meta.page.tags && article.tags.data.length > 0)
    span.article-meta.tags
    each item, index in article.tags.data
    a(href=url_for(item.path) event.cancelbubble onclick="window.event.cancelBubble=true;").article-meta__tags
    span
    i.anzhiyufont.anzhiyu-icon-hashtag
    =item.name

    mixin countBlockInIndex
    - needLoadCountJs = true
    span.article-meta
    span.article-meta-separator
    i.anzhiyufont.anzhiyu-icon-comments
    if block
    block
    span.article-meta-label= ' ' + _p('card_post_count')

    if theme.comments.card_post_count
    case theme.comments.use[0]
    when 'Valine'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.valine-comment-count(data-xid=url_for(link))
    i.anzhiyufont.anzhiyu-icon-spinner.anzhiyu-spin
    when 'Waline'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.waline-comment-count(id=url_for(link))
    i.anzhiyufont.anzhiyu-icon-spinner.anzhiyu-spin
    when 'Twikoo'
    +countBlockInIndex
    a.twikoo-count(href=url_for(link) + '#post-comment' tabindex="-1")
    i.anzhiyufont.anzhiyu-icon-spinner.anzhiyu-spin
    when 'Artalk'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.artalk-count(data-page-key=url_for(link))
    i.anzhiyufont.anzhiyu-icon-spinner.anzhiyu-spin

    //- Display the article introduction on homepage
    case theme.index_post_content.method
    when false
    - break
    when 1
    .content!= article.description
    when 2
    if article.description
    .content!= article.description
    else
    - const content = strip_html(article.content)
    - let expert = content.substring(0, theme.index_post_content.length)
    - content.length > theme.index_post_content.length ? expert += ' ...' : ''
    .content!= expert
    default
    - const content = strip_html(article.content)
    - let expert = content.substring(0, theme.index_post_content.length)
    - content.length > theme.index_post_content.length ? expert += ' ...' : ''
    .content!= expert

    if theme.ad && theme.ad.index
    if (index + 1) % 3 == 0
    .recent-post-item.ads-wrap!=theme.ad.index

第二步:添加自定义样式文件
  1. 创建CSS文件

    • themes/anzhiyu/source/css/ 目录下,新建一个文件,命名为 post-ui.css
  2. 粘贴CSS代码

  • 将下面的CSS代码完整复制到您刚创建的 post-ui.css 文件中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
        /* 首页布局 摘要 标签 */
    #recent-posts > .recent-post-item > .recent-post-info {
    display: flex !important;
    flex-direction: column !important;
    padding: 0 32px !important;
    justify-content: center !important;
    gap: 8px;
    }

    .recent-post-info-top {
    margin-bottom: 50px !important;
    }

    #content-inner #recent-posts > .recent-post-item > .recent-post-info > .content {
    opacity: 1 !important;
    height: auto !important;
    line-height: 1.5 !important;
    margin-top: 0 !important;
    font-size: 15px !important;
    }

    .recent-post-info-top-tips {
    display: flex;
    gap: 10px;
    position: absolute;
    z-index: 999;
    background: rgb(255 255 255 / 20%);
    padding: 0 5px;
    margin: 10px !important;
    border-radius: 6px;
    color: var(--anzhiyu-white);
    backdrop-filter: blur(5px);
    }

    .recent-post-info-top-tips.right {
    right: 0;
    }

    .recent-post-info-top-tips.left {
    left: 0;
    }

    [data-theme='dark'] .recent-post-info-top-tips {
    filter: brightness(0.8);
    }
    .article-meta-wrap {
    position: inherit !important;
    padding: 0 !important;
    }

    .article-meta.sticky-warp,
    span.newPost {
    color: #ff7242;
    }
    .article-categories-original,
    span.newPost {
    display: flex;
    gap: 5px;
    align-items: center;
    }

    span.article-meta.tags,span.post-meta-date {
    height: 26px;
    line-height: 26px;
    }

    .recent-post-info .recent-post-info-top {
    padding: 0 !important;
    }

    .unvisited-post {
    display: none !important;
    }

    @media screen and (max-width: 768px) {
    #recent-posts > .recent-post-item > .recent-post-info > .article-meta-wrap {
    bottom: 0 !important;
    }
    .recent-post-info-top-tips.right {
    right: inherit;
    }
    }

    /* --- 首页文章卡片擦亮动画效果 --- */

    #recent-posts > .recent-post-item:not(a)::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 200%;
    background: linear-gradient(to right, transparent, white, transparent);
    transform: translateX(-200%);
    transition: transform 0.5s linear;
    z-index: 1; /* 确保扫光效果在图片上方 */
    }

    #recent-posts > .recent-post-item:not(a):hover::before {
    transform: translateX(100%) skewX(-60deg);
    }
    ​```

第三步:在主题配置中注入新样式
  1. 打开主题配置文件 (themes/anzhiyu/_config.yml)。

  2. 找到 inject: 配置项,在 head: 列表中添加我们新建的CSS文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    inject:
    head:
    # - 首页媒体样式
    - <link rel="stylesheet" href="/css/index_media.css">
    # - 文章样式
    - <link rel="stylesheet" href="/css/post-ui.css">
    bottom:
    # - 其他 bottom 内容
    - <script src="/js/index_media.js"></script>


第四步:确保配置项开启

1.设置封面位置为左右交替

1
2
3
4
cover:
# 首页文章封面显示的位置
# left/right/both
position: both # 改为 both (左右交替)