WordPress'使用 Jekyll 和 Liquid 标签的 body_class 功能

发布于 2025-01-03 16:51:10 字数 1136 浏览 7 评论 0原文

我不是 WordPress 的忠实粉丝,但我认为 WordPress 做对的一件事是 body_class 功能。

我想使用 Jekyll液体标签。我希望能够进行这样的调用,

<body class="{% body_class %}">

它将自动生成基于以下内容的类:

  • Jekyll Template
  • 当前帖子(如果有)
  • 当前页面(如果有)
  • 当前类别(如果有)

示例:

/index.html 使用默认布局将导致

<body class="layout-default page-index">

/_posts/2012-01-01-my-unique-entry.markdown 和 blog.html 布局会导致

<body class="layout-blog post-my-unique-entry">

我知道我可以使用 YAML front Matter 实现所有这些,但如果我可以自动执行此操作以删除另一个重复的变量,那么会保持理想状态。

从我迄今为止的尝试来看,这就是我正在采取的策略:

class BodyClassTag < Liquid::Tag

  def initialize(tag_name, name, tokens)
    super tag_name, name, tokens
  end

  def render(context)
    # Build string from Jekyll instance variables possible here?
  end

end

Liquid::Template.register_tag('body_class', BodyClassTag)

关于这是否可能的任何想法,以及如果可能的话应该结合什么?

I'm not the biggest fan of WordPress, but I think the one thing that WordPress gets right is the body_class functionality.

I want to recreate this functionality using Jekyll and Liquid Tags. I want to be able to make a call like

<body class="{% body_class %}">

That would automatically generate classes based on:

  • Jekyll Template
  • Current Post (if any)
  • Current Page (if any)
  • Current Category (if any)

Examples:

/index.html with default layout would result in

<body class="layout-default page-index">

/_posts/2012-01-01-my-unique-entry.markdown with blog.html layout would result in

<body class="layout-blog post-my-unique-entry">

I know I can achieve all this using YAML front matter, but If I can automate this to remove one more repetitious variable, that would be ideal.

From what I've attempted so far, this is the strategy I'm taking:

class BodyClassTag < Liquid::Tag

  def initialize(tag_name, name, tokens)
    super tag_name, name, tokens
  end

  def render(context)
    # Build string from Jekyll instance variables possible here?
  end

end

Liquid::Template.register_tag('body_class', BodyClassTag)

Any ideas on if this is possible, and what to tie into if so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蓝颜夕 2025-01-10 16:51:11

这是基于我刚刚进入 Jekyll 的事实,但希望我的解决方案对某人有所帮助。我使用了 Front Matter 变量和简单的 if 语句。以下是使用“关于”页面作为示例的两个简单步骤。

在“关于”页面中,将类似以下内容的变量添加到“Front Matter”中(您可以使用任何您想要的名称):

body_class: page-about

更详细的示例:

---
title: About
permalink: "/about/"
layout: page
body_class: page-about
---

现在将此 if 语句添加到您的 body 标记中:

{% if page.body_class %}class="{{ page.body_class }}"{% endif %}

更详细的示例:

<body {% if page.body_class %}class="{{ page.body_class }}"{% endif %}>

如果 body_class 变量存在,则为一个类被添加到身体中。如果 Front Matter 页面中不存在 body_class 变量,则不会添加任何类。

