10up / nodeifywp
将WordPress主题转换为同构JavaScript应用的API。需要PHP的V8Js。
Requires
- gmazzap/url-to-query: ^1.0
This package is auto-updated.
Last update: 2021-06-25 19:32:22 UTC
README
NodeifyWP 允许您使用WordPress和PHP创建同构JavaScript应用。使用NodeifyWP,您可以使用WordPress管理内容,并通过前端直接以同构方式输出内容,而无需使用Express等任何东西。NodeifyWP 提供了WordPress和强大的同构Node.js技术的所有优点。
背景
同构Web应用(在服务器和客户端上运行相同的代码)因其提供的灵活性、可扩展性和一致性,而成为构建大型和强大“应用程序”体验的必备。JavaScript和Node.js用于创建同构应用,因为JS可以在Web浏览器中本地运行。
随着800万个不同的同构Web框架和策略出现在JavaScript周围,我们WordPress社区一直被困在PHP世界中,在那里同构实际上并不可能实现。我们相信WordPress是一个极其相关和有用的完整内容管理系统,提供了最好的整体编辑体验。因此,我们不希望为了最新的“热门”Web技术而放弃WordPress。
要在WordPress中创建由JavaScript驱动的“应用程序”体验,我们目前有几个选择
-
创建一个带有客户端层的PHP主题,使用Underscore模板和REST API刷新DOM。这种策略允许我们达到预期效果,但这种方法有点强制,因为我们必须在PHP中创建模板,并为JavaScript创建单独的模板。从开发角度来看,这种结构很难维护。
-
随着REST API的发布,我们可以完全放弃WordPress的前端。我们可以使用Node.js和类似Express的东西来提供我们的前端,并通过REST API与WordPress通信。这很好,但带来了一些严重的困难。首先,我们必须进行外部请求来获取像主题选项、菜单和侧边栏这样的简单内容。自定义器功能基本上是无效的。预览和评论很难实现。管理员栏消失了。前端认证变得极其困难。插件无法与前端交互。
-
前两个选项的某种混合。
目前可用的选项使我们决定构建NodeifyWP。
NodeifyWP利用PHP在服务器上执行Node.js代码。 这得益于V8Js,这是一个用于谷歌V8引擎的PHP扩展。NodeifyWP在服务器端JavaScript中暴露WordPress钩子、导航菜单、侧边栏、文章等。它提供了一个简单的API,用于在JavaScript中注册PHP "标签"。它还包括一个REST API,用于检索路由信息、更新标签、侧边栏、菜单等,以适应应用程序状态的变化。使用NodeifyWP,我们可以在PHP中提供真正的同构应用程序。我们获得了WordPress和强大的同构Node.js技术的所有好处。不需要单独的Node.js/Express服务器。
要求
- PHP V8Js。如果您想使用PHP7的V8Js,您可能需要进行一些调整。我们的Twenty Sixteen React主题内置了一个开发环境,使用Dockerfiles创建一切。
- 谷歌V8
- PHP 5.6+
- WordPress 4.7+
我们创建了一个Docker化NodeifyWP环境,为您设置所有这些。
安装
- 安装并启动NodeifyWP环境。由于V8Js和V8的设置可能很困难,我们创建了这个打包的环境。我们强烈推荐使用它。
- 安装插件。您可以从WordPress.org或作为Composer依赖项安装。
- 激活插件。
- 记住,NodeifyWP是一个框架。构建或使用实现NodeifyWP的主题。
主题
以下主题是用NodeifyWP构建的
Twenty Sixteen React是一个使用以下技术重建的NodeifyWP WordPress主题
使用
确保NodeifyWP正确安装(无论是作为插件还是Composer依赖项)后,将以下内容添加到您的主题中的functions.php
\NodeifyWP\App::setup( $server_js_path, $client_js_url = null, $includes_js_path, $includes_js_url = null );
$server_js_path
应该是您的服务器JS入口点的绝对路径。$client_js_url
应该是您的client.js入口点的URL。
您可以向setup
方法提供可选的第三个和第四个参数,即$includes_js_path
和$includes_js_url
。$includes_js_path
应指向一个包含您的应用程序包含项的服务器端JavaScript文件,$includes_js_url
指向客户端的相同包含项。在这里存储您的包含项将允许NodeifyWP使用V8堆快照来缓存您的包含项。
设置完成后,NodeifyWP将通过执行服务器端JavaScript并退出来自动接管您的主题。在index.php、header.php、archive.php等文件中不会解析任何PHP代码。
NodeifyWP通过使用V8Js中的全局变量PHP.context
将WordPress设置、侧边栏、文章等传输到JavaScript。此上下文对象允许您同构渲染您的主题。上下文对象如下构建
PHP.context.$route
- 包含关于当前显示的页面信息。
示例
PHP.context.$route = { type: 'home', // Type of route being shown i.e. home or single object_type: null, // Type of object being viewed i.e. category if viewing a category archive object_id: null // ID of object if viewing a single };
PHP.context.$nav_menus
- 一个以菜单名称为键的对象,包含每个已注册的主题菜单。
示例
PHP.context.$nav_menus = { primary: [ { title: 'Link title', url: 'http://site.com', children: [ ... ] } ] };
PHP.context.$posts
- 当前路由的帖子数组。对于页面,数组中只有一个帖子。
示例
PHP.context.$posts = [ { ID: 1, post_title: '', post_content: '', the_title: '', // Filtered title the_content: '', // Filtered content post_class: '', // Post classes for current post permalink: '', ... } ];
PHP.context.$sidebars
- 包含侧边栏HTML的对象,键为侧边栏名称。
示例
PHP.context.$sidebars = { 'sidebar-1': 'Raw sidebar HTML' };
PHP.context.$template_tags
- 包含已注册的模板标签。请参阅下面的API部分以了解注册模板标签
示例
PHP.context.$template_tags = { wp_head: 'Raw wp_head HTML' };
PHP.context.$user
- 包含当前登录用户的信息。
示例
PHP.context.$user = { user_login: '', user_nicename: '', ID: '', display_name: '', rest_nonce: '' };
PHP.client_js_url
- 客户端JavaScript文件的URL。
在您的服务器端JavaScript中,您可以像这样打印或检查这些对象之一
print(PHP.client_js_url); print(require('util').inspect(PHP.context.$sidebars));
API
NodeifyWP有几个有用的API方法可用
\NodeifyWP\App::instance()->register_template_tag( $tag_name, $tag_function, $constant = true, $on_action = 'nodeifywp_render' );
已注册的模板标签“localize”用于在JavaScript中使用的内容。默认情况下,NodeifyWP包括一些常见的模板标签,如wp_head
(见standard-tags.php
)。模板标签在PHP中以以下方式提供
- (string)
$tag_name
:标签名称。将在JS中作为PHP.context.$template_tags.$tag_name
可用。 - (callable)
$tag_function
:此函数将被执行以确定标签的内容 - (boolean)
$constant
:常量标签在客户端导航时(在get_route
API调用中)不会重新计算。 - (string)
$on_action
:您可以选择模板标签应在哪里渲染
\NodeifyWP\App::instance()->register_post_tag( $tag_name, $tag_function );
已注册的帖子标签“localize”用于在JavaScript中单独的帖子对象中使用的内容。
- (string)
$tag_name
:标签名称。将在JS中作为PHP.context.$posts[...][{$tag_name}]
可用。 - (callable)
$tag_function
:此函数将被执行以确定标签的内容。一个WP_Post
对象将传递给函数并设置为全局帖子。
例如,要注册用于在JavaScript中每个帖子中使用的帖子元数据
\NodeifyWP\App::instance()->register_post_tag( 'my_meta', function( $post ) { $meta = get_post_meta( $post->ID, 'my_meta', true ); echo $meta; } );
然后帖子标签将在JavaScript中作为PHP.context.$posts[...].my_meta
可用。
V8Js "注意事项"
console
不存在。请使用print()
代替。setTimeout
不存在。
基准测试
NodeifyWP(及其支持的主题)不是性能瓶颈,并且将随着任何WordPress网站进行扩展。我们已编译了使用NodeifyWP主题的Twenty Sixteen React的基准测试,与标准Twenty Sixteen主题进行比较。从我们的基准测试中获得的经验教训
- 未设置缓存时,Twenty Sixteen React的平均响应时间比相同配置的Twenty Sixteen长约200ms。
- 使用NodeifyWP(包括(堆快照)和对象缓存),Twenty Sixteen React的平均响应时间比相同配置的Twenty Sixteen长约150ms。
- 使用对象缓存和页面缓存(Batcache),Twenty Sixteen React的平均响应时间比相同配置的Twenty Sixteen慢40ms。
由于NodeifyWP和Twenty Sixteen React依赖于V8,因此不可避免地会有一些开销。然而,通过优化V8和V8Js,我们的基准测试表明我们可以减少足够的多余开销,以至于对页面加载时间感知的影响几乎可以忽略不计。此外,运行SPA风格网站的用户体验提升使NodeifyWP成为一个更吸引人、更适用于生产的框架。
贡献
我们非常期待看到社区对项目的反应。我们很高兴收到使用NodeifyWP的开源主题的链接。
许可证
这是一款免费软件;您可以在自由软件基金会发布的GNU通用公共许可证的条款下重新分发或修改该软件;许可证的版本可以是2.0版本,或者(根据您的选择)任何更新的版本。
支持级别
已存档:该项目不再由10up维护。除非与安全问题相关,否则我们不再响应问题或拉取请求。我们鼓励感兴趣的开发商分叉该项目并使其成为自己的项目!