跳至主要内容

如何开发 Pagekit 主题

在这个教程中,你将学习如何根据我们的Hello Theme蓝图开发自己的主题。你将了解主题结构,并按照添加新位置和选项的基本步骤。

注释

完成的主题可以在Github上找到。

入门

本教程假设你在本地服务器环境中运行了 Pagekit 安装。如果不是这样,下载Pagekit安装包并快速安装。然后登录管理区,查看集成市场的主题部分。

Pagekit 市场展示了我们的 Hello 主题,这是开发主题的蓝图,包括代码示例和帮助你入门的通用基础。

你好主题 无样式
Hello 主题不提供任何造型,但为你提供了一个很好的起点来发展自己的主题。

首先,从Pagekit市场安装主题,看看整体文件结构。安装后,Hello 主题位于 。如果你将来开发自己的主题,建议在旁边安装一个简单的主题作为参考,比如默认的Theme One。这样你可以比较结构元素,获得一些灵感。不过在这个教程中,我们只需要Hello主题。packages/pagekit/theme-hello

结构

让我们来看看你在开发自己主题时将要处理的一些核心文件和文件夹。

/css
  theme.css               // skeleton css with pre-defined classes
/js
  theme.js                // empty file for your scripts
/views
  template.php            // renders the theme's output; logo, menu, main content, sidebar and footer positions are available by default
composer.json             // package definition so that Pagekit recognizes the theme
image.jpg                 // preview screenshot
index.php                 // the central theme configuration
CHANGELOG.md              // changes of current and previous versions
README.md                 // contains basic information

重新命名你的主题

如果你只是更改了Hello主题的文件,任何市场对主题的更新都会覆盖你的更改。另外,你可能还想给主题取一个自定义的名字。如果你决定把主题上传到市场,甚至需要重新命名。这需要三个简单的步骤:

  1. 把所有文件从 复制到 (你需要创建这些文件夹)。packages/pagekit/theme-hellopackages/your-name/your-theme
  2. 打开并替换为 。另外,也可以改为 。composer.json"name": "pagekit/theme-hello","name": "your-name/your-theme""title": "Hello""title": "Your theme"
  3. 打开并替换为 。index.php'name' => 'theme-hello''name' => 'your-theme'

为了简化,教程的其他部分仍然会在示例中调用它。theme-hello

CSS

Hello 主题不包含任何样式。附带文件列出了所有由 Pagekit 核心扩展渲染且没有额外样式的 CSS 类。你可以在这些类中添加自己的 CSS。css/theme.css

Pagekit的管理界面和默认主题都是用UIkit前端框架构建的。所以你也可以考虑在项目中使用它。在下面的例子中,我们将用UIkit来构建主题。如果你使用其他框架或根本不使用框架,基本方法就是包含CSS。

设置主题文件结构有很多种可能的方法。我们可以推荐两种方法。一种是“经典”的包含纯CSS的方法。第二种初始设置更复杂,但灵活性更大。

简单方法是:包含纯CSS文件

UIkit官网,下载最新版本并解压。UIkit 包含三个主题:默认、渐变和几乎平坦。要包含默认主题,从UIkit包复制文件并粘贴到主题文件夹中。css/uikit.min.csstheme-hello/css/

为了确保Pagekit加载文件,请打开主题的主布局文件,该文件位于。theme-hello/views/template.php

在这个布局文件的部分,我们看到已经包含了一个CSS文件。<head>

<?php $view->style('theme', 'theme:css/theme.css') ?>

现在再加一行来添加UIkit CSS。确保在已有的那行方添加它,这样看起来如下。

<?php $view->style('custom-uikit', 'theme:css/uikit.min.css') ?>
<?php $view->style('theme', 'theme:css/theme.css') ?>

就是这样,你的主题现在包含了UIkit的CSS。要添加你自己的CSS规则,只需编辑。theme-hello/css/theme.css

默认UIkit样式
从 UIkit 添加 CSS 会为渲染的标记添加默认样式。为了让它看起来更美观,我们还需要在标记中添加一些类,自定义默认的UIkit样式,也许还要添加我们自己的CSS样式

高级方法:用Gulp和LESS设置

在上一节中,我们已经展示了向主题添加普通CSS文件是多么简单。如果你有网站建设经验,你可能熟悉更灵活的内容样式方式。一个很好的例子是使用像 LESS 这样的 CSS 预处理器。这让你可以使用变量等功能,使代码更易阅读和管理。

