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:
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
):
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
):
<div class="container">
<h1>{{ $title }}</h1>
<div class="content">
{!! $content !!}
</div>
</div>
To render a view from your controller:
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
):
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
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
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
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:
// 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
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
},
],
],
];