A Better Wordpress
, (*1)
ABetter Wordpress is a turnkey solution for using Wordpress on top of Laravel to build exceptionally fast web applications β while still using the worlds most popular CMS to manage content and translations., (*2)
Our methodology to fast web applications is all about Separation of Concerns (SoC) and Scalable Static Caching. We let Wordpress handle the content back-end and Laravel the standalone front-end. Additional API and web services for dynamic content are also routed through Laravel., (*3)
With the ABetter Toolkit we give Laravel/Blade some new powerful directives helping us separate as much as possible in standalone and resusable components β much inspired by ReactJS/VueJS., (*4)
Requirements
- PHP 7.2+
- Imagick 3+
- MySQL 5.7+
- Composer 1.6+
- Laravel 5.8+
- Deployer 6+
- Node 10.0+
- NPM 6.4+
Installation
Via Composer:, (*5)
composer create-project --prefer-dist laravel/laravel . "6.*"
composer require abetter/wordpress
Laravel modifications
Add post install/update script to composer.json:, (*6)
"scripts": {
"post-install-cmd": [
"ABetter\\Wordpress\\ComposerScripts::postInstall"
],
"post-update-cmd": [
"ABetter\\Wordpress\\ComposerScripts::postUpdate"
]
}
Note: The script will modify any core files using the global __() method for string translations and add a cross-framework workaround. Sadly wordpress core do not check for function_exists before defining global __(), which breaks Laravel + Wordpress compatibility without modification., (*7)
Add middleware to app/Http/Kernel.php:, (*8)
protected $middleware = [
\ABetter\Toolkit\SandboxMiddleware::class,
\ABetter\Wordpress\Middleware::class,
];
Note: The middleware helps Blade clear the view cache when developing many nested components., (*9)
Preparations
- Setup a local host domain using .loc, (e.g. www.abetter.loc)
- Point the host to /public
- Create a local mysql database
Setup Laravel
Edit .env settings, (*10)
APP_NAME=<name>
APP_VERSION=<version>
APP_KEY=base64:insert/base64/encoded/aes256/encryption/key=
APP_ENV=<sandbox|local|dev|stage|production>
APP_DEBUG=<true|false>
APP_URL=<url>
APP_PROXY=<browsersync-proxy-url>
DB_DATABASE=<database>
DB_USERNAME=<username>
DB_PASSWORD=<password>
WP_THEME=<optional-views-subfolder>
WP_AUTOLOGIN=<optional-autologin-user>
WP_REQUIRELOGIN=<optional-require-login-to-view>
Note: Use APP_ENV=sandbox when developing with browsersync., (*11)
Add routes to /routes/web.php, (*12)
// ABetter Toolkit services
Route::any('image/{style?}/{path}', '\ABetterToolkitController@handle')->where('path','.*');
Route::any('proxy/{path}', '\ABetterToolkitController@handle')->where('path','.*');
Route::any('browsersync/{event?}/{path}', '\ABetterToolkitController@handle')->where('path','.*');
Route::any('service/{path?}.{type}', '\ABetterToolkitController@handle')->where(['path'=>'.*','type'=>'json']);
// ABetter Wordpress main route
Route::any('{path}', '\ABetterWordpressController@handle')->where('path','^(?!nova-api|nova-vendor|nova|api).*$');
Note: Remove any other routes for root or wp paths (i.e default Welcome)., (*13)
Copy the Deployer file to root and run setup once:, (*14)
cp vendor/abetter/toolkit/deploy/deploy.php deploy.php
dep setuponce local
Run audit fix if needed:, (*15)
npm audit fix
Note: Only run the setuponce on fresh projects, since it will replace files in /resources and /public., (*16)
Test to build the app:, (*17)
dep build local
Setup Wordpress
Go to host in browser (e.g. http://www.abetter.loc) and follow install instructions., (*18)
Go to /Appearance/Themes, and activate ABetter theme., (*19)
Go to /Plugins, and activate:, (*20)
- Advanced Custom Fields.
- Disable Gutenberg (full support is coming soon...).
- ... Any other of the supported plugins you need.
Add default pages:, (*21)
<name> : <slug> : <template> : <order>
Start : start : default : -1
News : news : default : 200
Privacy Policy : privacy-policy : default : 200
Search : search : search : 400
403 Forbidden : 403-forbidden : error : 403
404 Not found : 404-not-found : error : 404
Go to /Settings/Reading:, (*22)
- Select Start as homepage
- Select News as post page
Finaly, go to host in browser:, (*23)
Congratulations to your new site!, (*24)
Usage
Development
Use npm to start webpack and browsersync:, (*25)
npm run watch
... or if using php artisan serve:, (*26)
php artisan serve & npm run watch
NOTE: With "php artisan serve" you need to modify APP_PROXY in .env to http://127.0.0.1:8000., (*27)
Component file structure
.
βββ public # Handled by build script (will be overwritten)
βββ routes # Add any development routes to /web.php
βββ resources #
β βββ scripts # Global scripts in "app.js"
β βββ styles # Global styles in "app.scss"
β βββ fonts # Fonts here (will copy to /public on build)
β βββ images # Images here (will copy to /public on build)
β βββ videos # Videos here (will copy to /public on build)
β βββ views #
β β βββ <theme> # Subfolder defined in .env / WP_THEME
β β β βββ template.blade.php # Template file requested in route
β β β β βββ components #
β β β β β βββ menu # Component subfolder:
β β β β β β βββ menu.blade.php # Template file : @component('components.menu',TRUE)
β β β β β β βββ menu.scss # Sass file : @style('menu.scss')
β β β β β β βββ menu.js # Javascript file : @script('menu.js')
...
/vendor/abetter/wordpress/ # Default components will be used if not overridden!
βββ views # (e.g. html head start/end is rendered from here)
β βββ default #
β β βββ robots.blade.php # Default Robots.txt template
β β βββ sitemap.blade.php # Default Sitemap.xml template
β β βββ components #
β β β β βββ html # Default HTML head components
β β β β βββ missing # Default debugging for missing components
β β β β βββ robots # Default Robots.txt component
β β β β βββ sitemap # Default Sitemap.xml component
...
Note: Component names will be auto-resolved if the blade file has same basename as folder., (*28)
Note: Linked JS/Sass files in components will be external files in development to support browsersync live, but will be embedded in html source on Stage/Production environments for better caching., (*29)
Note: You can auto-terminate a @component with TRUE as the second paramater, to avoid writing out @endcomponent, e.g when not using any slots or nested content., (*30)
Deployment
(coming soon), (*31)
Contributors
Johan SjΓΆland johan@sjoland.com
Senior Product Developer: ABetter Story Sweden AB., (*32)
License
MIT license. Please see the license file for more information., (*33)