|
| 1 | +# {Theme} Theme for Botble CMS |
| 2 | + |
| 3 | +Welcome to your new Botble CMS theme! This guide will help you get started with theme development. |
| 4 | + |
| 5 | +## 🚀 Quick Start |
| 6 | + |
| 7 | +### 1. Theme Structure |
| 8 | + |
| 9 | +``` |
| 10 | +{theme}/ |
| 11 | +├── assets/ # CSS, JS, and image files |
| 12 | +│ ├── css/ |
| 13 | +│ │ └── style.css # Main stylesheet |
| 14 | +│ ├── js/ |
| 15 | +│ │ └── script.js # Main JavaScript file |
| 16 | +│ └── sass/ # Optional: Sass files |
| 17 | +├── functions/ # Theme functions and configurations |
| 18 | +│ ├── functions.php # Theme setup and helpers |
| 19 | +│ ├── theme-options.php # Admin customization options |
| 20 | +│ └── shortcodes.php # Custom shortcodes |
| 21 | +├── lang/ # Translation files |
| 22 | +│ └── en/ |
| 23 | +│ └── theme.php |
| 24 | +├── layouts/ # Layout templates |
| 25 | +│ └── default.blade.php # Main layout |
| 26 | +├── partials/ # Reusable template parts |
| 27 | +│ ├── header.blade.php |
| 28 | +│ └── footer.blade.php |
| 29 | +├── public/ # Compiled assets (auto-generated) |
| 30 | +├── routes/ # Custom routes |
| 31 | +│ └── web.php |
| 32 | +├── src/ # PHP source code |
| 33 | +│ └── Http/ |
| 34 | +│ └── Controllers/ |
| 35 | +├── views/ # Page templates |
| 36 | +│ ├── index.blade.php # Homepage |
| 37 | +│ ├── page.blade.php # Static pages |
| 38 | +│ ├── 404.blade.php # 404 error page |
| 39 | +│ ├── 500.blade.php # 500 error page |
| 40 | +│ └── 503.blade.php # Maintenance page |
| 41 | +├── config.php # Theme configuration |
| 42 | +├── theme.json # Theme metadata |
| 43 | +├── webpack.mix.js # Asset compilation config |
| 44 | +└── README.md # This file |
| 45 | +``` |
| 46 | + |
| 47 | +### 2. Initial Setup |
| 48 | + |
| 49 | +1. **Install dependencies** (if not already done): |
| 50 | + ```bash |
| 51 | + npm install |
| 52 | + ``` |
| 53 | + |
| 54 | +2. **Compile assets for development**: |
| 55 | + ```bash |
| 56 | + npm run dev |
| 57 | + ``` |
| 58 | + |
| 59 | +3. **Watch for changes during development**: |
| 60 | + ```bash |
| 61 | + npm run watch |
| 62 | + ``` |
| 63 | + |
| 64 | +4. **Compile for production**: |
| 65 | + ```bash |
| 66 | + npm run prod |
| 67 | + ``` |
| 68 | + |
| 69 | +### 3. Configure Theme Options |
| 70 | + |
| 71 | +1. Go to **Admin Panel → Appearance → Theme options** |
| 72 | +2. Configure: |
| 73 | + - Site title and description |
| 74 | + - Logo and favicon |
| 75 | + - Social media links |
| 76 | + - Color scheme |
| 77 | + - Footer content |
| 78 | + - Custom CSS/JS |
| 79 | + |
| 80 | +## 📝 Development Guide |
| 81 | + |
| 82 | +### Creating Templates |
| 83 | + |
| 84 | +#### Homepage Template |
| 85 | +Edit `views/index.blade.php` to customize your homepage: |
| 86 | + |
| 87 | +```blade |
| 88 | +<div class="homepage"> |
| 89 | + <h1>{{ theme_option('homepage_title', 'Welcome') }}</h1> |
| 90 | + |
| 91 | + @if (is_plugin_active('blog')) |
| 92 | + {!! Theme::partial('recent-posts') !!} |
| 93 | + @endif |
| 94 | +</div> |
| 95 | +``` |
| 96 | + |
| 97 | +#### Page Templates |
| 98 | +Create custom page templates in `views/`: |
| 99 | + |
| 100 | +```blade |
| 101 | +{{-- views/page-full-width.blade.php --}} |
| 102 | +@extends('theme.{theme}::layouts.full-width') |
| 103 | + |
| 104 | +@section('content') |
| 105 | + <h1>{{ $page->name }}</h1> |
| 106 | + {!! BaseHelper::clean($page->content) !!} |
| 107 | +@endsection |
| 108 | +``` |
| 109 | + |
| 110 | +Register in `functions/functions.php`: |
| 111 | +```php |
| 112 | +register_page_template([ |
| 113 | + 'full-width' => __('Full Width Page'), |
| 114 | +]); |
| 115 | +``` |
| 116 | + |
| 117 | +### Working with Menus |
| 118 | + |
| 119 | +Display menus in your templates: |
| 120 | + |
| 121 | +```blade |
| 122 | +{!! Menu::renderMenuLocation('main-menu', [ |
| 123 | + 'options' => ['class' => 'navbar-nav'], |
| 124 | + 'view' => 'main-menu', |
| 125 | +]) !!} |
| 126 | +``` |
| 127 | + |
| 128 | +### Adding Theme Options |
| 129 | + |
| 130 | +Edit `functions/theme-options.php`: |
| 131 | + |
| 132 | +```php |
| 133 | +theme_option() |
| 134 | + ->setField([ |
| 135 | + 'id' => 'primary_color', |
| 136 | + 'section_id' => 'opt-text-subsection-general', |
| 137 | + 'type' => 'color', |
| 138 | + 'label' => __('Primary Color'), |
| 139 | + 'attributes' => [ |
| 140 | + 'name' => 'primary_color', |
| 141 | + 'value' => '#ff2b4a', |
| 142 | + ], |
| 143 | + ]); |
| 144 | +``` |
| 145 | + |
| 146 | +Access in templates: |
| 147 | +```blade |
| 148 | +<style> |
| 149 | + :root { |
| 150 | + --primary-color: {{ theme_option('primary_color', '#ff2b4a') }}; |
| 151 | + } |
| 152 | +</style> |
| 153 | +``` |
| 154 | + |
| 155 | +### Creating Shortcodes |
| 156 | + |
| 157 | +Add to `functions/shortcodes.php`: |
| 158 | + |
| 159 | +```php |
| 160 | +add_shortcode('button', __('Button'), __('Display a button'), function ($shortcode) { |
| 161 | + return Theme::partial('shortcodes.button', [ |
| 162 | + 'text' => $shortcode->text, |
| 163 | + 'url' => $shortcode->url, |
| 164 | + 'type' => $shortcode->type ?: 'primary', |
| 165 | + ]); |
| 166 | +}); |
| 167 | + |
| 168 | +// Usage in content: [button text="Click me" url="/contact" type="primary"] |
| 169 | +``` |
| 170 | + |
| 171 | +### Working with Widgets |
| 172 | + |
| 173 | +If the widget plugin is active: |
| 174 | + |
| 175 | +```php |
| 176 | +// Register widget area in functions/functions.php |
| 177 | +register_sidebar([ |
| 178 | + 'id' => 'footer_sidebar', |
| 179 | + 'name' => __('Footer sidebar'), |
| 180 | +]); |
| 181 | + |
| 182 | +// Display in template |
| 183 | +{!! dynamic_sidebar('footer_sidebar') !!} |
| 184 | +``` |
| 185 | + |
| 186 | +### Using Assets |
| 187 | + |
| 188 | +```php |
| 189 | +// In functions/functions.php |
| 190 | +Theme::asset() |
| 191 | + ->add('theme-style', 'css/style.css') |
| 192 | + ->add('theme-script', 'js/script.js', ['jquery']) |
| 193 | + ->add('bootstrap', '//cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css'); |
| 194 | +``` |
| 195 | + |
| 196 | +### Translations |
| 197 | + |
| 198 | +Add translations in `lang/en/theme.php`: |
| 199 | + |
| 200 | +```php |
| 201 | +return [ |
| 202 | + 'welcome' => 'Welcome to our website', |
| 203 | + 'read_more' => 'Read more', |
| 204 | + 'contact_us' => 'Contact us', |
| 205 | +]; |
| 206 | +``` |
| 207 | + |
| 208 | +Use in templates: |
| 209 | +```blade |
| 210 | +<h1>{{ __('theme.{theme}::theme.welcome') }}</h1> |
| 211 | +``` |
| 212 | + |
| 213 | +## 🎨 Styling Guide |
| 214 | + |
| 215 | +### CSS Variables |
| 216 | + |
| 217 | +Your theme uses CSS custom properties for easy customization: |
| 218 | + |
| 219 | +```css |
| 220 | +:root { |
| 221 | + --primary-color: #ff2b4a; |
| 222 | + --secondary-color: #6c757d; |
| 223 | + --text-color: #333333; |
| 224 | + --bg-color: #ffffff; |
| 225 | + --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto; |
| 226 | +} |
| 227 | +``` |
| 228 | + |
| 229 | +### Responsive Design |
| 230 | + |
| 231 | +Use Bootstrap's grid system or CSS Grid: |
| 232 | + |
| 233 | +```blade |
| 234 | +<div class="container"> |
| 235 | + <div class="row"> |
| 236 | + <div class="col-md-8">Main content</div> |
| 237 | + <div class="col-md-4">Sidebar</div> |
| 238 | + </div> |
| 239 | +</div> |
| 240 | +``` |
| 241 | + |
| 242 | +### Dark Mode Support |
| 243 | + |
| 244 | +```css |
| 245 | +@media (prefers-color-scheme: dark) { |
| 246 | + :root { |
| 247 | + --text-color: #e9ecef; |
| 248 | + --bg-color: #212529; |
| 249 | + } |
| 250 | +} |
| 251 | +``` |
| 252 | + |
| 253 | +## 🔌 Plugin Integration |
| 254 | + |
| 255 | +### Blog Plugin |
| 256 | + |
| 257 | +```blade |
| 258 | +@if (is_plugin_active('blog')) |
| 259 | + @php |
| 260 | + $posts = get_recent_posts(5); |
| 261 | + @endphp |
| 262 | + |
| 263 | + @foreach($posts as $post) |
| 264 | + <article> |
| 265 | + <h2><a href="{{ $post->url }}">{{ $post->name }}</a></h2> |
| 266 | + <p>{{ $post->description }}</p> |
| 267 | + </article> |
| 268 | + @endforeach |
| 269 | +@endif |
| 270 | +``` |
| 271 | + |
| 272 | +### Gallery Plugin |
| 273 | + |
| 274 | +```blade |
| 275 | +@if (is_plugin_active('gallery')) |
| 276 | + {!! render_galleries(8) !!} |
| 277 | +@endif |
| 278 | +``` |
| 279 | + |
| 280 | +### Contact Form |
| 281 | + |
| 282 | +```blade |
| 283 | +@if (is_plugin_active('contact')) |
| 284 | + {!! Theme::partial('contact-form') !!} |
| 285 | +@endif |
| 286 | +``` |
| 287 | + |
| 288 | +## 🛠️ Advanced Features |
| 289 | + |
| 290 | +### AJAX Loading |
| 291 | + |
| 292 | +```javascript |
| 293 | +// In assets/js/script.js |
| 294 | +$(document).on('click', '.load-more', function(e) { |
| 295 | + e.preventDefault(); |
| 296 | + $.ajax({ |
| 297 | + url: $(this).attr('href'), |
| 298 | + success: function(data) { |
| 299 | + $('.posts-container').append(data.html); |
| 300 | + } |
| 301 | + }); |
| 302 | +}); |
| 303 | +``` |
| 304 | + |
| 305 | +### Custom Routes |
| 306 | + |
| 307 | +In `routes/web.php`: |
| 308 | + |
| 309 | +```php |
| 310 | +Route::get('custom-page', 'CustomController@index') |
| 311 | + ->name('theme.custom-page'); |
| 312 | +``` |
| 313 | + |
| 314 | +### SEO Optimization |
| 315 | + |
| 316 | +```blade |
| 317 | +{!! SeoHelper::render() !!} |
| 318 | + |
| 319 | +{{-- Or manually --}} |
| 320 | +<meta name="description" content="{{ $page->description }}"> |
| 321 | +<meta property="og:title" content="{{ $page->name }}"> |
| 322 | +<meta property="og:image" content="{{ RvMedia::getImageUrl($page->image) }}"> |
| 323 | +``` |
| 324 | + |
| 325 | +## 📚 Useful Functions |
| 326 | + |
| 327 | +### Theme Helpers |
| 328 | + |
| 329 | +- `theme_option('key', 'default')` - Get theme option |
| 330 | +- `Theme::asset()` - Manage assets |
| 331 | +- `Theme::partial('name', $data)` - Include partial |
| 332 | +- `Theme::breadcrumb()` - Show breadcrumbs |
| 333 | +- `Theme::content()` - Render main content |
| 334 | +- `Theme::layout('name')` - Set layout |
| 335 | + |
| 336 | +### CMS Helpers |
| 337 | + |
| 338 | +- `is_plugin_active('plugin-name')` - Check if plugin is active |
| 339 | +- `get_recent_posts($limit)` - Get recent blog posts |
| 340 | +- `get_all_pages()` - Get all pages |
| 341 | +- `Menu::renderMenuLocation('location')` - Render menu |
| 342 | +- `RvMedia::getImageUrl($path)` - Get media URL |
| 343 | +- `BaseHelper::clean($content)` - Clean HTML content |
| 344 | + |
| 345 | +## 🐛 Troubleshooting |
| 346 | + |
| 347 | +### Assets not updating? |
| 348 | +```bash |
| 349 | +npm run dev |
| 350 | +php artisan cache:clear |
| 351 | +``` |
| 352 | + |
| 353 | +### Theme not appearing in admin? |
| 354 | +Check `theme.json` has correct structure and theme is in `platform/themes/` directory. |
| 355 | + |
| 356 | +### Styles not loading? |
| 357 | +Ensure `webpack.mix.js` is configured correctly and run `npm run prod`. |
| 358 | + |
| 359 | +## 📖 Resources |
| 360 | + |
| 361 | +- [Theme Development Guide](https://docs.botble.com/cms/theme-development/theme.html) |
| 362 | +- [Blade Templates](https://laravel.com/docs/blade) |
| 363 | +- [Bootstrap Documentation](https://getbootstrap.com/docs/) |
| 364 | +- [Tabler UI Components](https://docs.tabler.io/ui) |
| 365 | +- [Laravel Mix](https://laravel-mix.com/docs/) |
| 366 | + |
| 367 | +## 🤝 Support |
| 368 | + |
| 369 | +- Documentation: https://docs.botble.com |
| 370 | +- Community: https://github.com/botble/botble/discussions |
| 371 | +- Issues: https://github.com/botble/botble/issues |
| 372 | + |
| 373 | +--- |
| 374 | + |
| 375 | +Happy theming! 🎨 |
0 commit comments