Discourse 主题入门设计师指南

所以,你对为 Discourse 设计自己的主题感兴趣?那你来对地方了:smile:

本指南将更侧重于在 Discourse 中处理主题的 SCSS/CSS 方面。如果你也熟悉 JS/EmberJs/Handlebars,你可以通过查看这份指南深入探索。

我将向你介绍我在 Discourse 中设计和主题化的个人方法。就像大多数事情一样,实现自己的设计有很多方式。我非常喜欢在使用 Inspector 工具时进行主题创作,并会在本文中向你展示几次我是如何做的。

主题设置准备

在继续之前,请先阅读 Discourse 主题使用入门指南 以及 主题结构…。此时不需要深入的知识,但这些文章会让你在开始之前对相关内容有更熟悉的感觉。

为了在 Discourse 中更好地进行主题设计,我建议进行以下设置,以提供最快、最流畅的设计流程。这些步骤将使你能够在进行修改时实时查看变化,而无需从 Discourse 站点管理面板“保存”并刷新。

完全可以通过管理控制台来完成本指南(前提是你拥有 Discourse 论坛的管理员权限。)

  • 安装 Discourse Theme CLI 并阅读该主题以了解其功能。
  • https://discourse.theme-creator.io/ 获取 API 密钥
    • 使用你的 Meta 账户登录
    • 点击 我的主题
    • 点击 API 密钥
    • 在弹出的模态框中,点击 生成 API 密钥 并复制为你生成的密钥(稍后我们会用到)

运行 Discourse Theme CLI

安装好 Discourse Theme CLI 并准备好 API 密钥后,打开你喜欢的文本编辑器或终端窗口,将工作目录更改为你希望设置主题文件夹的位置。

到达后,运行以下命令 discourse_theme new your_theme_name,并按如下方式填写提示:

  1. 你想给主题起什么名字? 选择你的主题名称

  2. 你想开始监控这个主题吗?

  3. 你的 Discourse 站点的根 URL 是什么? https://discourse.theme-creator.io/

  4. 你想将此站点名称存储…?

  5. 你的 API 密钥是什么? 输入你从主题生成器获取的 API 密钥

  6. 你想将此 API 密钥存储…?

  7. 当提示时,选择 创建并与新主题同步

  8. 当提示关于子主题组件时,选择 不操作

如果一切正常,你现在应该能够导航到 https://discourse.theme-creator.io/ 上的“我的主题”,并在左侧的主题列表中看到你的新主题。

要实时查看这些更改,点击你的主题名称,然后在信息区域底部点击 预览

Theme CLI 现在也在监控新创建目录中的任何更改,并会在每次更改时保存以及更新 theme-creator 上的主题。

第一步

Discourse Theme CLI 已在我们之前命令中指定的文件夹名称内为我们创建了主题脚手架。生成了很多我们不会使用的文件,因此我们将删除除以下内容之外的所有内容:

common/common.scss

desktop/desktop.scss

mobile/mobile.scss

about.json

在目录内,同时也运行 rm -rf .git 以移除 git 版本跟踪,本指南不需要它。

你的主题目录现在应该看起来像这样:

值得注意的是,添加到这些文件中的样式将在其各自的用例中呈现。common.scss 中的样式将应用于桌面端和移动端,而 desktop.scss 中的样式仅应用于桌面浏览,mobile.scss 中的样式仅应用于移动端视图。

Hello World(彩色版)

Discourse 使用 SCSS 进行样式设计,因此为了最好地利用样式,你可能想熟悉一下 SASS,但如果不熟悉,你仍然可以跟随本指南进行。

好的,现在让我们进入大家期待已久的内容……主题化!

目前,我们的 about.json 尚未定义任何 color_schemes,因此请将以下代码粘贴到该部分中然后保存。

{
  "name": "my theme",
  "about_url": null,
  "license_url": null,
  "assets": {},
  "color_schemes": {
    "Default": {
      "primary": "222222",
      "secondary": "ffffff",
      "tertiary": "0088cc",
      "quaternary": "e45735",
      "header_background": "ffffff",
      "header_primary": "333333",
      "highlight": "ffff4d",
      "danger": "e45735",
      "success": "009900",
      "love": "fa6c8d"
    }
  }
}

如果你打开了浏览器,你可能不会看到任何变化生效,因为这是在没有方案时使用的默认配色方案。

主题概览

为了在本指南中实际实现一些内容,我将带你基于这个配色方案创建一个简单的主题。

image

更改背景色 + 主文本颜色

