Theme
Namespace: App\Infrastructure\Services\Theme
Method | Description | Type | Parameters | Return |
---|---|---|---|---|
__construct | throws ContainerExceptionInterface throws ReflectionException throws NotFoundExceptionInterface|Exception |
public | ||
id | Theme's id | protected | ||
name | Theme's name | protected | ||
path | The theme's directory path |
protected | string | |
route | Theme's route for submenu | protected | ||
url | Theme's url | protected |
If you are not interested in using Devflow as a headless CMS, you have the option of creating a theme. When creating a theme, you can extend the abstract class Theme
and implement the two abstract methods meta
and handle
. The meta
method returns an array of info about your theme, and
the handle
method is called by the system to load assets, views, etc. The following 4 steps will walk you through creating your first theme.
Using Coding Standards
Devflow uses specific coding standards to help maintain consistency, quality, and clean code. The coding standard that Devflow uses and promotes is PSR-12 along with the Qubus Coding Standards.
Namespaces
Classes as well as function should be namespaced, unless there is a strong reason to not namespace a function. Namespacing functions is recommended and highly encouraged in order to keep the
global
namespace clean and available for native PHP functions.
Security
You must always validate and sanitize data on output. Never trust user data that was inputted. If you use the native Devflow
functions that output data, that data is already sanitized or purified.
Keep these things in mind when outputting data outside the native functions:
- Sanitize data on output by using helpers
Qubus\Security\Helpers\esc_html
,Qubus\Security\Helpers\esc_html__
,Qubus\Security\Helpers\esc_url
,Qubus\Security\Helpers\esc_js
, andQubus\Security\Helpers\purify_html
. - Check user permission before executing or saving data to prevent unauthorized operations or access.
- Use the Devflow database helper (
App\Shared\Helpers\dfdb
) and prepared statements to avoid SQL injection vulnerabilities.
Step #1: Create Your Theme File
The first step is to create a folder for your theme in the public/themes
directory. Your directory must meet PSR-4 autoload standards. For this example, we are going to create a My Site theme.
The name of the new folder will be NewsWidget
and the name of the main class will be the same followed by the suffix Theme.php
: MySiteTheme.php.
MySiteTheme.php
will extend the abstract class App\Infrastructure\Services\Theme
. We should now have a new class:
<?php
declare(strict_types=1);
namespace Theme\MySite;
use App\Infrastructure\Services\Theme;
class MySiteTheme extends Theme
{
/**
* @inheritDoc
*/
public function meta(): array
{
// TODO: Implement meta() method.
}
/**
* @inheritDoc
*/
public function handle(): void
{
// TODO: Implement handle() method.
}
}
We need to fill out the meta method to include our theme's info:
name
- The name of the theme.id
- Theme's unique identifier. This is also used for your route if you need to register a submenu.author
- Person or company who authored the theme.version
- Current version of the theme.description
- A short description of the theme's purpose.basename
- Filename of the theme.path
- File path of the theme.url
- Theme's directory url.themeUri
- Where the theme is hosted and updates found.authorUri
- Website of the theme author.className
- Name of the class.screenshot
- Preview image of the theme.
With the meta details filled out, this is now the state of our theme class:
<?php
declare(strict_types=1);
namespace Theme\MySite;
use App\Infrastructure\Services\Theme;
use App\Shared\Services\Registry;
use function App\Shared\Helpers\theme_root;
use function App\Shared\Helpers\theme_url;
use function basename;
use function dirname;
use function get_class;
use function Qubus\Security\Helpers\t__;
class MySiteTheme extends Theme
{
/**
* @inheritDoc
*/
public function meta(): array
{
$theme = [
'name' => t__(msgid: 'My Site Theme', domain: 'mysite'),
'id' => 'mysite',
'author' => 'Joshua Parker',
'version' => '1.0.0',
'description' => 'My Site theme.',
'basename' => basename(dirname(__FILE__)),
'path' => theme_root(__FILE__),
'url' => theme_url('', __CLASS__),
'themeUri' => 'https://github.com/getdevflow/mysite-theme',
'authorUri' => 'https://nomadicjosh.com/',
'className' => get_class($this),
'screenshot' => theme_url('MySite/screenshot.png'),
];
Registry::getInstance()->set('mysite', $theme;
return $theme;
}
/**
* @inheritDoc
*/
public function handle(): void
{
// TODO: Implement handle() method.
}
}
Now that the meta
method is implemented, our theme should now be registered on our themes page.
Step #2: Create Other Methods (if needed)
You can create other methods as needed such as rendor
for views. To get an idea, check out the Plugin guide
Step #3: The Loop
For you main view, you can use the loop to load all content or content by content type:
if(has_content()):
while(the_content()) :
//
// Content here
//
endwhile;
endif;
content_*
or product_*
.
Step #4: Share Your Theme
If we wanted to share your theme to allow others in the community to install it via composer
, we would add a composer.json
file to the root of our theme's directory:
{
"name": "getdevflow/mysite",
"description": "My Site theme.",
"type": "devflow-thee",
"keywords": ["devflow-theme","themes"],
"license": "GPL-2.0-only",
"authors": [
{
"name": "Joshua Parker",
"email": "joshua@joshuaparker.dev"
}
],
"require": {
"php": ">=8.3",
"oomphinc/composer-installers-extender": "^2.0"
},
"extra": {
"installer-name": "MySite",
"installer-types": ["devflow-theme"]
},
"minimum-stability": "stable",
"prefer-stable": true,
"config": {
"allow-plugins": {
"composer/installers": true,
"oomphinc/composer-installers-extender": true
}
}
}
There are several important key points to point out in the json data above:
- Make sure to change the vendor name
- Make sure to add the type
devflow-theme
- Make sure to include
installer-name
and make it PSR-4 compatible. It will install the theme asMySite
instead of asmysite
. - Make sure the
installer-types
includesdevflow-theme
When someone runs composer require getdevflow/mysite
, the theme will be installed with the correct folder name public/themes/MySite/
.
There you go. These are the steps you can take to create a theme as well as how to share your new theme with the Devflow
community.
Any theme added to Packagist with the above composer.json
information, will appear on the Devflow extensions page of the main website.
Child Themes
If you need or want to customize a theme, you can create a child theme. If we were to create a child theme of the sample theme made previously,
we would create another directory named MySiteChild
, and the main class will be named MySiteChildTheme
, which will extend the class
of the main theme:
<?php
declare(strict_types=1);
namespace Theme\MySiteChild;
use Theme\MySite\MySiteTheme;
final class MySiteChildTheme extends MySiteTheme {
}