richardhj / contao-theme-framework
Requires
- php: >=8.1
- contao/core-bundle: ^5.3
- symfony/config: ^5.0 || ^6.0 || ^7.0
- webmozart/path-util: ^2.3
Requires (Dev)
- contao/manager-plugin: ^2.7
Suggests
- richardhj/contao-knp-menu: Directly reference navigaiton modules in Twig templates
README
Contao中构建前端主题的一种新的标准化且无数据库的方式。
功能
- 自动通过
theme.yml
清单文件注册定义的主题和布局:几乎没有数据库需要维护 - 部署更简单! - 禁用了 tl_theme 和 tl_layout 面板中的所有冗余字段 - 您通过清单文件定义所有设置(除模块包含外)。
- 将主题的公共文件夹注册为资产包,支持通过
manifest.json
进行文件版本控制! - 开箱即支持 Symfony Encore 及其
entrypoints.json
!
此扩展稳定且从 Contao >=4.13 得到支持,最终将被集成到 Contao 核心中,请参阅 contao/contao#2781。
安装
composer require richardhj/contao-theme-framework
快速入门
1. 创建主题文件夹
在 /themes
下创建一个用于主题的文件夹,并具有以下结构
|- files
|- themes
|- my_theme
|- assets (Optional folder, we recommend placing your CSS/JS files there)
|- public (Distribution folder with your CSS/JS files, will be symlinked into the web/ folder)
|- templates (Overridden Contao templates, for frontend modules, etc.pp.)
|- theme.[yml|yaml] (Theme manifest)
如果您不使用预处理器,请将所有 CSS/JS 文件放入公共文件夹。
或者,复制样板文件夹
cp -r vendor/richardhj/contao-theme-framework/skeleton/theme themes/[my_theme]
此命令将安装一个有偏好的起始主题包。
ℹ️ 除了预定的目录结构外,您可以使用任何技术(Encore、Webpack、Gulp、SASS、纯 CSS、……)。
2. 编写主题清单
编写您的主题清单
# themes/[my_theme]/theme.yml theme: name: My cool theme layouts: # "_default" is a special key. # Will create a "default" layout, and all other layouts will merge these settings. # Using this key is optional. # The key:value structure maps the tl_layout structure. _default: name: Default layout template: fe_page rows: 3rw other_layout: name: Other layout template: fe_page_2 image_sizes: # See https://docs.contao.org/dev/framework/image-processing/image-sizes/#size-configuration
在下一个版本中,主题清单的 XML 格式将可用。
3. 安装主题
要安装您的新主题,请运行迁移命令
./vendor/bin/contao-console contao:migrate -n
ℹ️ 仅在更改主题清单时,主题才会通过迁移命令更新。最好将迁移命令添加到您的部署脚本中(这始终是个好主意)。
要创建公共文件夹的符号链接,请运行以下命令(这只需要做一次,并且这会在 composer install
时自动完成,所以通常不需要这样做)
./vendor/bin/contao-console contao:symlinks
4. 创建前端模块并将它们分配给布局
登录到 Contao 后端,在那里您将找到新的主题。创建前端模块(如果需要)并将它们相应地分配给布局。
用法
以下章节描述了根据您选择的工具链如何编写前端代码
Vanilla(无工具链)
每个主题的公共文件夹(即,/themes/[my_theme]/public
)被注册为 assets.packages
组件。 了解更多关于 Asset 组件的信息。
您可以使用 {{asset}}
插入标签或相应的 twig 函数来引用主题公共文件夹内的任何文件。主题名称等于文件夹名称。
当您在公共文件夹中使用 manifest.json
时,它将由 Symfony 的 Asset 组件处理。确保在您的 webpack.config.js
文件中使用 setManifestKeyPrefix('')
。
示例
<!-- HTML5 --> {{asset::images/logo.svg::my_theme}} <!-- Twig --> {{ asset('images/logo.svg', 'my_theme') }}
ℹ️ 将 CSS 文件包含到页面中的最简单方法是修改
fe_page.html5
模板,并包含{{asset::css/custom.css::my_theme}}
插入标签。
Encore
在此处阅读 Encore 的文档:https://symfony.ac.cn/doc/current/frontend/encore/index.html
首先,安装 Webpack Encore
composer require symfony/webpack-encore-bundle
确保通过将 webpack.config.js 文件放入您的 themes/[my_theme]/assets
文件夹中,正确配置 Encore。
然后您就可以将CSS和JS文件注入到页面模板中
{{ theme_link_tags('app') }} {{ theme_script_tags('app') }}
ℹ️ 名称 "app" 与在 webpack.config.js 中定义的入口名称相匹配。您可以为每个主题定义多个入口点。
最后,关于使用Encore和打包器的几点建议
将public文件夹添加到Git忽略列表
public文件夹内的主题文件通常已进行版本控制并包含重复信息,因此您不希望将这些文件提交到版本控制中。相反,您希望在部署之前构建主题(yarn run prod
)。
ℹ️ 骨架主题的 .gitignore文件 可能会很有用。
使用yarn工作区来管理多个主题
您可以使用 yarn工作区。这样,当使用多个主题时,只需运行一次构建命令。
// /package.json { "private": true, "workspaces": ["themes/*/assets"], "scripts": { "prod": "yarn workspaces run prod" } }
然后您可以从根目录运行 yarn run prod
。
资产管理器
在此处阅读资产管理器的文档: https://symfony.ac.cn/doc/current/frontend/asset_mapper.html
(待定)
常见问题解答
等等——如果从tl_layout中禁用了所有字段,我该如何构建网站?
好问题!
Contao中的布局高度冗余。您不需要通过布局配置viewport-attribute、body-class等。相反,只需直接将这些更改放入您的fe_page模板中。
直接通过{{asset}}插入标签或twig函数(或通过Encore,见下文)包含文件,而不是通过布局选择CSS文件和JS文件(这仅限于/files内的文件)。不要在布局中使用“自定义<head>
”或“自定义<script>
”设置。这很难维护和跟踪。相反,直接将这些内容放入模板中。
考虑到这些可维护性问题,不配置布局中的任何设置会更简单。在布局中,您只需分配模块到布局部分。
如果您的布局使用行和列,请在theme.yml
中设置相应的配置。例如,rows: 3rw
启用标题和页脚部分。
使用Twig模板(可选)
如果您的页眉和页脚部分只包含静态内容,您不需要在布局中配置这些部分。只需通过Twig包含将这些部分包含进来。对于导航菜单,您可以使用Knp Menu(见下文)。对于用户菜单,您可以使用{{ app.user }}变量。您将惊讶于不使用模块进行布局如何显著提高可维护性。
自定义布局部分
布局中的自定义布局区域工作如下。
首先,在布局中定义部分
# themes/[my_theme]/theme.yml layouts: _default: name: Default layout sections: - title: Bereich A id: custom1 position: manual template: block_section - title: Bereich B id: custom2 position: manual template: block_section
然后,将部分添加到页面布局中(即fe_page
)
{# themes/my_theme/fe_page.html.twig #} <div> {{ section.invoke('custom1') }} </div> <div> {{ section.invoke('custom2') }} </div>
<!-- themes/my_theme/fe_page.html5 --> <div> <?php $this->section('custom1') ?> </div> <div> <?php $this->section('custom2') ?> </div>
迁移到theme-framework
您可以将现有的主题和布局迁移到theme-framework。
在运行contao:migrate
之前
-
向
tl_theme
表添加一个名为alias
的新列,并将'alias' = 'my_theme'
(其中my_theme
与您的主题文件夹名称相匹配)设置。 -
向
tl_layout
表添加一个名为alias
的新列,并将'alias' = '_default'
(其中_default
与通过清单文件定义的布局名称相匹配)设置。 -
通过清单文件定义的所有布局设置将在
contao:migrate
命令中被覆盖。现有设置不会被修改。
最佳实践
不要重命名主题文件夹
重命名主题文件夹将在数据库内部创建一个新的 Contao 主题。您需要重新分配布局到页面。
使用 Twig 模板
您可以根据喜好使用 Twig 或 PHP 模板。如前所述,您的模板属于 templates
文件夹。
对于 Twig 模板,文件名后缀为 .html.twig
,例如 fe_page.html.twig
。对于 PHP 模板,使用默认命名,例如 fe_page.html5
。
主题文件夹中的 Twig 模板使用命名空间 @Contao_Theme_<name>
,例如模板 /themes/my_theme/templates/fe_page.html.twig
可以引用为 @Contao_Theme_MyTheme/fe_page.html.twig
。
ℹ️ 注意,"主题缩写" 对于 Twig 命名空间将被转换为驼峰式。如果您的主题文件夹名为
my_theme
,则 Twig 命名空间将是@Contao_Theme_MyTheme
。
您也可以在全局(非主题相关)文件夹中放置 twig 模板——无论哪种方式让您感觉更合适。
有关 Contao 中 Twig 模板的更多信息,请参阅 https://docs.contao.org/dev/framework/templates/twig/。
使用 Webpack Encore 编译您的主题资源
骨架主题附带了一个预定义的 webpack.config.js
文件。配置将自动处理来自 assets
文件夹的资产文件,并将打包文件生成到 public
文件夹。
Webpack Encore 还会在公共文件夹中提供一个 entrypoints.json
文件。这有助于轻松地将正确的 JS 和 CSS 文件添加到当前页面(见上文使用说明)。
使用 KnpMenu 用于导航模块
使用 KnpMenu,您可以在页面上需要的任何位置更灵活地输出导航。
有关更多信息,请参阅 https://github.com/richardhj/contao-knp-menu。
不要部署资源文件夹
包含源文件(如果有)的资源文件夹应从部署中排除,因为它很可能包含位于源文件夹旁边的 node_modules 文件夹。相比之下,所有其他文件,如主题.yml 清单文件、public 和 templates 文件夹,在部署时都需要上传。
卸载
当您卸载扩展时,您想知道您的主题会发生什么?
首先,您的所有主题、布局和图像大小配置都保留在 Contao 中。它们不会被删除。
其次,位于 /themes/foobar/templates
下的模板将不再使用命名空间 @Contao_Theme_Foobar
,而是使用命名空间 @Contao_Theme__themes_foobar_templates
。这可能会破坏您的网站。为了修复此问题,将模板文件夹移动到 /templates/Foobar
(从项目根目录)。Twig 命名空间保持不变。
第三,您将失去 Encore 和资源集成。这意味着使用资产({{ asset() }}
)函数或插入标记({{asset::*}}
)将失败。此外,twig 函数 theme_link_tags()
和 theme_script_tags()
将变得不可用。为了修复此问题,您必须通过直接引用它们来包含 CSS/JS 文件。
使用 Symfony UX
// TODO