sketch / app
Sketch WordPress 应用程序框架 - 示例应用程序
Requires
- sketch/sketch: dev-master
Requires (Dev)
- mockery/mockery: dev-master
- phpunit/phpunit: 4.0.*
This package is not auto-updated.
Last update: 2024-09-28 15:18:36 UTC
README
##注意:此库目前未维护。可能不建议使用。请随意分支!
#Sketch
Sketch 是一个用于在 WordPress 中创建良好结构 MVC 应用的微型框架。它提供了一套工具和推荐的架构,以便以可测试、松耦合的方式构建自定义 WordPress 功能。
Sketch 主要关注简化创建菜单页面,在这些页面上,网站管理员可以处理数据,以及自定义文章类型、元框和分类法。
$app = require_once 'app/bootstrap.php'; // Add our sample menus and submenus $app->make('Hello\Hello'); $app->make('Hello\Submenus\HelloSubmenu'); // Add our sample post type, with a metabox and a taxonomy $app->make('HelloPostType') ->addMetabox($app->make('HelloMetabox')) ->addTaxonomy($app->make('HelloTaxonomy'));
##目录
##Sketch 独特之处是什么?
Sketch 采用面向对象的方法与 WordPress 交互。虽然它不是第一个将 MVC 风格引入 WordPress 开发的尝试,但它(据我所知)是第一个利用 Composer 自动加载和 Laravel 的 IoC 容器(Laravel 的 IoC 容器)的。
Sketch 的体积非常小。它旨在能够在缺乏命令行访问的环境(例如,共享云托管)中很好地工作,这意味着 Sketch 的默认生产依赖项已经足够小,以至于如果您需要的话,不需要担心它们在版本控制下。
####何时应该使用 Sketch?
Sketch 受到如 Laravel 和 Silex 这样的全栈 PHP 框架的启发,但它绝不是要取代它们。实际上,与它们相比,它相当基础!目标是简单地提供一个更好的方法来与 WordPress 一起工作,只要与 WordPress 一起工作是有意义的。
因此,与其问“何时应该使用 Sketch”,不如问一个更好的问题:“何时应该使用 WordPress?”WordPress 有许多优点,但忽视它的限制是愚蠢的。Sketch 可以扩展您可以使用 WordPress 做好的事情,但它不能扩展 WordPress 可以做好的事情。
话虽如此——您的网站是否包含多个自定义文章类型、元框、分类法或设置页面?它是否与第三方 API 交互?尝试使用 Sketch 吧!
##安装
安装 Sketch 的最佳方式取决于您要安装的项目类型。
####安装到新项目 如果您正在将 Sketch 安装到没有 composer.json
文件和 /vendor
目录的 WordPress 项目中,可以使用 Composer(Composer)轻松完成。在终端中,导航到您的 WordPress 项目的根目录,并运行以下命令
composer create-project sketch/app -s dev your-app-name-goes-here --prefer-dist
然后,从您的主题的 functions.php
文件、您的插件或您希望实例化 Sketch 的任何位置开始,只需 require path/to/sketch/index.php
并开始构建。
####安装到已使用 Composer 的项目 如果您正在安装到已有 composer.json
文件和 /vendor
目录的项目中,请按照以下步骤操作
- 可以使用以下任一方法:运行命令
git clone https://github.com/sketchwp/app.git
,或者将此示例应用程序下载并解压到项目的根目录。 - 假设Composer已经在其他地方加载,请从
app/bootstrap.php
文件的最顶部删除包含require_once __DIR__.'/../vendor/autoload.php';
的行。如果Composer没有在其他地方加载,请保留此行不变 - 但您可能需要修改它以指向您的/vendor
目录。 - 将
"sketch/sketch": "dev-master"
添加到您的composer.json
文件的 "require" 部分。 - 运行
composer update
。 - 与全新安装类似,在
functions.php
文件、插件或其他您希望实例化Sketch的地方,要求path/to/sketch/index.php
。
##单元测试
Sketch 的主要目标之一是使 WordPress 开发者能够更容易地测试 WordPress 功能。
WordPress 的单元测试一直很痛苦,因为你不能使用任何 WordPress 函数而不实例化整个 WordPress 应用程序。使用 Sketch,如果您的任何类需要使用 WordPress 函数,只需将该类传递一个 \Sketch\WpApiWrapper
实例。该类恰好包含一个函数,即 __call($method, $arguments)
,它只是调用并返回传递给它的方法。因此,您在类中使用 get_post_meta($id, 'meta_key', true);
而不是 $this->wp->get_post_meta($id, 'meta_key', true);
。
虽然需要一点自律,但这个抽象层就是您在单元测试中模拟 WordPress 的“全局命名空间”函数所需要的。
##控制器
Sketch 的默认控制器已经填充了模板系统实例(默认为 Plates)和 Symfony 请求 对象。对于任何其他依赖项,请使用类型提示和构造函数注入 - IoC 容器将自动传递它们。当然,如果您将接口作为依赖项进行类型提示,请确保在您的 index.php 文件中使用 $app->bind('FooInterface', 'FooConcrete')
来告诉 IoC 容器应该注入哪个具体类。
假设您想要创建一个控制器,它从查询字符串中获取 page
(即菜单别名)并将其传递给视图。以下是使用 Sketch 的默认控制器完成此操作的方法:
Class HomeController extends \Sketch\WpBaseController { public function index() { $data = array( 'page' => $this->request->query->get('page') ); $this->render('home', $data); } }
如果您不希望使用 Sketch 的默认控制器,您不必这么做!您可以使用 服务提供者 注册不同的控制器类型。请随时寻求帮助!关于这方面的文档尚未编写。
##视图
对于与上述控制器示例对应的视图,创建一个名为 app/views/home.php
的文件。要输出 page
变量,请在模板的任何地方使用 <?= $this->page ?>
。
一些变量会自动传递给每个视图:nonce_name
、nonce_action
、message
和 errors
。此外,Sketch 还附带了一些简单的 Plates 扩展,最重要的是 wp()
函数,它提供了对 \Sketch\WpApiWrapper
的访问。将函数名称作为第一个参数传递,将参数数组作为第二个参数传递。
请参阅 Plates 文档了解有关默认视图可以做什么的更多信息。
与 Sketch 的默认控制器一样,Plates 被注册为 服务提供者。将其替换为您选择的模板引擎并不难。请随时寻求帮助!关于这方面的文档尚未编写。
##模型
基础模型提供了三种与Wordpress数据进行交互的方式: \Sketch\WpApiWrapper
、\Sketch\WpQueryFactory
和 \Sketch\WpDbWrapper
。这样,您可以按照自己的喜好获取帖子和数据对象,无论是使用常规Wordpress函数(例如,$this->wp->get_posts()
),通过创建新的WP_Query对象($this->wp_query->make($args)
),还是使用 $this->wpdb->get_results($prepared_sql)
。
如果这对您的项目来说太简单了,请记住您并不需要使用Sketch的基础模型。您可以轻松地编写自己的基础模型类,或者如果您不将小体积作为高优先级,甚至可以使用类似 Eloquent ORM 的东西。
##菜单
通常,当您创建Wordpress菜单时,您使用 add_menu_page()
函数并传递一个回调,该回调定义了菜单应该显示的一切。使用Sketch,您通过扩展 \Sketch\Menu\WpMenuAbstract
或 \Sketch\Menu\WpSubmenuAbstract
类来创建菜单。将菜单标题、slug和权限等定义为类的属性,Sketch将处理其余部分。Sketch的菜单类将路由类作为依赖项,this->router->resolve()
是在运行时Wordpress创建菜单时传递给Wordpress的回调。
如果您需要添加与菜单相关的任何操作(例如,队列公共资源),请覆盖菜单的 addActions()
方法,并使用菜单的 \Sketch\WpApiWrapper
实例添加这些操作。例如
protected function addActions() { $this->wp->wp_enqueue_script('my_script', 'path/to/my/script.js'); }
就像您在 app/menus
文件夹中看到的那样定义您的菜单类,并在 index.php
中通过调用 $app->make('MyMenu')
来实例化它们;
####菜单路由
Sketch的菜单路由器主要旨在创建Wordpress管理后端菜单页面的导航。目前,它不感兴趣创建前端路由或“篡改”Wordpress的本地路由系统。相反,它旨在与现有系统友好地协作。
Wordpress的管理菜单导航主要基于查询字符串的内容,因此Sketch的路由器通过传递需要匹配的查询字符串变量关联数组或实际的查询字符串进行配置。此外,您还将传递应处理匹配路由的控制器和方法名称。
以下示例都是相同的
$app['router']->get('?page=my_menu_slug&action=index', 'HomeController@index');
$app['router']->get('action=index&page=my_menu_slug', 'HomeController@index');
$app['router']->get(['page' => 'my_menu_slug', 'action' => 'index'], 'HomeController@index');
上面的示例将导致Sketch查找 HomeController
类,并运行其 index()
方法。您也可以传递回调函数而不是控制器引用。路由器有 post()
或 any()
方法来处理GET和POST请求。对于GET和POST以外的其他方法,使用 register('METHOD', $params, $controller)
。请注意,无论您传递查询字符串还是数组,变量的传递顺序都不重要。此外,当传递查询字符串时,您可以包含或排除'?'。
目前,路由器非常简单。它只能匹配相同的字符串或 {int}
变量。因此,如果您想编辑特定的“foo”项,您的路由可能看起来像这样
$app['router']->get(array('page' => 'my_foo_menu_slug', 'action' => 'edit', 'id' => '{int}'), 'FooController@edit');
在 app/menus/routes.php
中定义您的菜单路由。由于第一个匹配的路由将被选中,因此首先定义最具体的路由,然后是最不具体的路由。
##自定义文章类型
与菜单类似,您可以通过扩展 \Sketch\CustomPostType\BaseCustomPostType
类来创建一个新的自定义文章类型。再次强调,将文章类型的参数定义为类的属性。您可以将 $args
、$labels
和 $rewrite
变量分别定义为它们自己的数组。Sketch 在运行时创建文章类型时,会自动将 $labels
和 $rewrite
参数添加到 $args
数组中。这种安排虽然略微偏离了正常的“WordPress方式”,但似乎是最易于阅读的解决方案。
在 index.php
中实例化自定义文章类型时,请添加元框和分类(请参阅页面顶部的第一个代码示例)。
##元框
Sketch 元框与自定义文章类型和菜单非常相似。通过扩展 \Sketch\Metabox\BaseMetabox
类来创建元框。将元框的参数定义为类的参数。
但是,还有更多!除了将标准元框参数定义为类参数之外,您还必须指定一个控制器和用于处理元框业务逻辑的方法。
以下是示例 Sketch 应用程序中提供的基本元框的代码
class HelloMetabox extends BaseMetabox { protected $id = 'hello_metabox', $post_type = 'hello_post_type', $callback_controller = 'HelloController@metabox' ; }
就像菜单路由一样,元框的控制器由 IoC 容器解析,并且可以访问 Symfony 请求对象和 Plates 模板系统。此外,(就像所有 WordPress 元框一样)它还将传递有关当前显示的文章和元框本身的信息。以下是我们的示例元框控制器
public function metabox($post, $metabox) { $data = [ 'post' => $post, 'metabox' => $metabox ]; $this->render('hello::metabox', $data); }
在您的应用程序中实例化此元框有两种方式。第一种方式如本页顶部所示 - 通过在应添加元框的文章类型上调用 ->addMetabox($app->make('HelloMetabox'))
。注意,如果您使用此方法,则不需要在元框本身上设置 $post_type
参数。当您将其添加到文章类型对象时,它将自动设置。
第二种方法是,在您的 Sketch 应用程序的 index.php
文件中实例化元框后,调用元框的 ->manuallyAddAction()
函数。例如
$app->make('HelloMetabox')->manuallyAddAction();
如果您使用此方法,则必须设置 $post_type
参数。否则,它将不会在任何地方显示。
##分类
要创建分类,扩展 \Sketch\Taxonomy\BaseTaxonomy
类,并按与自定义文章类型相同的方式添加分类的参数。除了 $args
、$labels
和 $rewrite
数组之外,分类还可以有一个 $capabilities
数组。
##验证
Sketch 默认提供 Valitron 验证类。您可以直接在任何类中使用 Valitron,Sketch 还提供了一个 \Sketch\ValidatorFactory
类,以便您可以更容易地注入验证器实例或设置验证服务。
##服务提供者
服务提供者是放置第三方服务的引导代码并注册到 Sketch 应用程序的好地方。要创建服务提供者,首先创建一个新的类,该类实现 \Sketch\ServiceProviderInterface
。
Sketch 服务提供者只需要实现一个方法:register(\Sketch\Application $app)
。该方法是在应用程序上注册绑定的好地方。例如
use \Sketch\Application; use \Sketch\ServiceProviderInterface; class MyProvider implements ServiceProviderInterface { public function register(Application $app) { $app->bind('FooInterface', function() { $config = array('foo' => 'bar'); return new FooClass($config); }); } }
您还可以将配置值数组作为 register 方法的第二个参数传递
public function register(Application $app, $config) { $app->bind('FooInterface', function() use($config) { return new FooClass($config); }); }
在 Sketch\index.php
中注册您的服务提供者,紧挨着实例化菜单、自定义文章类型等的位置。这也是您需要传递那些配置值的地方,如果情况需要的话
$app = require_once 'app/bootstrap.php'; $config = array('foo' => 'bar'); $app->register(new MyProvider(), $config);
要查看更多服务提供者示例,请查看 app/bootstrap.php
文件,其中注册了 Plates 模板系统和 Sketch 的默认控制器工厂。
##重大变更和向后兼容性
Sketch 目前处于某种alpha或beta阶段,对核心框架的一些更改将需要修改应用程序。
如果您正在使用Sketch(根据packagist,您没有使用),并且运行composer update
导致您的应用程序崩溃(请务必在本地测试后再更新生产依赖项),以下是一些您可以做的事情:
- 将最新Sketch引导文件中的代码复制到您的应用程序的
app/bootstrap.php
文件中。 - 在元框和
app/menus/routes.php
中更新控制器引用。由于最近更改了Sketch\ControllerDispatcher
类,您现在必须将控制器完整类名传递给路由器。即,将hello@index
更改为HelloController@index
。 - 如果第1步和第2步不起作用,请创建github问题,或者如果紧急,直接联系我。我很乐意提供帮助!
##致谢
Sketch是在ArcStone创建的,ArcStone是一家位于明尼苏达州明尼阿波利斯市的网站开发、设计和营销机构。