WP Emerge Logo

Packagist Travis branch Scrutinizer Scrutinizer Coverage Gitter

📦 A micro framework which modernizes WordPress as a CMS development by providing tools to implement MVC and more.

🔥 Integration is incremental - you can use it only on the pages you want or on all pages.

❤ If you've used frameworks such as Laravel, Slim or Symfony you will love WP Emerge.

🚀 Also, make sure you check out the WP Emerge Starter Theme project.


  • PHP >= 5.5
  • WordPress >= 4.7
  • Composer

Features & Documentation



API Reference


Development Team

Brought to you by Atanas Angelov and the lovely folks at htmlBurger.

Comparison Table ¹ ²

WPEmerge Sage Timber
View Engine PHP, Blade, Twig, Custom PHP, Blade Twig
MVC ✖✔✔ ✖✔✖³ ✖✔✖
View Composers ✔/✖⁴
Service Container

¹ We are comparing frameworks and themes - style, build tools etc. are not mentioned. For a full comparison check out the WP Emerge Starter Theme.

² WP Emerge is theme agnostic - you can use it in any theme.

³ Sage's Controller is more of a View Composer than a Controller.

⁴ Sage's Controller provides similar functionality but is limited to 1 composer (controller) per view and vice versa.

Email any factual inaccuracies to atanas.angelov.dev@gmail.com so they can be corrected.


Routes with optional rewrite rule integration

  • Enables the use of controllers to compartmentalize your business logic away from your presentation.
  • Use existing routes or add new ones with a rewrite.
  • Use built-in dynamic route conditions or define your own custom ones.
  • Use anonymous functions for quick one-off conditions.
Router::get( '/', 'HomeController@index' );

Router::get( '/custom', 'CustomController@custom' )
    ->rewrite( 'index.php?...' );

Router::get( ['post_id', get_option('page_on_front')], 'HomeController@index' );

Router::get( function() {
    return is_front_page();
}, 'HomeController@index' );


  • Separate unrelated business logic into controllers, and related business logic into controller methods.
  • Receive an object representing the current request and respond with a PSR-7 response.
  • Use different methods for different routes.
  • Respond with a view, json, a redirect etc.
  • Easy to test.
class HomeController {
    public function index( $request ) {
        $name = $request->get( 'name' );
        return app_view( 'templates/home.php' )
            ->with( [
                'welcome' => 'Welcome, ' . $name . '!',
            ] );


  • Hook before and/or after route handlers (e.g. controller methods).
  • Add globally or to specific routes or route groups.
  • Powers features such as Flash and OldInput.
Router::get( '/', 'HomeController@index' )
    ->add( function( $request, $next ) {
        // perform action before
        $response = $next( $request );
        // perform action after
        return $response;
    } );

PSR-7 Responses

  • Use PSR-7 objects for your responses.
  • Easy to stream and modify before outputting.
  • Uses Guzzle's implementation - read more.
class HomeController {
    public function index( $request ) {
        return app_response()
            ->withHeader( 'X-Custom-Header', 'foo' );

View Composers

  • Pass generic context to partials regardless of which controller or parent view uses them.
  • Work with any View engine (Php, Blade, Twig).
View::addComposer( 'templates/about-us', function( $view ) {
    $view->with( ['hello' => 'world'] );
} );

Service container

  • Define your dependencies in a service container.
  • Override any and all WP Emerge dependencies when needed.
  • Enables dependency injection.
  • Uses Pimple - read more.
// getContainer() used for brevity's sake - use a Service Provider instead.
$container = WPEmerge::getContainer();
$container['my_service'] = function( $container ) {
    return new MyService( $container['my_dependency'] );

Service providers

  • Register dependencies into the service container and boot them, if needed.
  • Enables to split your dependencies logically into separate providers.
  • WP Emerge's own dependencies are provided via Service providers.
class MyServiceProvider implements ServiceProviderInterface {
    public function register( $container ) {
        $container['my_service'] = function( $container ) {
            return new MyService( $container['my_dependency'] );

    public function boot( $container ) {
        // bootstrap code if needed

Custom view engine support

  • Replace the view engine used in the service container.
  • Blade and Twig available as add-on packages.
  • You can even write your own view engine and use it seamlessly.
// getContainer() used for brevity's sake - use a Service Provider instead.
$container = WPEmerge::getContainer();
$container[ WPEMERGE_VIEW_ENGINE_KEY ] = function( $container ) {
    return new MyViewEngine();


WP Emerge is completely open source and we encourage everybody to participate by:

results matching ""

    No results matching ""