使用UIkit时,这个优点是你可以简单修改变量来应用全局变化,比如更改主主题颜色。

为了舒适地使用LESS预处理器,你应该在命令行安装并使用一些工具:npmgulpbower。如果你还没安装,可以快速谷歌一下,网上有很多教程。

有多种可能的文件结构设置方式。在接下来的段落中,我们建议了官方Pagekit主题所采用的结构。虽然第一次创建主题时看起来步骤繁多,但根据我们的经验,这种设置允许结构良好的代码、便捷的UIkit自定义,并且用Bower方便地保持UIkit的更新。

第一步

在你的主题中,创建新的文件 、 、 和 。将以下内容粘贴到这些文件中。如果你给主题命名不同,请用主题名称替换所有字符串的出现。package.jsonbower.json.bowerrcgulpfile.jsless/theme.lesstheme-hello

package.json.该文件定义了运行时安装的所有 JavaScript 依赖,并包含若干 npm 包,例如我们将用到的,例如在将 LESS 编译成 CSS 时:npm install

{
    "name": "theme-hello",
    "devDependencies": {
         "bower": "*",
         "gulp": "*",
         "gulp-less": "*",
         "gulp-rename": "*"
     }
}

bower.json让鲍尔去获取最新的UIkit版本。这样你就可以随时从UIkit获取当前的LESS源文件:bower install

{
    "name": "theme-hello",
    "dependencies": {
        "uikit": "*"
    },
    "private": true
}

.bowerrc包含 Bower 的配置设置。默认情况下,Bower 会将所有内容安装到主题目录内调用的目录中。出于偏好,我们会更改该默认目录:/bower_components

{
    "directory": "app/assets"
}

gulpfile.js包含所有可用 Gulp 执行的任务。我们只需要一个任务将 LESS 编译成 CSS。为了方便,我们还添加了一个任务,当检测到文件发生变化时,可以自动重新编译 LESS:watch

var gulp       = require('gulp'),
    less       = require('gulp-less'),
    rename     = require('gulp-rename');

    gulp.task('default', function () {
        return gulp.src('less/theme.less', {base: __dirname})
            .pipe(less({compress: true}))
            .pipe(rename(function (file) {
                // the compiled file should be stored in the css/ folder instead of the less/ folder
                file.dirname = file.dirname.replace('less', 'css');
            }))
            .pipe(gulp.dest(__dirname));
    });

    gulp.task('watch', function () {
        gulp.watch('less/*.less', ['default']);
    });

less/theme.less是你存放主题风格的地方。请注意,你首先需要导入UIkit,这样它也能被我们上面定义的Gulp任务编译。

@import "uikit/uikit.less";

// use icon font from system
@icon-font-path: "../../../../app/assets/uikit/fonts";

// your theme styles will follow here...

.gitignore是一个可选文件,在你用 Git 管理代码时非常有用。在 Hello 主题中,文件已经有一个版本存在。你可以添加新条目,让它看起来如下。你可能不想通过 Bower 提交下载的包和生成的 CSS。只要确保在将主题上传到服务器或 Pagekit 市场时包含生成的 CSS。

