跳至主要内容

如何开发 Pagekit 扩展

本教程将按照设置和开发完整扩展来管理 Pagekit 管理区待办事项的所有步骤。你将学习基础扩展概念、控制器、路由、视图渲染和Vue.js框架。

内容

  1. 使用模块扩展 Pagekit
  2. 路由与控制器
  3. 查看渲染和模块配置
  4. 在 Pagekit 扩展中使用 Vue.js
  5. 完成的实例

如果你更喜欢视频而不是文字,可以看看Youtube播放列表,教程里包含所有截屏

注释

完成的示例可在 Github 上获取。

步骤1:使用模块扩展Pagekit

作为开发者,你可以轻松扩展Pagekit已有的功能。无论你想要自定义主题还是扩展以增加功能,两者都是遵循相同的方法构建的。在这一步中,我们将介绍什么是模块——这两个都是Pagekit的核心概念。

观看这一步视频

术语:软件包和模块

主题和延伸从外表看可能不同,但它们都是我们称之为一个整体的东西。包只是一个文件夹,里面包含了若干文件,并包含一个称为 的文件中的元数据。composer.json

要在 Pagekit 系统注册任何东西,你还会包含一个名为 . 的文件。它包含了我们称之为的定义。模块是Pagekit规范中最重要的建筑单元。模块是自成一体的单元,将功能捆绑起来,并组合起来构成整个系统。模块既用于 Pagekit 核心,也用于任何第三方扩展中。index.php

包文件该放在哪里

每个软件包都属于一个特定的供应商名称,这在你查看新安装的 Pagekit 目录结构时就能看出来。

核心包是命名空间的一部分,并位于 内相应的子目录中。任何第三方套餐(包括你的!)都会有自己的供应商名称,因此会放在一个单独的子文件夹里。pagekit/packages

/packages
    /pagekit
        /blog
        /theme-one
    /your-vendor
        /your-theme
        /your-extension

每个包中你至少会发现两个文件:和。composer.jsonindex.php

1. composer.json:包元数据

该包包含了元数据。这会显示在 Pagekit 后台,如果你把扩展上传到 Pagekit 市场时会使用。composer.json

packages/pagekit/todo/composer.json

{
    "name": "pagekit/todo",
    "version": "0.1",
    "type": "pagekit-extension",
    "title": "ToDo management"
}

2. index.php:模定义

模块将功能捆绑在 Pagekit 内部,是你连接 Pagekit 系统的方式。从代码角度看,模块定义是一个带有某些属性的PHP数组。总是必须 一个有效的数组。index.phpreturn

<?php

use Pagekit\Application;

// packages/pagekit/todo/index.php

return [

    'name' => 'todo',

    'type' => 'extension',

    // called when Pagekit initializes the module
    'main' => function (Application $app) {
        echo "It's alive";
    }
];

?>

为了测试功能,确保你在后台启用了扩展。激活时,你会在屏幕顶部看到打印出来的输出。

这个最小的例子展示了一个功能完整模块可以非常小。它能访问实例。通过这个对象,你可以访问所有服务,触发事件,并监听其他模块触发的事件。Application

步骤2:路由与控制器

在扩展设置的基本结构中,常见任务是注册自己的控制器并将菜单项添加到管理区域。为此,我们将探讨一些你可以添加到模块定义中的附加属性。index.php

观看这一步视频

添加控制器

Pagekit 中的控制器只是一个普通的 PHP 类。每个正确命名的公共方法(即 )都会被 Pagekit 的路由(即 )挂载。someAction()/todo/some

创建一个包含以下代码的文件。packages/pagekit/todo/src/Controller/TodoController.php

<?php

namespace Pagekit\Todo\Controller;

/**
 * @Access(admin=true)
 */
class TodoController
{

    public function indexAction()
    {
       return "Yay.";
    }

}

为了限制对管理区域的访问并将该控制器挂载到管理员网址,我们使用注释。注释是放置在类或方法上方评论块的关键词。了解更多关于注释的信息@Access(admin=true)

要使用这个控制器,我们需要自动加载命名空间并将控制器挂载到路由中。在你的配置数组中添加以下属性。index.php

    // ...

    // array of namespaces to autoload from given folders
    'autoload' => [
        'Pagekit\\Example\\' => 'src'
    ],


    // array of routes
    'routes' => [

        // identifier to reference the route from your code
        '@todo' => [

            // which path this extension should be mounted to
            'path' => '/todo',

            // which controller to mount
            'controller' => 'Pagekit\\Todo\\Controller\\TodoController'
        ]
    ],

    // ...

你现在可以在网址 访问新的控制器。注意这个 URL 是由四个部分生成的:<pagekit_path>/admin/todo

  1. <pagekit_path>URL总是从你的URL开始
  2. @Access(admin=true)结果生成了一个管理员网址/admin
  3. 控制器安装方式为/todo
  4. 该URL的默认路由是 。indexAction

如果你无法访问你的路线,请清除缓存。Pagekit 缓存路由以提升性能。

调试工具栏

要查看开发过程中所有已注册的路由,启用 Pagekit 系统设置中的调试工具栏非常有用。工具栏显示在屏幕底部,显示所有已注册路线及其他有用信息。

记得关闭直播网站时的这个功能。

添加菜单项

要添加菜单项,请使用模块定义中的属性。将以下内容添加到 。menuindex.php

// ...

'menu' => [
    'example' => [
        'label'  => 'ToDo',
        'icon'   => 'app/system/assets/images/placeholder-icon.svg',
        'url'    => '@todo',
    ]
],
// ...

刷新Pagekit后端,你会看到一个新的菜单项,链接到该路线。@todo

