Skip to content

Need it customized?

Custom features, theme changes, server setup, migrations and upgrades - built by the Botble team. Quick fixes from $99, fixed quote within 1 business day.

Get a free quote →

Theme MVC Pattern ​

Botble CMS themes follow the MVC (Model-View-Controller) pattern, allowing you to create custom functionality within your theme while maintaining a clean separation of concerns.

Theme Structure ​

When developing a theme, you can start by using the default theme called Ripple or create a new theme using the theme generator command:

bash
php artisan cms:theme:create <your-theme-name>

This will create a new theme with the following structure:

platform/themes/<your-theme-name>/
├── assets/                 # Theme assets (CSS, JS, images)
├── functions/              # Theme functions
│   ├── functions.php       # Main functions file
│   ├── shortcodes.php      # Theme shortcodes
│   └── theme-options.php   # Theme options
├── layouts/                # Theme layouts
│   └── default.blade.php   # Default layout
├── partials/               # Theme partials
├── routes/                 # Theme routes
│   └── web.php             # Web routes
├── src/                    # Theme PHP classes
│   ├── Http/
│   │   └── Controllers/    # Theme controllers
│   └── Models/             # Theme models
├── views/                  # Theme views
├── composer.json           # Composer configuration
├── config.php             # Theme configuration
└── theme.json             # Theme metadata

Theme Namespace ​

Each theme has its own namespace defined in the composer.json file. For example, if your theme is named "Ripple", the namespace will be Theme\Ripple\. This namespace is used for all PHP classes within your theme.

Models ​

You can create custom models in the platform/themes/<your-theme>/src/Models directory. These models follow standard Laravel Eloquent patterns.

Example model (platform/themes/<your-theme>/src/Models/CustomPost.php):

php
namespace Theme\YourTheme\Models;

use Illuminate\Database\Eloquent\Model;

class CustomPost extends Model
{
    protected $table = 'posts';

    protected $fillable = [
        'name',
        'content',
        'status',
    ];
}

Views ​

Theme views are located in the platform/themes/<your-theme>/views directory. These views use Laravel's Blade templating engine.

Example view (platform/themes/<your-theme>/views/custom-page.blade.php):

blade
<div class="container">
    <h1>{{ $title }}</h1>
    <div class="content">
        {!! $content !!}
    </div>
</div>

To render a view from your controller:

php
return Theme::scope('custom-page', ['title' => 'My Page', 'content' => 'Page content']);

Controllers ​

Theme controllers are located in the platform/themes/<your-theme>/src/Http/Controllers directory. These controllers should extend the Botble\Theme\Http\Controllers\PublicController class.

Example controller (platform/themes/<your-theme>/src/Http/Controllers/YourThemeController.php):

php
namespace Theme\YourTheme\Http\Controllers;

use Botble\Theme\Facades\Theme;
use Botble\Theme\Http\Controllers\PublicController;
use Illuminate\Http\Request;

class YourThemeController extends PublicController
{
    public function getCustomPage(Request $request)
    {
        $title = 'Custom Page';
        $content = 'This is a custom page.';

        return Theme::scope('custom-page', compact('title', 'content'));
    }

    public function getAjaxData(Request $request)
    {
        // Process AJAX request
        $data = ['success' => true, 'message' => 'Data loaded successfully'];

        return $this->httpResponse()->setData($data);
    }
}

Routes ​

Theme routes are defined in the platform/themes/<your-theme>/routes/web.php file. These routes are automatically loaded when the theme is active.

Example routes file (platform/themes/<your-theme>/routes/web.php):

php
<?php

use Botble\Base\Http\Middleware\RequiresJsonRequestMiddleware;
use Botble\Theme\Facades\Theme;
use Illuminate\Support\Facades\Route;
use Theme\YourTheme\Http\Controllers\YourThemeController;

Theme::registerRoutes(function (): void {
    Route::group(['controller' => YourThemeController::class], function (): void {
        // Regular routes
        Route::get('custom-page', 'getCustomPage')->name('public.custom-page');

        // AJAX routes
        Route::middleware(RequiresJsonRequestMiddleware::class)
            ->group(function (): void {
                Route::get('ajax/data', 'getAjaxData')->name('public.ajax.data');
            });
    });
});

// This loads the default theme routes
Theme::routes();

Using Theme Functions ​

Theme functions are defined in the platform/themes/<your-theme>/functions directory. These functions can be used to customize your theme's behavior.

Theme Options ​

Theme options are defined in functions/theme-options.php:

php
<?php

use Botble\Theme\Events\RenderingThemeOptionSettings;

app('events')->listen(RenderingThemeOptionSettings::class, function (): void {
    theme_option()
        ->setField([
            'id' => 'custom_setting',
            'section_id' => 'opt-text-subsection-general',
            'type' => 'text',
            'label' => __('Custom Setting'),
            'attributes' => [
                'name' => 'custom_setting',
                'value' => null,
                'options' => [
                    'class' => 'form-control',
                    'placeholder' => __('Enter custom setting'),
                ],
            ],
        ]);
});

Shortcodes ​

Theme shortcodes are defined in functions/shortcodes.php:

php
<?php

use Botble\Shortcode\Compilers\ShortcodeCompiler;
use Botble\Theme\Facades\Theme;

shortcode()->register('custom-shortcode', __('Custom Shortcode'), __('Custom Shortcode Description'), function (ShortcodeCompiler $shortcode) {
    return Theme::partial('shortcodes.custom-shortcode', ['title' => $shortcode->title]);
});

Accessing Theme Assets ​

You can access theme assets using the Theme::asset() helper:

php
// Get URL to a theme asset
Theme::asset()->url('css/style.css');

// Add a CSS file to the theme
Theme::asset()->usePath()->add('custom-style', 'css/custom-style.css');

// Add a JS file to the footer
Theme::asset()->container('footer')->usePath()->add('custom-script', 'js/custom-script.js');

Theme Configuration ​

Theme configuration is defined in the config.php file. This file allows you to define event listeners for various theme events:

php
<?php

use Botble\Theme\Theme;

return [
    'events' => [
        // Before rendering the theme
        'beforeRenderTheme' => function (Theme $theme): void {
            // Add theme assets
            $theme->asset()->usePath()->add('main-css', 'css/main.css');
            $theme->asset()->container('footer')->usePath()->add('main-js', 'js/main.js');
        },

        // Before rendering a specific layout
        'beforeRenderLayout' => [
            'default' => function (Theme $theme): void {
                // Add layout-specific assets
            },
        ],
    ],
];