让我们做一些非常简单的事情。我们将更改当前配色方案的 "Secondary" 值。将其更改为 "secondary": "EEF4F7"(这将更改背景颜色)。我们还将 "primary" 值更改为 "203243"


仅凭这一行,我们就已经改变了论坛的外观和感觉。仅通过编辑配色方案中的颜色就可以完成大量自定义。

配色方案的使用

以下所有键都在 about.json 文件中根据相应的配色方案名称定义。这些描述是很好的参考,可以帮助你理解每个变量名称的主要用途:

颜色 描述
primary 大多数文本、图标和边框
secondary 主背景色以及某些按钮的文本颜色
tertiary 链接、某些按钮、通知和强调色
quaternary 导航链接
header_background 站点标题的背景色
header_primary 站点标题中的文本和图标
highlight 页面上高亮元素的背景色,例如帖子和主题
danger 删除帖子和主题等操作的强调色
success 用于指示操作成功
love 点赞按钮的颜色

这些变量中的每一个都可以像这样在我们的 SCSS 文件中使用。

body {
  background-color: var(--primary);
}

每种颜色的其他版本也已创建供我们使用。诸如 var(--primary-medium)var(--primary-very-low) 之类的东西可用于获取同一颜色的不同色调。

让我们将“Default”配色方案中的其他颜色更改为与此匹配:

"Default": {
      "primary": "203243",
      "secondary": "EEF4F7",
      "tertiary": "416376",
      "quaternary": "5E99B9",
      "header_background": "FaFaFa",
      "header_primary": "EEF4F7",
      "highlight": "86BDDB",
      "danger": "8F393E",
      "success": "70DB82",
      "love": "FC94CB"
    }

:flashlight: 如果你在 theme creator 上预览主题时点击 样式指南 链接,然后在左侧菜单中点击“颜色”,你可以看到所有可用于 SCSS 文件的变量。

样式指南是创建自定义主题时查看的非常有用的部分。每个 Atom 都会向你展示应用你的样式后 Discourse 的某些元素将如何显示。

深入探索

有了上一部分的内容,我认为现在是时候更深入地了解仅使用 SCSS 在 Discourse 中可以做什么了。(提示:很多!)

样式化标题

你会注意到,我们对配色方案的先前更改使我们的标题有些不尽如人意。图标几乎看不见!

image

Discourse 标题包含一个容器(带有背景色),用于容纳站点徽标以及右侧的导航图标。所有这些都可以自定义。

自定义标题的目标类是 .d-header

在我们的 common/common.scss 文件中,添加以下内容:

.d-header {
  box-shadow: none;
  border-bottom: 1px solid var(--primary-low-mid);
  height: 5em;
}

这将移除标题的默认 box-shadow,增加一点高度,并设置 border-bottom 以提供一些分隔。

对于图标——在 .d-header SCSS 括号内,让我们添加以下嵌套代码。

.d-header {
  // ...之前的代码
  .d-icon {
    color: var(--primary-low-mid);
  }
}

看起来不错,但敏锐的眼睛会注意到增加的标题高度使它与其余 Discourse 论坛元素之间的空间变少了!

主区域和标题之间的间距由 #main-outlet 目标控制。让我们通过在 common/common.scss 文件底部添加以下内容来稍微增加这个间距。

#main-outlet {
  padding-top: 6.5em;
}

导航容器

导航容器包含以下部分。

image

最左侧区域是分类/标签筛选下拉菜单,接着是导航链接,最后是“新主题”按钮。

分类 / 标签下拉菜单

让我们对这个区域做一些更改。为此,将以下内容添加到你的 common.scss 文件中。

.navigation-container {
  .select-kit.combo-box {
    .select-kit-header {
      border-radius: 0.9em;
      background-color: var(--header_background);
    }
  }
}

在这里,我们针对 .select-kit-header 以给它们相同的 border-radius,以及更浅的背景色。

点击其中任何一个,都会打开一个下拉菜单。

目前,它也有硬角,所以让我们添加一些样式来将它们圆角化,并将背景色更改为与标题相同。

.navigation-container {
  .select-kit.combo-box {
    // ...之前的代码
    &.category-drop,
    &.tag-drop {
      .select-kit-body {
        border-radius: 0.9em;
        background-color: var(--header_background);

        .select-kit-collection {
          background-color: var(--header_background);
          border-top-left-radius: 0px;
          border-top-right-radius: 0px;
        }
      }
    }
  }
}

结果如下所示…

如果你仔细观察,你会发现我们的更改在搜索区域的右上角留下了一条可见的小边框。