/app/bundle/*
/app/assets/*
/node_modules
/css
.DS_Store
.idea
*.zip

第二步

创建完上面的文件后,去UIkit的Github仓库,下载压缩包,解压后找到文件夹(或者其他主题,如果你愿意的话)。注意你需要的是 Github 版本,而不是我们在简单设置中下载的仅支持 CSS 的版本。themes/default

从 Github 下载 UIkit

第三步

在你的主题内创建一个文件夹,复制粘贴主题文件夹,并重命名为 ,这样它就在你的主题文件夹里。/lessdefault/uikitless/uikit

步骤4

我们刚复制的样式需要非常少地导入核心UIkit,这样才能成功编译。要实现这一点,你需要更新主题文件中的导入路径。确保在第4行更改导入路径如下:less/uikit/uikit.less@import "../../app/assets/uikit/less/uikit.less";

第五步

在新的控制台标签页(例如)打开你的主题,然后运行 , 和 。cd pagekit/packages/theme-hellonpm installbower installgulp

这可是相当多的步骤。确保你的文件结构现在看起来如下(以及之前存在的额外主题文件):

app/
    assets/
        jquery/    result of bower install
        uikit/     result of bower install
css/
    theme.css      result of gulp
less/
    uikit/
        ... uikit components
        uikit.less
    theme.less
node_modules/      result of npm install
.bowerrc
bower.json
gulpfile.js
package.json
... other theme files

有了这个文件设置,我们现在实现了以下目标:

  • 主题样式和UIkit自定义的分离。在里面添加你自己的样式,在UIkit里自定义less/theme.lessless/uikit/*
  • 轻松自定义UIkit:每个UIkit组件的设置都位于其独立文件中。例如,要更改正文字体大小,打开并更改 的值,然后重新运行 。要使用任何 UIkit 插件组件,打开并导入目录中的插件 less 文件,例如幻灯片,添加行:并重新运行*.lessless/uikit/base.less@base-body-font-sizegulpless/uikit.lessapp/assets@import "../../app/assets/uikit/less/components/slideshow.less";gulp.
  • 轻松更新UIkit:运行以获取最新版本的UIkit,然后运行以重新编译你的LESS文件为CSS。bower installgulp

添加JavaScript

Hello 主题中包含一个空的 JavaScript 文件。在这里,你可以添加自己的JavaScript代码。在 Hello Theme 中,文件被加载是因为它已经包含在以下格式中:js/script.jstemplate.php

<?php $view->script('theme', 'theme:js/theme.js') ?>

在包含脚本时,需要一个唯一的标识符()和脚本文件的路径()。如你所见,你可以用它作为主题目录文件路径的简短版本。要添加更多JavaScript文件,只需以同样方式添加更多行。确保给脚本分配不同的标识符。如果你打电话给所有公司,只有最后一个会被包含在内。themetheme:js/theme.jstheme:theme

<?php $view->script('theme', 'theme:js/theme.js') ?>
<?php $view->script('plugins', 'theme:js/plugins.js') ?>
<?php $view->script('slideshow', 'theme:js/slideshow.js') ?>

虽然添加多个调用是包含JavaScript最简单的方式,但该辅助工具允许更强大的方式来包含JavaScript文件,这些文件之间也可能相互依赖。让我们在接下来的章节中更深入地探讨这一点。script()script()

添加多个带有依赖的JavaScript文件

在之前的例子中,我们已经使用了UIkit的CSS。如果你也想使用UIkit的JavaScript组件和工具,添加UIkit的JavaScript文件是合理的。注意,UIkit需要先加载jQuery才能使用UIkit的JavaScript组件。

在 的前一行找到,并用接下来的三行替换它。script('theme', ...)views/template.php

<?php $view->script('theme-jquery', 'theme:app/assets/jquery/dist/jquery.min.js') ?>
<?php $view->script('theme-uikit', 'theme:app/assets/uikit/js/uikit.min.js', 'theme-jquery') ?>
<?php $view->script('theme', 'theme:js/theme.js', 'theme-uikit') ?>

这个例子假设你用了上面提到的高级设置,Bower把UIkit和jQuery都安装到了文件夹里。如果你用的是更简单的设置,只需下载并复制到主题中的某个地方,然后相应地修改示例中的路径。app/assetsjquery.min.jsuikit.min.js

注意我们现在增加了第三个参数,定义了我们加载脚本的依赖关系。依赖是需要更早加载的其他JavaScript文件。所以在这个例子中,Pagekit 肯定会确保按以下顺序加载这三个文件:jQuery、UIkit,然后是我们自己的 。在这个具体例子中,这个机制似乎没什么用,因为脚本很可能会按照我们放在 的顺序加载,对吧?没错,但想象这些线条分别位于你主题的不同文件和子模板中。定义依赖关系可以确保 Pagekit 总是按正确顺序加载文件。theme.jstemplate.php

如你在上面示例中已经看到的,依赖关系使用唯一的字符串标识符(例如 )。在我们的例子中,该标识符在首次使用该方法包含脚本时被赋予。正如你现在看到的,这个方法需要三个参数: 。theme-jqueryscript()$view->script($identifier, $path_to_script, $dependencies)

要确认是否有效,请打开并添加以下几行(是UIkit JavaScript组件的前缀)。views/template.phpdata-uk-*

<!-- ADD id="up" to body -->
<body id="up">

    <!-- LEAVE existing content ... -->
    ...

    <!-- ADD to-top-scroller -->
    <div class="uk-text-center">
       <a href="#up" data-uk-smooth-scroll=""><i class="uk-icon-caret-up"></i></a>
    </div>

    <!-- LEAVE rendering of footer section  -->
    <?= $view->render('footer') ?>

</body>

刷新浏览器时,你会看到一个小箭头,可以用来平滑地滚动到浏览器窗口顶部。如果浏览器滚动不平顺,而是立即跳动,请检查你是否完全按照示例写入。

添加第三方脚本,比如 jQuery

你可能会问,为什么我们调用包含的jQuery脚本而不是简单地调用。一般来说,在自己标识符前加前缀总是有用的,以避免与其他扩展名冲突。然而,在这个具体例子中,标识符和已经被占用了,因为Pagekit本身包含jQuery和UIkit。这意味着你可以在不包含这些JavaScript文件的情况下加载它们。这样,所有主题和扩展都可以共享一个jQuery版本(如果使用UIkit,还包括UIkit),以避免冲突。theme-jqueryjqueryjqueryuikit

<?php $view->script('theme', 'theme:js/theme.js', ['uikit', 'jquery']) ?>

如示例所示,方法的第三个参数也可以包含多个依赖关系。在前面的例子中,我们只传递了单一字符串(例如)。可以输入字符串表示单个依赖,或输入列表表示多个依赖——两者皆可。script()theme-jquery

当前加载的jQuery和UIkit版本依赖于当前版本的Pagekit。随着Pagekit的新版本发布,这些库的版本将持续更新。虽然这样可以始终保持当前版本可用,但潜在的缺点是你需要确保代码也能支持这些库的新版本。

布局

主题布局的中央文件是和。实际渲染发生在 。views/template.phpindex.phptemplate.php

打开 ,你会看到一个非常基础的入门设置。我们用一个容器包裹主内容,把系统输出和侧边栏划分为网格。template.php

大约在第30行,文件渲染侧边栏位置和实际内容。views/template.php

<!-- Render widget position -->
<?php if ($view->position()->exists('sidebar')) : ?>
    <?= $view->position('sidebar') ?>
<?php endif; ?>

<!-- Render content -->
<?= $view->render('content') ?>

利用UIkit的工具组件,我们将创建一个位置块和一个宽度为流体的容器。

最好先给自己的类做前缀,这样它们就不会和你正在用的其他 CSS 发生冲突。例如,所有UIkit类都以前缀。为了区分来自该主题的类或ID,我们将使用前缀 。因此,我们添加类别和ID来识别该截面。uk-tm-tm-main

<div id="tm-main" class="tm-main uk-block">
    <div class="uk-container uk-container-center">

        <!-- Render widget position -->
        <?php if ($view->position()->exists('sidebar')) : ?>
            <?= $view->position('sidebar') ?>
        <?php endif; ?>

        <!-- Render content -->
        <?= $view->render('content') ?>

    </div>
</div>

现在我们希望系统输出和侧边栏实际上并排。网格组件可以帮我们解决这个问题。为了更语义化的布局,我们将使用 和 元素作为容器。<main><aside>

<div id="tm-main" class="tm-main uk-block">
    <div class="uk-container uk-container-center">

        <div class="uk-grid" data-uk-grid-match data-uk-grid-margin>

            <main class="<?= $view->position()->exists('sidebar') ? 'uk-width-medium-3-4' : 'uk-width-1-1'; ?>">

                <!-- Render content -->
                <?= $view->render('content') ?>

            </main>

            <?php if ($view->position()->exists('sidebar')) : ?>
            <aside class="uk-width-medium-1-4">
                <?= $view->position('sidebar') ?>
            </aside>
            <?php endif; ?>

        </div>

    </div>
</div>

主题元素

为了创建更复杂的布局,你可以为两者添加自己的小部件位置、菜单和选项。常规主题基本上包括小部件、菜单和页面内容本身。

页面内容就是Pagekit系统的输出。这意味着你创建的任何页面内容都会在这个区域渲染。

小部件是你可以在网站不同位置渲染的小内容块,这样它们就会显示在网站标记的特定位置。

要浏览任何网站,首先需要设置菜单。为此,Pagekit 提供了不同的菜单位置,允许用户在主题标记的多个位置发布菜单。

典型主题元素
典型的网站布局包括主导航、页面内容和若干小部件位置

不过,你的主题需要先注册所有位置。这在文件中通过 and 属性完成。这些属性包含位置名称的数组和标签,标签会显示在管理面板中。这个文件还用于加载更多脚本等。index.phpmenuspositions

你首先要在主题中渲染的是主导航。

主导航无样式
默认情况下,Hello 主题以非常简单的垂直导航方式渲染菜单项。

第一步

Hello 主题自带预设的菜单位置。添加新位置时,需要通过标识符(即 )和一个标签来定义,以显示给用户(即位置)。main

'menu' => [

    'main' => 'Main',

]
网站树中的菜单位置
菜单可以发布到Pagekit站点树中定义的位置。

第二步

考虑到模块化的概念,Pagekit 将位置布局渲染为独立文件。为了导航,创建包含以下内容的文件:views/menu-navbar.php

<?php if ($root->getDepth() === 0) : ?>
<ul class="uk-navbar-nav">
<?php endif ?>

    <?php foreach ($root->getChildren() as $node) : ?>
    <li class="<?= $node->hasChildren() ? 'uk-parent' : '' ?><?= $node->get('active') ? ' uk-active' : '' ?>" <?= ($root->getDepth() === 0 && $node->hasChildren()) ? 'data-uk-dropdown':'' ?>>
        <a href="<?= $node->getUrl() ?>"><?= $node->title ?></a>

        <?php if ($node->hasChildren()) : ?>

            <?php if ($root->getDepth() === 0) : ?>
            <div class="uk-dropdown uk-dropdown-navbar">
            <?php endif ?>

                <?php if ($root->getDepth() === 0) : ?>
                <ul class="uk-nav uk-nav-navbar">
                <?php elseif ($root->getDepth() === 1) : ?>
                <ul class="uk-nav-sub">
                <?php else : ?>
                <ul>
                <?php endif ?>
                    <?= $view->render('menu-navbar.php', ['root' => $node]) ?>
                </ul>

            <?php if ($root->getDepth() === 0) : ?>
            </div>
            <?php endif ?>

        <?php endif ?>

    </li>
    <?php endforeach ?>

<?php if ($root->getDepth() === 0) : ?>
</ul>
<?php endif ?>

第三步

要渲染文件中的实际导航栏,创建一个元素并添加类。在元素中加载文件,步骤如下(你可以移除渲染的现有块)。template.php<nav>.uk-navbarmenu-navbar.php$view->menu('main')

<nav class="uk-navbar">

    <?php if ($view->menu()->exists('main')) : ?>
    <div class="uk-navbar-flip">
        <?= $view->menu('main', 'menu-navbar.php') ?>
    </div>
    <?php endif ?>

</nav>

主菜单现在应该会自动渲染到新的导航栏位置。

步骤4

你可能还希望标志出现在导航栏内。所以也把元素包裹在标志上,并添加类,以应用合适的间距。<nav>.uk-navbar-brand

<nav class="uk-navbar">

    <!-- Render logo or title with site URL -->
    <a class="uk-navbar-brand" href="<?= $view->url()->get() ?>">
        <?php if ($logo = $params['logo']) : ?>
            <img src="<?= $this->escape($logo) ?>" alt="">
        <?php else : ?>
            <?= $params['title'] ?>
        <?php endif ?>
    </a>

    <?php if ($view->menu()->exists('main')) : ?>
    <div class="uk-navbar-flip">
        <?= $view->menu('main', 'menu-navbar.php') ?>
    </div>
    <?php endif ?>

</nav>
水平导航栏
通过我们的更改,菜单项现在以水平导航栏的形式呈现。

添加主题选项

Pagekit 使用 Vue.js 来构建其管理接口。这里有一个关于Pagekit Vue.js的视频教程

一个经常被要求的功能是,当网站向下滚动时,导航栏会固定在浏览器窗口顶部。在接下来的步骤中,我们将把这个选项加入到我们的主题中。

第一步

首先,我们需要创建文件夹,并在其中生成文件 。存储在该文件中的设置影响整个网站,可以在站点树设置标签下的主题中找到。它们不能应用于特定页面。app/componentssite-theme.vue

网站树
你可以在管理员区添加任何设置界面。

在新创建的文件中,我们添加了一个选项,该选项将在Pagekit管理中显示。site-theme.vue

<template>

    <div class="uk-margin uk-flex uk-flex-space-between uk-flex-wrap" data-uk-margin>
        <div data-uk-margin>
            <h2 class="uk-margin-remove">{{ 'Theme' | trans }}</h2>
        </div>
        <div data-uk-margin>
            <button class="uk-button uk-button-primary" type="submit">{{ 'Save' | trans }}</button>
        </div>
    </div>

    <div class="uk-form uk-form-horizontal">

        <div class="uk-form-row">
            <label for="form-navbar-mode" class="uk-form-label">{{ 'Navbar Mode' | trans }}</label>
            <p class="uk-form-controls-condensed">
                <label><input type="checkbox" v-model="config.navbar_sticky"> {{ 'Sticky Navigation' | trans }}</label>
            </p>
        </div>

    </div>

</template>

第二步

现在我们还需要在站点树中提供这个选项。为此,我们可以通过在文件选项下方添加以下脚本,在界面中创建一个主题标签页。site-theme.vue

<script>

    module.exports = {

        section: {
            label: 'Theme',
            icon: 'pk-icon-large-brush',
            priority: 15
        },

        data: function () {
            return _.extend({config: {}}, window.$theme);
        },

        events: {

            save: function() {

                this.$http.post('admin/system/settings/config', {name: this.name, config: this.config}).catch(function (res) {
                    this.$notify(res.data, 'danger');
                });

            }

        }

    };

    window.Site.components['site-theme'] = module.exports;

</script>

第三步

要加载脚本并在站点树中添加该选项,你还需要在文件中添加以下内容。index.php

'events' => [

    'view.system/site/admin/settings' => function ($event, $view) use ($app) {
        $view->script('site-theme', 'theme:app/bundle/site-theme.js', 'site-settings');
        $view->data('$theme', $this);
    }

]

步骤4

在文件中添加导航栏模式的默认设置。index.php

'config' => [
    'navbar_sticky' => false
],

第五步

Vue 组件需要使用 Webpack 编译成 JavaScript。为此,请在你的主题文件夹中创建该文件:webpack.config.js

module.exports = [

    {
        entry: {
            "site-theme": "./app/components/site-theme.vue"
        },
        output: {
            filename: "./app/bundle/[name].js"
        },
        module: {
            loaders: [
                { test: /\.vue$/, loader: "vue" }
            ]
        }
    }

];

第六步

之后,在theme文件夹里运行命令,模板标记会被编译成内联字符串。webpacksite-theme.vue/bundle/site-theme.js

如果你以前没用过,你需要快速全局安装 webpack,然后在项目目录中运行以下程序,这样才能获得本地 webpack 版本和 Vue 编译器。

npm install webpack vue-loader vue-html-loader babel-core babel-loader babel-preset-es2015 babel-plugin-transform-runtime --save-dev

每当你对 Vue 组件进行更改时,都需要再次执行该任务。或者,你也可以运行 或 该任务保持活跃状态,并在更改 Vue 组件时自动重新编译。你可以用快捷键 Ctrl + C 退出该命令。想了解更多关于 Vue 和 Webpack 的信息,请仔细查看这份文档webpack --watchwebpack -w

第七步

最后,我们希望在文件顶部加载必要的JavaScript依赖。我们使用的是UIkit中的粘性组件。由于它不包含在框架核心中,需要显式加载。你可以通过在加载主题JavaScript时添加粘性组件来实现这一点。views/template.php

<?php $view->script('theme', 'theme:js/theme.js', ['uikit-sticky']) ?>

现在你只需要把这个选项渲染到实际的导航栏里。template.php

<nav class="uk-navbar uk-position-z-index" <?= $params['navbar_sticky'] ? ' data-uk-sticky' : '' ?>>

在管理区,进入主题>>设置,启用粘贴导航选项,查看该功能在你的网站上生效。

小工具

小部件位置允许用户在主题标记的多个位置发布小部件。它们出现在 Pagekit 管理面板的 Widgets 区域,用户可以在设置 Widget 时选择。

第一步

要渲染一个新的控件位置,首先需要在文件中注册它。例如,如果我们想创建一个新的顶位位置,我们会通过属性来定义它。index.phppositions

'positions' => [

    'sidebar' => 'Sidebar',
    'top' => 'Top'

],

第二步

既然我们已经向 Pagekit 公布了新位置,我们还需要创建一个位置渲染器。我们可以跳过这一步,使用默认渲染器,但那样所有控件都会直接在每个像素下方渲染。所以要把小部件排成网格,可以创建以下文件:views/position-grid.php

<?php foreach ($widgets as $widget) : ?>
<div class="uk-width-medium-1-<?= count($widgets) ?>">

    <div class="uk-panel">

        <h3 class="uk-panel-title"><?= $widget->title ?></h3>

        <?= $widget->get('result') ?>

    </div>

</div>
<?php endforeach ?>

第三步

要渲染主题标记中的新位置,我们需要在关闭标签之后添加它到文件中:views/template.php</nav>

<?php if ($view->position()->exists('top')) : ?>
<div id="top" class="tm-top">
    <div class="uk-container uk-container-center">

        <section class="uk-grid uk-grid-match" data-uk-grid-margin>
            <?= $view->position('top', 'position-grid.php') ?>
        </section>

    </div>
</div>
<?php endif ?>

现在可以选择“顶部”,表示你想渲染的任何小部件在新创建的位置。

小部件位置
创建小部件时选择新位置。

增加位置选项

之前的示例添加了适用于整个网站的配置选项。我们也可以扩展站点树,配置只适用于特定页面。让我们添加一个选项,可以为新的顶部位置应用不同的背景色。

第一步

首先,我们需要在文件夹 中创建文件。这里我们添加一个选项,该选项将在Pagekit管理中显示。存储在该文件中的设置可以通过在站点树中输入相应项目并点击主题标签,分别应用到每个页面上。node-theme.vueapp/components

<template>

    <div class="uk-form-horizontal">

        <div class="uk-form-row">
            <label for="form-top-style" class="uk-form-label">Top {{ 'Position' | trans }}</label>
            <div class="uk-form-controls">
                <select id="form-top-style" class="uk-form-width-large" v-model="node.theme.top_style">
                    <option value="uk-block-default">{{ 'Default' | trans }}</option>
                    <option value="uk-block-muted">{{ 'Muted' | trans }}</option>
                </select>
            </div>
        </div>

    </div>

</template>

第二步

现在我们还需要在站点树中提供这个选项。为此,我们可以在界面中添加以下内容来创建一个主题标签页。node-theme.vue

<script>

    module.exports = {

        section: {
            label: 'Theme',
            priority: 90
        },

        props: ['node']

    };

    window.Site.components['node-theme'] = module.exports;

</script>

第三步

在关于主题选项的章节中,我们插入了事件监听器,以便加载脚本并将选项添加到站点树中。现在我们需要对网站设置做同样的事情。整个剖面应该是这样的。index.phpevents

'events' => [

    'view.system/site/admin/settings' => function ($event, $view) use ($app) {
        $view->script('site-theme', 'theme:app/bundle/site-theme.js', 'site-settings');
        $view->data('$theme', $this);
    },

    'view.system/site/admin/edit' => function ($event, $view) {
        $view->script('node-theme', 'theme:app/bundle/node-theme.js', 'site-edit');
    }

]

步骤4

控件位置的默认设置也需要添加到 .index.php

'node' => [

    'top_style' => 'uk-block-muted'

],

第五步

在关于主题选项的章节中,我们创建了文件 。我们的文件还需要注册以便编译成JavaScript。webpack.config.jsnode-theme.vue

entry: {
    "node-theme": "./app/components/node-theme.vue",
    "site-theme": "./app/components/site-theme.vue"
},

第六步

现在你可以在theme文件夹里运行命令webpack,并会被编译成 。node-theme.vueapp/bundle/node-theme.js

第七步

最后,要将所选设置渲染到控件位置,我们需要在文件中的位置本身添加类和样式参数。.uk-blocktemplate.php

<div id="top" class="tm-top uk-block <?= $params['top_style'] ?>">

第八步

在网站树中,编辑页面时你现在会看到一个主题标签。在这里你可以配置新选项。此配置仅适用于本特定页面。

主题添加的节点选项
主题添加的节点选项。

添加小部件选项

你也可以为小部件本身添加特定选项。在这种情况下,我们希望为每个小部件提供一个面板样式选项。

小工具选项
主题可以为小部件编辑器添加任何类型的选项。

第一步

首先,我们需要在文件夹 中创建一个文件。这会生成选择框,我们可以从中选择小部件的样式。app/components/widget-theme.vueapp/components

<template>

    <div class="uk-form-horizontal">

        <div class="uk-form-row">
            <label for="form-theme-panel" class="uk-form-label">{{ 'Panel Style' | trans }}</label>
            <div class="uk-form-controls">
                <select id="form-theme-panel" class="uk-form-width-large" v-model="widget.theme.panel">
                    <option value="">{{ 'None' | trans }}</option>
                    <option value="uk-panel-box">{{ 'Box' | trans }}</option>
                    <option value="uk-panel-box uk-panel-box-primary">{{ 'Box Primary' | trans }}</option>
                    <option value="uk-panel-box uk-panel-box-secondary">{{ 'Box Secondary' | trans }}</option>
                    <option value="uk-panel-header">{{ 'Header' | trans }}</option>
                </select>
            </div>
        </div>

    </div>

</template>

第二步

现在我们还是得在小部件管理中提供这个选项。为此,我们可以在界面中添加以下内容来创建一个主题标签页。widget-theme.vue

<script>

    module.exports = {

        section: {
            label: 'Theme',
            priority: 90
        },

        props: ['widget', 'config']

    };

    window.Widgets.components['theme'] = module.exports;

</script>

第三步

为了在控件管理中提供该选项,我们可以通过在文件中的部分添加以下内容,创建一个主题标签页eventsindex.php

'view.system/widget/edit' => function ($event, $view) {
    $view->script('widget-theme', 'theme:app/bundle/widget-theme.js', 'widget-edit');
}

步骤4

小部件的默认设置也需要添加到 .index.php

'widget' => [

    'panel' => ''

],

第五步

把这个条目添加到文件中,这样它就会被编译成JavaScript(别忘了之后在theme文件夹里运行它)。widget-themewebpack.config.jsonwebpack

entry: {
    "node-theme": "./app/components/node-theme.vue",
    "site-theme": "./app/components/site-theme.vue",
    "widget-theme": "./app/components/widget-theme.vue"
},

第六步

现在我们只需要把选定的设置渲染到文件里的小部件里。position-grid.php

<div class="uk-panel <?= $widget->theme['panel'] ?>">

第七步

编辑小部件时,你现在会在编辑器顶部看到一个主题标签,可以访问我们刚刚添加的面板样式配置。

覆盖系统视图

主题还可以自定义 Pagekit 如何渲染静态页面和博客文章。你只需覆盖系统视图文件,应用你自己的布局。为此,在主题内创建对应的文件夹,模拟 Pagekit 系统的原始结构,并将模板文件放入那里:

档案 原始视图文件 描述
views/system/site/page.php /app/system/site/views/page.php 默认静态页面视图
views/blog/post.php /packages/pagekit/blog/views/post.php 博客文章单一视图
views/blog/posts.php /packages/pagekit/blog/views/posts.php 博客文章列表视图

要了解这些视图中有哪些变量可用,请查看原始视图文件中的标记。

收尾

在本教程中,你已经掌握了为Pagekit创建主题的基础知识和工具。让我们总结一下我们已经涵盖的主题。

注释

完成的主题可以在Github上找到。

  • 你现在已经熟悉了Pagekit主题的文件结构。配置和自定义代码的主要入口是主题的,主模板文件位于主题内部。index.phpviews/template.php
  • 我们提出了一种现代前端工作流程的方法,使用了LESS、Gulp和Bower等工具。你可以根据自己的喜好定制这个设置。
  • 向主题添加JavaScript,你可以添加自己的代码,并在模板中包含脚本文件。你还可以添加第三方库,比如UIkit和jQuery,帮助你为网站添加交互功能。
  • 小部件和菜单由 Pagekit 管理区管理,并以主题的特殊位置渲染。你已经学会了如何创建这些位置以及如何更改小部件的默认渲染方式。
  • 为了确保你的主题可以从管理区自定义,你可以添加自己的设置界面。这些可以添加到站点树、站点设置和控件编辑器中。
  • 为了覆盖系统视图,你的主题可以包含自定义视图文件,以改变静态页面和博客文章的渲染方式。

凭借这些技能,你现在可以为客户项目和Pagekit市场创建主题。