步骤3:查看渲染和模块配置

在之前的步骤中,我们已经探讨了模块和路由的基础。然而,我们的第一个控制器只返回了简单的字符串。在这一步中,让我们看看实际的视图渲染。

观看这一步视频

从控制器作渲染视图

为了将参数传递给视图渲染器,控制器作返回一个 PHP 数组。保留键保存视图渲染器的参数,即要渲染视图文件的参数。$viewname

public function indexAction()
{
    return [
        '$view' => [
            'title' => 'TODO management',
            'name' => 'todo:views/admin/index.php'
        ],
        'message' => 'Hello how\'s it going?'
    ];
}

渲染后的视图文件可以是一个普通的PHP模板。简单的参数(即 )可以作为 PHP 变量(即 )。message$message

packages/pagekit/todo/views/admin/index.php:

<h1><?php echo $message; ?></h1>

资源简写

我们可以使用简写语法,而不是引用文件的完整路径。 变为 。这样打字更快,阅读也更舒服。packages/pagekit/todo/views/admin/index.phptodo:views/admin/index.php

你可以在你的 .在这个例子中,我们想指向当前的路径。index.phptodo:index.php

'resources' => [
    'todo:' => ''
],

模块配置

模块可以带一个配置阵列,可以存储各种设置。我们可以把这里当作简单的存放待办事项的储藏空间。

'config' => [
    'entries' => [
        ['message' => 'Buy milk.', 'done' => false], // ...
    ]
],

从控制器中,我们可以作为模块实例的属性访问该配置。

src/Controller/TodoController.php:

use Pagekit\Application as App;

// ...

    $module = App::module('todo');
    $config = $module->config;

// ...

我们可以将模块配置的更改存储在数据库中。默认模块配置的更改会与存储的更改合并,以确保控制器中始终有有效的配置可用。

// modifying the module config
App::config('todo')->set('entries', $entries);

步骤4:在Pagekit扩展中使用Vue.js

在为管理区构建自己的屏幕时,可以使用任何你习惯的库。但由于Pagekit自带Vue.js,了解一下它是否适合你是很有意义的。在这一步中,我们将介绍在Pagekit中使用Vue.js的基本概念。

观看这一步视频

1. 将数据传递给JavaScript

在之前的文章中,我们已经看到数据可以在PHP控制器中被访问。要在JavaScript中使用这些数据,请使用关键词将PHP数组传递给视图渲染器。Pagekit会自动将其转换为JSON表示,并在生成HTML的头部部分渲染。$data

// packages/pagekit/todo/src/Controller/TodoController.php

// ...

public function indexAction()
{
    $module = App::module('todo');

    return [
        '$view' => [
            'name' => 'todo:views/admin/index.php'
        ],
        '$data' => $module->config
    ];
}

这将在你的部分中呈现以下内容。<head>

<script>var $data = {"entries": [{"message":"Buy milk","done":false},{"message":"Drink coffee","done":true}] };</script>

2. 将视图和模型合并

ViewModel 是一个实例,将模型中的数据与视图界面同步。这被称为反应性,是Vue的关键特性之一。正确使用,有助于保持JavaScript组件小巧且易读。Vue

你可以将实例附加到DOM元素()。模型将是你传递给参数的参数。要使用Pagekit的数据,取你视图渲染的全局对象。Vueel: '#todo'datawindow.$data

你创建的任何模板都可以调用。我们会在下一步创建模板标记。methods


// packages/pagekit/todo/js/todo.js

$(function(){

    var vm = new Vue({

        el: '#todo',

        data: {
            entries: window.$data.entries,
        },

        methods: {

            add: function(e) {
                // ...
            },

            toggle: function(entry) {
                entry.done = !entry.done;
            },

            remove: function(entry) {
                this.entries.$remove(entry);
            },

            save: function() {
                // ...
            }

        }

    });

});

2. Vue 的加价

从 PHP 中,我们仍然渲染视图文件 。这里包含了所需的JavaScript文件。要让 Vue 在你的脚本中可用,可以在 中添加一个依赖作为第三个参数。views/admin/index.phpvue

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

在你的HTML中,包含Vue实例寻找的DOM元素()。在元素内部,你可以使用Vue指令。指令是某些关键词,用来告诉Vue该如何处理该元素。<div id="todo"></div>

<p v-if="entry.done">This will be displayed if the item has been done.</p>

你可以绑定到视图模型中的点击事件和调用方法。@click

要从模型输出数值,可以使用卷括号()。Pagekit 提供了一个过滤器,如果对所选位置存在翻译替代字符串,它会用一个替换字符串。{{ entry.message }}trans

{{ 'Save' | trans }}

这就是一个简单的视角可能的样子。

<!-- packages/pagekit/todo/views/admin/index.php -->

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

<div id="todo">

    <button @click="save()">{{ 'Save' | trans }}</button>

    <ul>
        <li v-for="entry in entries">
            {{ entry.message }}

            <button @click="toggle(entry)">{{ entry.done ? 'Undo' : 'Do' }}</button>
        </li>
    </ul>

</div>

了解更多关于Vue的信息

Vue.js 是一个强大的库,使得构建反应式网页界面变得容易。想了解更多信息,请查看官方指南。我们也强烈推荐Vue.js的Laracasts视频。这两个平台都是了解Vue能做什么的好地方,无论是书面形式还是视频形式。

完成的实例

在完成的示例中,我们实现了后端的实际保存,并清理了源代码。它结合了之前描述的所有步骤,我们描述了如何创建一个简单的Todo扩展。结果可以在Github上发布,供你自由探索。