让我们通过在浏览器 Inspector 中查看来修复这个问题。这始终是一个超级有用的工具,用于学习我们需要针对哪些类/ID 以正确应用样式。

当下拉菜单可见时,右键点击搜索区域并在浏览器中“检查”该元素。

我们可以看到该输入位于一个具有 select-kit-filter 类的 div 内。

如果我们查看应用于此选择器的规则,我们可以看到它目前具有 border-top 和 border-bottom,以及一些应用的 padding。我们只想更改 border-top 样式。

将以下代码嵌套到之前的 .select-kit-body scss 中。

.select-kit.combo-box.category-drop,
.select-kit.combo-box.tag-drop {
  .select-kit-body {
    // ...之前的代码
    .select-kit-filter {
      border-top: 0px;
    }
  }
}

这样,我们用于样式化导航容器的代码应该如下所示。

.navigation-container {
  // 分类 + 标签下拉菜单
  .select-kit.combo-box {
    .select-kit-header {
      border-radius: 0.9em;
      background-color: var(--header_background);
    }

    &.category-drop,
    &.tag-drop {
      .select-kit-body {
        border-radius: 0.9em;
        background-color: var(--header_background);

        .select-kit-collection {
          background-color: var(--header_background);
          border-top-left-radius: 0px;
          border-top-right-radius: 0px;
        }

        .select-kit-filter {
          border-top: 0px;
        }
      }
    }
  }
}

导航链接

让我们添加一些样式,使这些导航链接看起来类似于此:

image

让我们再次使用 Inspector 来发现我们应该针对什么。

我们可以看到我们的导航元素位于一个具有 "nav nav-pills ..." 类的 UL 内。

回到我们的 common.scss 文件,在上一部分之下,但仍嵌套在 navigation-container 内,让我们添加以下内容:

.nav-pills {
  & > li a {
    &.active {
      color: var(--tertiary);
      background-color: var(--secondary);
      border-bottom: 4px solid var(--tertiary);
    }
  }
}

此更改将仅针对具有 active 类且是 nav-pills 子项的链接。此更改应使我们的活动链接看起来像这样:

image

这还可以,但我希望底部边框仅延伸到文本长度。为此,在 &.active { 行之上,让我们添加以下内容,这将影响导航 <li> 标签内的所有 A 链接。

// ...其他代码
.nav-pills {
  & > li a {
    padding: 0;
    margin-right: 20px;
    color: var(--tertiary-high);
    border-bottom: 4px solid transparent;

    &.active {
      // ...更多代码
    }
  }
}

现在,我们需要将“悬停”效果样式化为与“活动”效果相同。

在我们之前的 &.active 下添加

:hover {
  color: var(--tertiary);
  background-color: var(--secondary);
  border-bottom: 4px solid var(--primary);
}

因此,我们所有的导航代码现在应该如下所示:

// Nav Pills
.nav-pills {
  & > li a {
    padding: 0;
    margin-right: 20px;
    color: var(--tertiary-high);
    border-bottom: 4px solid transparent;

    &.active {
      color: var(--tertiary);
      background-color: var(--secondary);
      border-bottom: 4px solid var(--tertiary);
    }

    &:hover {
      color: var(--tertiary);
      background-color: var(--secondary);
      border-bottom: 4px solid var(--primary);
    }
  }
}

按钮

Discourse 中的按钮有多种形状和大小。你可以在样式指南的“按钮”部分查看它们的 assortment。

我想将此主题上的大多数按钮更改为圆角并带有自定义样式。这将更改 + 新主题 按钮以及站点中的其他按钮。

在我们的 common.scss 文件底部,让我们添加以下内容:

.btn {
  background-color: var(--header_background);
  color: var(--primary);
  border-radius: 1.2em;
  border: 1px solid var(--primary-low-mid);

  .d-icon {
    color: var(--primary);
  }

  &:hover {
    background-color: var(--quaternary-low);
    color: var(--primary);
    .d-icon {
      color: var(--primary);
    }
  }

  &.btn-default,
  &.btn-primary {
    padding: 10px 12px;
  }
}

这将使我们的按钮看起来像这样:

image

现在我们的按钮已经样式化,我想指出关于按钮样式化的一点,以及为什么测试所有设计很重要。

前往你的站点预览中的某个主题,然后点击主题回复上的 回复 按钮,或者主题流底部的回复按钮。你会看到我们的按钮样式化影响了一些我们可能没想到的东西。

我不希望这些文本编辑按钮受到我先前样式化的影响。这需要更复杂的 SASS/CSS,但我们可以让代码 :not() 影响这些按钮。:wink:

让我们在当前的 .btn 目标之前添加这一行代码。这将告诉我们的样式仅应用于不是 .d-editor-button-bar 子项的按钮。

:not(.d-editor-button-bar) > .btn

好的,这工作得很好……但是等等!现在有一个奇怪的叛逆者在做自己的事情。

image

在浏览器中检查它,我可以看到这个按钮有一个 .select-kit-header 类,因为点击这个齿轮后,会显示更多选项。

:flashlight: 我无法强调在创建 Discourse 主题时使用浏览器 Inspector 工具的重要性。它们是你旅途中最好的朋友。

既然我们知道我们_不_想针对这个按钮,让我们为我们的代码添加更多 :not() 功能。

:not(.d-editor-button-bar) >
.btn:not(.single-select-header)

这将选择所有不是 .d-editor-button-bar 子项且没有 .single-select-header 类的按钮。我知道这有点令人困惑,但在 Discourse 内部,有很多移动部件,所以有时样式需要非常具体才能正确影响元素。

我还注意到,我们当前的样式化以尴尬的方式影响了模态关闭按钮。点击任何弹出模态框的内容,你就可以看到这一点,或者更简单地说,我们可以导航到样式指南的模态框部分。

为了解决这个问题,我将为我们的代码添加另一个目标。

:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close)

