Devflow is not a plug-and-play content management system (cms). Devflow was created to give PHP architects a tool to build bespoke websites, applications, and websites that may have complex domain business logic. It is a headless content management framework (CMF). You have the option to build out a frontend, create themes, or consume the REST api. Don't like REST, well it is a framework, and you are free to implement graphql.

It is not a perfect tool, and it may not be to everyone's liking, and that's ok. It has taken a few years to get the system to this point; it is still an infant and definitely needs improvement.

It does include helpful tools, but does not include everything and the kitchen sink. It is more of a repository for your data. For example, you can add products, but it is not include a full-featured e-commerce solution. This is something you will need to build out.

Devflow is built on top of the CodefyPHP Framework, which is a DDD framework with CQRS, and event sourcing. If you are not familiar with domain-driven development (DDD), I suggest you make yourself familiar with Aggregates and Service Bus

Custom Development

If you are wanting to build a frontend or add custom functionality, you can add your custom Controllers and Routes to the Cms namespace and your custom views to Cms/views/.

So, lets say that you want to build a frontend for example.com. This is what you will need:

  • A frontend controller or controllers depending on how you segment your code
  • A route to serve your different requests
  • And a view (presentation layer)

Controller

Our custom controller will go into Cms/Application/Http/Controller, and will be named MyFrontendController.php (Application\Http\Controller\MyFrontendController):

<?php

declare(strict_types=1);

namespace Application\Http\Controller;

use Psr\Http\Message\ResponseInterface;

use function Codefy\Framework\Helpers\view;

final class MyFrontendController
{
    public function index(): ResponseInterface
    {
        return view(
            template: 'cmf::frontend/index',
            data: [
                'title' => 'Site Frontend',
                'body'  => '<h3>This is my frontend page.</h3>'
            ]
        );
    }
}

Route

Next, we need to add our route. We will create a new route class in Cms/Applicaton/Http/Route called MyFrontendRoute:

<?php

declare(strict_types=1);

namespace Application\Http\Route;

use Application\Http\Controller\MyFrontendController;
use Qubus\Routing\Psr7Router;

final class MyFrontendRoute
{
    public function handle(Psr7Router $router): void
    {
        $router->get('/', function(MyFrontendController $controller) {
            return $controller->index();
        });
    }
}

The handle method has a Router dependency which is taken care of by the system's Dependency Injector. Our route is frontend which converts to example.com/, and we use our controller as the callback.

To learn more about controllers, check out Creating Controllers and Creating Service Providers.

View

We need to create two views, one for the layout and one for frontend which will go into the Cms/views/frontend/ folder:

layout.phtml

<!DOCTYPE html>
<html lang="en">
<head>
    <base href="<?=site_url();?>">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title><?=$this->esc($title ?? '');?></title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=6, user-scalable=yes" name="viewport">
</head>

    <body>

    <?php $this->block('frontend'); ?>

    </body>
</html>

index.phtml

<?php

declare(strict_types=1);

$this->parent('cmf::frontend/layout');
$this->block('frontend', function ($params) {

    echo 'Page Title: ' . $params['title'];

    echo 'Page Content: ' . $params['body'];
});

To learn more about views and namespacing views, check out Creating Views

Putting it together

Now that we have our controller, route and views, it is time to put it together to make it work.

First, open config/routes.php to add your route. It should look similar to this:

<?php

use Application\Http\Route\MyFrontendRoute;

return [
    'example.com' => MyFrontendRoute::class,
];

The key for your route is the hostname. Why, you ask? Well, Devflow supports multisite. Therefore, when the site is loaded, the correct route will be loaded based on the hostname.

And that is it. The system will automatically load the controller and execute the handle method, our views are in place, and the route has been set in config/routes.php. All that's left now is to visit http://example.com/ and you should see the title and the content.