如果您想向主体中已存在的类添加一个额外的类,这应该也有效(确保之前存在空间:

<body class="main{% if page.body_class %} {{ page.body_class }}{% endif %}">

我已经确认这对我来说很有效,希望其他人可以受益。

This is late based on the fact that I am just now getting into Jekyll but hopefully my solution will be helpful to someone. I used a Front Matter variable along with a simple if statement. So here are the two simple steps using an About page as an example.

In your About page add something like this variable to your Front Matter (you can use any name you would like):

body_class: page-about

More detailed example:

---
title: About
permalink: "/about/"
layout: page
body_class: page-about
---

Now add this if statement to your body tag:

{% if page.body_class %}class="{{ page.body_class }}"{% endif %}

More detailed example:

<body {% if page.body_class %}class="{{ page.body_class }}"{% endif %}>

If the body_class variable exists, a class is added to the body. If the body_class variable doesn't exist in the page Front Matter, no class is added.

If you would like to add an extra class to a class that already exists in the body, this should work as well (make sure the space exists before :

<body class="main{% if page.body_class %} {{ page.body_class }}{% endif %}">

I have confirmed this works well for me and hopefully someone else can benefit.

野侃 2025-01-10 16:51:11

我将其添加到 default.html

<body class="{{ page.id | remove:'/' }}">

希望这对大家有帮助,

I added this to default.html

<body class="{{ page.id | remove:'/' }}">

Hope this helps out guys,

烈酒灼喉 2025-01-10 16:51:11

我更喜欢以特异性降序提供多个样式挂钩,如下所示:

<body class="
{{ post.title | downcase | replace:' ','-' | replace:',','' | strip_html }}
{% if page.category %} category-{{ page.category }}{% endif %}
{% if page.layout-class %} layout-{{ page.layout-class }}{% endif %}
">

这会创建如下输出:

<body class="my-stackoverflow-design category-portfolio layout-category">

我在我的 front-matter 中使用页面布局类,因为当前有 Jekyll 中的一个错误,意味着 {{ page.layout }} 不起作用;无论使用的布局如何,它总是返回“默认”。

I prefer to provide multiple styling hooks in decreasing order of specificity, like so:

<body class="
{{ post.title | downcase | replace:' ','-' | replace:',','' | strip_html }}
{% if page.category %} category-{{ page.category }}{% endif %}
{% if page.layout-class %} layout-{{ page.layout-class }}{% endif %}
">

Which creates an output like:

<body class="my-stackoverflow-design category-portfolio layout-category">

I'm using a page-layout class in my front-matter as there is currently a bug in Jekyll that means {{ page.layout }} doesn't work; it always returns 'default' irrespective of the layout in use.

一梦等七年七年为一梦 2025-01-10 16:51:10

我可能是错的,但我不确定你是否需要使用 ruby​​ 来实现这一切;例如,布局可以从 Liquid 变量 page 中获得。

所以在你的布局文件中,你可以这样做:

{% capture layout %}{% if page.layout %}layout-{{ page.layout }}{% endif %}{% endcapture %}

<body class="{{ layout }}">

“页面和帖子的唯一标识符”有点复杂,因为 Jekyll 中没有这样的概念。但是,使用 page.url 并用“-”替换斜杠,您可以获得几乎相同的结果。如果您没有看到帖子,那么您看到的是一个页面。所以:

{% capture id_prefix %}{% if post %}post{% else %}page{% endif %}{% endcapture %}
{% capture id %}{{ id_prefix }}-{{ page.url | replace:'/','-' }}{% endcapture %}

<body class="{{ layout }} {{ id }}">

您可以非常类似地计算类别(请记住,一篇文章可以有多个类别)。

警告:上面的所有代码都是我从头开始完成的,根本没有经过测试。

I might be wrong, but I'm not sure you need to use ruby for all that; for example, the layout, is available from in the liquid variable page.

So in your layout file, you can do this:

{% capture layout %}{% if page.layout %}layout-{{ page.layout }}{% endif %}{% endcapture %}

<body class="{{ layout }}">

The "unique identifier of pages and posts" is a bit more complex, since there is no such concept in Jekyll. But you can get pretty much the same using page.url and replacing slashes by '-'. If you are not seeing a post, then you are seeing a page. So:

{% capture id_prefix %}{% if post %}post{% else %}page{% endif %}{% endcapture %}
{% capture id %}{{ id_prefix }}-{{ page.url | replace:'/','-' }}{% endcapture %}

<body class="{{ layout }} {{ id }}">

You can calculate category pretty similarly (remember though that a post can have more than one category).

Warning: all the code above has been done from the top of my head, and not tested at all.

非要怀念 2025-01-10 16:51:10

这个问题的答案中收集的信息,我能够想出一个几乎完全按照我想要的方式运行的解决方案。这是我定制的液体标签。如果有人想实现类似的目标,请在此发布。

class BodyClassTag < Liquid::Tag  

  def prefixed_body_class(prefix, id)
    id = id.gsub(/\.\w*?$/, '') # Remove extension from url
    id = id.gsub(/[-\/]/, '_')  # Replace '-' and '/' with underscore
    id = id.gsub(/^_/, '')      # Remove leading '_'

    case prefix
    when "class"
      prefix = ""
    else
      prefix = "#{prefix}_"
    end

    "#{prefix}#{id}"
  end

  def render(context)
    page = context.environments.first["page"]
    classes = []

    %w[class url categories tags layout].each do |prop|
      next unless page.has_key?(prop)
      if page[prop].kind_of?(Array)
        page[prop].each { |proper| classes.push prefixed_body_class(prop, proper) }
      else
        classes.push prefixed_body_class(prop, page[prop])
      end
    end

    classes.join(" ")
  end

end
Liquid::Template.register_tag('body_class', BodyClassTag)

With the information gleaned from the answers on this question, I was able to come up with a solution that behaves pretty much exactly the way I wanted it to. This is my custom liquid tag. Posting here in case anyone wants to achieve something similar.

class BodyClassTag < Liquid::Tag  

  def prefixed_body_class(prefix, id)
    id = id.gsub(/\.\w*?$/, '') # Remove extension from url
    id = id.gsub(/[-\/]/, '_')  # Replace '-' and '/' with underscore
    id = id.gsub(/^_/, '')      # Remove leading '_'

    case prefix
    when "class"
      prefix = ""
    else
      prefix = "#{prefix}_"
    end

    "#{prefix}#{id}"
  end

  def render(context)
    page = context.environments.first["page"]
    classes = []

    %w[class url categories tags layout].each do |prop|
      next unless page.has_key?(prop)
      if page[prop].kind_of?(Array)
        page[prop].each { |proper| classes.push prefixed_body_class(prop, proper) }
      else
        classes.push prefixed_body_class(prop, page[prop])
      end
    end

    classes.join(" ")
  end

end
Liquid::Template.register_tag('body_class', BodyClassTag)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文