继续…

我看到还有一个按钮似乎没有受到我们代码的影响。它是位于主题帖子流最底部的 Tracking 按钮。

image

我将在当前 .btn 代码的逗号后添加以下行。

:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close),
.topic-notifications-button > .select-kit > .btn

这将正确针对出现在此部分的按钮,现在,我们完成了论坛顶部区域的样式化。

:flashlight: 请随意调整你自己的 css 中的任何参数。你越尝试这些样式并观察它们如何影响 html,你就会学到越多!

接下来去哪里

本指南旨在让你初步了解如何为 Discourse 自定义自己的主题。我希望你现在对如何针对应用程序的区域进行自定义有了更多了解。

记住 许多事情仅使用 SCSS 就可以自定义。如果你想更深入地进行开发,我推荐阅读本文顶部链接的文章。

随时提出任何问题,我很乐意尝试帮助你,或为你指明正确的方向。


本文档受版本控制 - 建议更改 在 github 上

44 个赞

你好 @jordan.vidrine,

我在学习本教程的“运行 Discourse 主题 CLI”部分时遇到了 301 错误。

我通过将根 URL 从 https://theme-creator.discourse.org 替换为 https://discourse.theme-creator.io/ 解决了该问题。

希望这有帮助!

7 个赞

是的,我们更新了该网址,此帖子也需要更新——感谢告知!

6 个赞

感谢 @IdentityDan 提供的信息!
另外,供记录,如果您遇到此错误,您可能需要编辑此文件 /home/USERNAME/.discourse_theme,该文件存储了每个主题的 API 密钥与 discourse 站点之间的关系。
因此,即使主题创建失败,在“向导”中输入的信息也会存储在此处,如果您尝试使用相同名称创建新主题,URL 和 API 密钥将从此文件中检索。

3 个赞

另外还有一件事,在使用主题预览时,“Styleguide”链接无法正常工作。它会重定向到一个使用标准主题的页面,但通过在 URL 后面添加 ?preview_theme_id=THEME-ID-NUMBER,我们可以获得带有正确主题的 Styleguide。

1 个赞

谢谢,这太棒了

2 个赞

您好,我刚开始阅读帖子……
但在继续之前,我想知道是否可以使用 CLI 配合自托管实例?
或者我们必须使用 CLI 配合 theme-creator.io 进行开发,完成后再将主题“导入”到自托管实例中?
在我的例子中,我更感兴趣的是将其用作自定义一次性论坛的主题,而不是制作一个可重用的、打算发布的とのこと。
那么我是否仍应使用 CLI 配合该公共网站?
谢谢。

1 个赞

这是可能的,也是我推荐的方法。您唯一需要注意的就是,当您进行每次更改时,这些更改都会实时显示在论坛上。

我所做的是将主题设置为用户可选,并将我的个人用户偏好更改为该主题,同时为所有其他用户保留默认主题的选择。这样可以确保只有您能看到在主题化过程中可能出现的任何问题。

2 个赞

我经常用一个“虚拟在线”服务器来做这件事,它的域名我舍不得停租。

这样做更具成本效益,因为我不用它的时候,有时会把服务器关几周。

显然,我仍然要为存储(以及可能的 IP)付费,但至少我不用为 24/7 的计算付费。

我认为还有另一个地方需要更新!

1 个赞