WP Emerge 0.15.0: What’s new and what’s next
The release of 0.15.0 is a major stepping stone towards a stable 1.0.0 release. As such, it includes a number of minor breaking changes aimed at extensibility and consistency across the board.
Framework (GitHub)
What’s New
- Defining routes and route groups has been completely rewritten (docs).
-
You can now define Web, Admin and AJAX routes each with their own global middleware.
-
Automatic namespace prefixes have been added for Controllers, View Composers and Middleware.
This allows you to define controllers like this:HomeController@home
which will be automatically prefixed like this:
\App\Controllers\HomeController@home
Note: you can still use fully qualified class names – the prefix is only added if the class does not exist.
-
Route namespace prefixes can be adjusted on a per-group or per-route basis.
For example this:Route::setNamespace( '\\App\\Controllers\\Dashboard\\')->group( function () { Route::get()->url( '/dashboard/profile' )->handle( 'Profile@view' ); } );
will result in this:
\App\Controllers\Dashboard\Profile@view
- Added a new
Route::view()
shortcut to directly rendering a view in response to a request.
Example:Route::get()->url( '/' )->view( 'index.php' );
- Middlewares now use string aliases that you need to register in your configuration (docs).
Example:// Configuration: 'middleware' => [ 'foo' => FooMiddleware::class, ], // Routes: Route::middleware( 'foo' )->...
- Added ability to pass basic parameters to middleware (docs).
Example:Route::middleware( 'user.can:manage_options' )->...
- Arbitrary middleware groups can now be created and assigned as middleware to routes by utilizing the new aliases functionality. You can even reference groups within groups (docs).
Example:// Configuration: 'middleware_groups' => [ 'privileged' => [ 'user.logged_in', 'user.can:manage_options', ], ], // Routes: Route::middleware( 'privileged' )->...
- Middleware ordering has been simplified and made consistent in cases where priority has not been specified (docs).
-
Middleware classes are now instantiated through the container allowing for dependency injection.
-
Introduced several new built-in middlewares to deal with authentication and authorization:
user.logged_in
,user.logged_out
anduser.can
(docs). -
Introduced
WPEmerge\run()
which allows you to run a full middleware + controller pipeline and get a response object independently from defined routes.
Running this:$response = \WPEmerge\run( \WPEmerge\Requests\Request::fromGlobals(), ['user.logged_in'], function ( $request, $foo ) { return 'Hello ' . $foo; }, ['World'] );
will result in a PSR-7 response object be it a redirect response if the user is not logged in due to the middleware supplied or a 200 OK response with a body of ‘Hello World’.
If you want to output the response as usual you can use\WPEmerge\Facades\Response::respond( $response )
; -
Added support for multiple views directories for all view engines.
You can now specify a single path or an array of paths. -
Fixed a race condition in Blade and Twig which caused global variables to not be available if registered too early.
-
The URL condition now has full regular expression support through a new parameter (docs).
Example:Route::get()->url( '/year/{year}', ['year' => '/^\d+$/'] )->...
- Added
@method
annotations for every facade class for improved IDE support. -
Various codebase-covering improvements targeting consistency and simplicity.
-
Various improvements to the documentation including a new
CONTRIBUTING.md
file in the repository.
Breaking Changes
-
Routes now must be defined in a separate file and then referenced in the configuration (docs):
// Configuration: 'routes' => [ 'web' => 'routes/web.php', 'admin' => 'routes/admin.php', 'ajax' => 'routes/ajax.php', ],
All groups are optional so you do not need to create an admin routes file if you have no admin routes.
-
Fixed PHP layout hierarchy being executed in the incorrect order (inside-out instead of outside-in).
-
Direct
\WPEmerge\Requests\Request
references have been replaced with a new\WPEmerge\Requests\RequestInterface
interface. -
app_response()
is now\WPEmerge\response()
. -
app_output
is now\WPEmerge\output()
. -
app_json
is now\WPEmerge\json()
. -
app_redirect
is now\WPEmerge\redirect()
. -
app_view
is now\WPEmerge\view()
. -
app_error
is now\WPEmerge\error()
. -
app_partial
is now\WPEmerge\render()
. -
app_layout_content
is now\WPEmerge\layout_content()
. -
->add()
is now->middleware()
-
Routes are no longer declared using
Router::
. See here for more information. -
Router::handleAll()
is nowRoute::all()
. -
The ability to specify a regular expresson inline for a URL condition parameter has been removed. Use the new separate URL condition parameter instead (docs).
-
The RouteCondition facade has been removed.
-
ServiceProviderInterface::boot()
is nowServiceProviderInterface::bootstrap()
. -
WPEmerge::boot()
is nowWPEmerge::bootstrap()
. -
Framework
facade is nowWPEmerge
. -
WPEMERGE_FRAMEWORK_KEY
constant is nowWPEMERGE_APPLICATION_KEY
. -
WPEmerge::facade()
is nowWPEmerge::alias()
. -
MiddlewareInterface has been removed and is no longer required for middleware.
-
Blade and Twig extensions will now proxy
.php
view rendering to the default view engine by default. -
An exception will no longer be thrown if
manifest.json
is missing.
Starter Theme (GitHub)
- Added a new
yarn release
command which builds and zips up your theme to be ready for distribution (docs). - Added suport for WordPress 5.2 features such as
wp_body_open
andlogin_headertext
. - Removed
app/framework.php
in favor of separateapp/routes/*.php
and/app/views.php
files. - Added a new
app/helpers/admin.php
file. - Updated WPCS to 2.0.
- Added a version number in composer.json for easy referencing.
- Automatically install and build all assets on install for easier setup process.
- Added
@hook
annotations to files that are loaded during a hook. - Added an
.htaccess
file which blocks direct access to “source” directories. - Implemented common browserslist for Babel and Autoprefixer.
- Added development port option to
config.json
(props @mickaelperrin). - Simplified editor.scss by utilizing SASS map loops.
- Added missing
ABSPATH
check to certain files. - Updated Blade templates for consistency.
- Updated all WP Emerge usage to match latest release.
What’s Next
While nothing is set in store, here what WP Emerge is aiming at next, in no particular order:
Plugin Support
While having all that functionality in a theme has its benefits it is not “the WordPress way”. Plugin support will enable users to include WP Emerge into their plugins in a pain-free way.
Starter Plugin
A starter plugin would be a great addition to Plugin Support to enable developers to hit the ground running.
Progressive CSS
There is nothing stopping users from implementing their own solution to this but I believe this is an interesting opportunity for WP Emerge to step in and provide some boilerplate-free tooling.
Theme Styles
The starter theme comes with zero theme styles so users don’t have to delete or override styling to implement their design. Having an optional theme styles package on the other hand should help developers get acquainted with the WP Emerge workflow.
Long Term: Migrations
If you’ve used Laravel or Symfony you probably miss the database migration tools that they provide (e.g. update, rollback and seed). Doing the same in WordPress is by no means straightforward which is why I’m thinking about creating a WordPress-specific migrations library which can tightly integrate with WP Emerge.
Excited about WP Emerge’s new features? Let me know by posting a comment and joining me in the WP Emerge Gitter Lobby for a chat!