larawelp / theme
WordPress的LaraWelP主题,由Laravel驱动。
Requires
- php: ^8.0
- larawelp/foundation: ^0.0
README
Laravel是一个具有表达性和优雅语法的Web应用程序框架。它是当今最受欢迎的PHP框架之一。
LaraWelP将Laravel框架引入WordPress,使我们能够享受到Laravel的所有好处。因此,您可以轻松地、愉快地创建主题!
要求
LaraWelP的99%都是普通的完整栈PHP框架Laravel。所以如果您从未听说过它,您在继续之前最好先看看它。
对于那些已经熟悉Laravel的人来说,开始使用LaraWelP应该易如反掌。
LaraWelP是什么以及不是什么
LaraWelP不是一个用于通用WordPress主题开发的框架。
是的,它是一个框架,但不是用于通用WordPress主题开发的框架。LaraWelP旨在帮助创建“自制主题”,而不是通用主题。因此,如果您想创建带有大量主题选项的主题用于销售或免费分发,您可能需要查看以下框架。
与原始Laravel相比有何不同?
我认为几乎没有差异,除了进行一些调整,以使Laravel在WordPress主题内部运行良好。所以基本上,您可以在WordPress主题内做任何您可以用Laravel做的事情。如果您对到底修改了什么感到好奇,查看原始Laravel的差异对于您来说是有意义的。
已知问题
WordPress使用mysqli
连接数据库,但Laravel使用PDO
。因此,如果您想使用Laravel的DB
外观,您必须安装PHP的pdo_mysql
扩展。LaraWelP正在进行Laravel的mysqli
驱动程序,但到目前为止,在PDO不可用的环境中(例如:wp-env)您可能会遇到错误。
入门
安装
您可以通过Composer
执行以下命令来安装LaraWelP。 composer create-project --prefer-dist larawelp/theme <theme-name>
请注意,在您执行composer create-project
命令以安装LaraWelP之前,必须运行MySQL服务器和Web服务器。因为Composer安装完成后,它将运行一个Artisan命令,该命令要求MySQL服务器和托管WordPress的Web服务器在您执行命令时正在运行。
此外,请注意,如果您在Mac上并且使用MAMP或类似应用程序创建本地服务器环境,您可能需要更改您的$PATH
环境变量,以便Composer使用MAMP提供的PHP二进制文件而不是操作系统内置的PHP二进制文件。
路由
LaraWelP用自己的一套替换了原始的UriValidator
(Illuminate\Routing\Matching\UriValidator
),允许您指定WordPress特定的路由,如“存档”、“页面”或“自定义帖子类型”等。
要定义一个WordPress特定的路由,只需提供一个“页面类型”作为第一个参数即可。
例如
// The "about" page Route::any('page.about', Controller@method); // The child page "works" of "about". Route::any('page.about.works', Controller@method); // Any child page of "about". Route::any('page.about.*', Controller@method); // Any descendant page of "about". Route::any('page.about.**', Controller@method); // Grouping multiple routes that sharing a common `prefix`. Route::group(['prefix' => 'page'], function () { Route::any('about.contact', function () { return 'Foo'; // equivalent to <page.about.contact> }); Route::any('service.*.price', function () { return 'Bar'; // equivalent to <page.service.*.price> }); }); // IMPORTANT ! // // Routes that has a higher specificity should be // placed more above(earlier) than the routes that have a lower specificity. // Why? If you place the routes that have a lower specificity, // the subsequent routes that have a higher specificity will be ignored. // // The following routes have a lower specificity than the above ones. // So you want to place them here. // Generic pages Route::any('page', Controller@method); // Front page Route::any('front_page', Controller@method); // Post archive index page Route::any('archive', Controller@method);
以下是一些需要注意的注意事项。
- 您可以使用“点表示法”指定页面和分类的层次结构。
- 您可以使用通配符指定任何子/后代页面/术语的父/祖先页面/术语。
- 你应该注意你的路由顺序。具有更高特异性的路由应该比具有较低特异性的路由放置得更靠上。
更重要的是,你甚至可以通过URI编写自己的路由,它只需这样就能工作。
// This will use the original UriValidator of Laravel. Route::get('/my/endpoint', function () { return 'Magic!'; });
模型
LaraWelP附带了一些通用模型,如Post
或Term
模型。请注意,它们不是像Laravel的Eloquent模型那样的ORM实现。它们只是WordPress API的简单包装,封装了一些常用逻辑,以帮助您简化业务逻辑。
您可以在LaraWelP\WpSupport\Model
中找到这些模型。因为Post
模型是最常用的模型,为了方便起见,一个扩展了LaraWelP\WpSupport\Model\Post
的Post
类已经带到了您的app/Models
目录中。
让我们看看一个例子。
看看你有一个这样的路由
Route::any('archive', 'Generic\Archive@index');
在您的控制器app\Http\Controllers\Generic\Archive
<?php namespace App\Http\Controllers\Generic; use App\Http\Controllers\Controller; use App\Models\Post; class Archive extends Controller { public function index() { $data = [ 'posts' => Post::queriedPosts() // get the posts for current page ]; return $this->view('generic.archive', $data); } }
在您的视图generic.archive
<main class="posts"> @foreach($posts as $post) <section class="post"> <a class="post" href="{{ $post->permalink }}"> <img class="post__thumbnail" src="{{ $post->thumbnail->url }}" alt="{{ $post->title }}"> </a> <time class="post__time" datetime="{{ $post->dateTime }}">{{ $post->date }}</time> <a class="post__category" href="{{ $post->category->url }}">{{ $post->category->name }}</a> <h1 class="post__title">{{ $post->title }}</h1> </section> @endforeach {{ $posts->getPagination() }} </main>
正如您在上面的例子中看到的,您可以获取帖子的常见属性,如$post->permalink
或$post->title
等。
实际上,这些属性
并不是“真实属性”。当您访问属性如$post->permalink
时,在底层,它会自动调用$post->permalink()
来获取值,并且从第二次访问相同的属性开始,它不会再次调用$post->permalink()
,而是返回上次调用结果的缓存值。如果您不想使用缓存值,可以显式调用方法,如$post->title()
。您还可以自由地为模型类添加公共方法来创建自己的“属性”。
查看LaraWelP\WpSupport\Model,其中有一些预定义的“属性”您可能想使用。
@loop
blade指令
LaraWelP还添加了一个@loop
blade指令来简化WordPress中的"The Loop"。
例如
@loop($posts as $post) {{ get_the_title() }} @endloop
将被编译为
<?php foreach($posts as $post): setup_the_post( $post->wpPost ); ?> <?php echo e(get_the_title()); ?> <?php endforeach; wp_reset_postdata(); ?>
其中$post
应该是一个Post
模型对象。
通常您不想使用@loop
指令。因为它会引入一些不必要的开销。请记住,始终首选@foreach
而不是@loop
。除非您想访问一些像content
或excerpt
这样的属性,这些属性必须在"The Loop"中检索,否则绝不要主动使用@loop
。
主题选项
设置自定义文章类型,注册导航菜单……当您开始构建WordPress主题时,总有一些常见任务您必须处理。《app/config/theme.php》是您定义所有常见任务的地方。
为您的提供了一些基本选项。查看config/theme.php。
此外,您可以通过向App\Providers\ThemeOptionsProvider
添加新静态方法来创建自己的选项。方法名称将成为一个选项。
动作和过滤器
您在App\Providers\EventServiceProvider
中定义您的动作和过滤器,就像Laravel的事件一样。
以下示例添加了一个pre_get_posts
动作,并且App\Listeners\MainQueryListener
的handle
方法将被此动作调用。
<?php namespace App\Providers; use LaraWelP\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider { /** * Register the WordPress actions * @var array */ protected $action = [ 'pre_get_posts' => 'App\Listeners\MainQueryListener' ]; /** * Register the WordPress filters * @var array */ protected $filter = []; }
分页
您可以通过调用Post
的getPagination
方法来获取分页。
use App\Models\Post; $posts = Post::queriedPosts();
<div> {{ $posts->getPagination() }} </div>
通过提供额外的参数,您可以指定视图文件和几个选项。有关更多详细信息,请参阅larawelp/pagination。
选项页面
创建选项页面可能是最枯燥的任务之一。如果你使用过WordPress的API来创建选项页面,你就会知道代码会多么混乱...
LaraWelP提供了一个强大且简洁的API,帮助你创建选项页面。
更多信息请参阅 larawelp/options。
查看调试器
有时候,你可能只想获取当前显示的视图(页面)的一些基本信息。例如,视图文件的路径或使用的控制器名称。
要获取当前显示的视图的基本信息,你需要在你的 App\Http\Controllers
中包含 ViewDebbuger
trait。打开你的浏览器控制台,你会看到类似以下内容
{ "view_path": "/var/www/example/wp-content/themes/example/resources/views/singular/news.blade.php", "compiled_path": "/var/www/example/wp-content/themes/example/storage/framework/views/befa3e2a2cb93be21c6ebf30a60824a5d2a2ed11.php", "data": { "post": {} }, "controller": "App\\Http\\Controllers\\Singular\\News" }
请注意,当在 .env
文件中将 APP_ENV=production
设置为生产环境时,控制台不会输出任何内容。
运行 artisan 命令
正如我在安装部分所提到的。要运行artisan命令,你必须满足以下条件。
- MySQL服务器和Web服务器必须正在运行。
- 如果你使用MAMP或其他类似的应用程序在Mac上创建本地服务器环境,你可能需要更改你的
$PATH
环境变量,以便Composer使用MAMP提供的PHP二进制文件,而不是操作系统内置的PHP二进制文件。
已知问题
如果你有一个使用Composer的插件,并且该插件与你的主题(LaraWelP)有相同的依赖项,当它们使用该依赖项的不同版本时可能会导致问题。在这种情况下,它将 require
多个Composer Autoloaders(vendor/autoload.php
),并且 最后加载的那个将优先于之前的那些。
例如,你有一个依赖于包 Foo (v1.2.0)
的插件,你的主题依赖于相同的包 Foo (v2.0.1)
;这种情况可能导致加载不想要的 Foo
版本。使用的版本取决于 autoloader.php
被加载的时间和包(类)被使用的时间。
也就是说,这不是Composer特有的问题。我认为这是一个需要解决的WordPress问题。
以下是讨论此问题的WordPress文章。