Custom Blocks - Streats22/LaraGrapePackage GitHub Wiki
The LaraGrape package includes a robust dynamic block loading system that automatically scans and loads blocks from the resources/views/filament/blocks/
directory structure with comprehensive error handling and fallbacks.
composer require streats22/laragrape
php artisan laragrape:setup --all
Blocks are organized by category in subdirectories for easy management:
resources/views/filament/blocks/
├── components/ # UI components (buttons, cards, alerts)
├── content/ # Content blocks (text, headings, lists)
├── forms/ # Form blocks (contact forms, newsletters)
├── layouts/ # Layout blocks (hero, sections, columns)
└── media/ # Media blocks (images, videos, galleries)
Decide which category your block belongs to and create a .blade.php
file in the appropriate directory.
Each block file must start with a metadata comment for automatic discovery:
{{-- @block id="my-block" label="My Block" description="A description of my block" --}}
<div class="my-block">
<!-- Your HTML content here -->
</div>
Option | Required | Description |
---|---|---|
id |
✅ | Unique identifier for the block |
label |
✅ | Display name in the GrapesJS block manager |
description |
❌ | Description shown in the block manager |
attributes |
❌ | JSON object of GrapesJS attributes |
{{-- @block id="feature-card" label="Feature Card" description="A card showcasing a feature with icon, title, and description" --}}
<div class="feature-card bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">
<div class="text-center">
<div class="w-16 h-16 bg-blue-500 rounded-full mx-auto mb-4 flex items-center justify-center">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
</div>
<h3 class="text-xl font-bold mb-2" data-gjs-type="text" data-gjs-name="title">Feature Title</h3>
<p class="text-gray-600" data-gjs-type="text" data-gjs-name="description">Feature description goes here</p>
</div>
</div>
- ✅ Automatic Discovery: Blocks are automatically loaded from the file system
- ✅ Category Organization: Blocks appear organized by category in the block manager
- ✅ Live Preview: Block previews are generated automatically
- ✅ Error Handling: Graceful fallbacks if blocks fail to load
Use data-gjs-type="text"
and data-gjs-name="unique-name"
attributes to make elements editable in GrapesJS:
<h1 data-gjs-type="text" data-gjs-name="heading">Editable Heading</h1>
<p data-gjs-type="text" data-gjs-name="content">Editable content</p>
<button data-gjs-type="text" data-gjs-name="button-text">Editable Button</button>
All blocks use Tailwind CSS classes for responsive design:
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Responsive grid layout -->
</div>
- alert.blade.php: Alert/notification component
- button.blade.php: Button component with variants
- card.blade.php: Card component with image, title, description
- pricing.blade.php: Pricing table component
- testimonial.blade.php: Customer testimonial component
- divider.blade.php: Horizontal divider/separator
- heading.blade.php: Heading with decorative underline
- list.blade.php: Ordered and unordered lists
- quote.blade.php: Blockquote component
- spacer.blade.php: Vertical spacing component
- text.blade.php: Simple text content block
- contact-form.blade.php: Contact form with name, email, message
- columns.blade.php: Two-column layout
- container.blade.php: Content container wrapper
- grid.blade.php: CSS Grid layout
- hero.blade.php: Hero section with title, subtitle, CTA
- section.blade.php: General content section
- gallery.blade.php: Image gallery component
- image.blade.php: Image block with placeholder
- video.blade.php: Video embed component
To add a new category:
- Create a new directory in
resources/views/filament/blocks/
- Add
.blade.php
files with proper metadata - The system will automatically detect and load them
Example:
mkdir resources/views/filament/blocks/widgets
touch resources/views/filament/blocks/widgets/weather.blade.php
The block system automatically reloads when:
- ✅ New block files are added
- ✅ Existing block files are modified
- ✅ The application is restarted
- ✅ Cache is cleared (
php artisan cache:clear
)
- Use Tailwind CSS classes for styling
- Blocks inherit global styles from your app's page template
- Responsive design with mobile-first approach
Add custom CSS to individual blocks if needed:
<style>
.custom-block {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 12px;
transition: transform 0.3s ease;
}
.custom-block:hover {
transform: translateY(-2px);
}
</style>
Blocks automatically inherit dynamic theme settings from TailwindConfig:
<div class="bg-primary-500 text-primary-50">
<!-- Uses dynamic primary colors -->
</div>
- All blocks are mobile-first and responsive
- Use Tailwind's responsive prefixes (
md:
,lg:
, etc.) - Test blocks on different screen sizes
- Ensure buttons and interactive elements are large enough for touch
- Use appropriate spacing for mobile devices
- Consider touch targets (minimum 44px)
-
Check file extension: Must be
.blade.php
-
Verify metadata: Ensure
@block
comment is properly formatted - Check directory: Ensure file is in correct category directory
-
Clear cache:
php artisan cache:clear
- Check BlockService: Use Tinker to test service
php artisan tinker
>>> use App\Services\BlockService;
>>> $service = new BlockService();
>>> dd($service->getBlocks());
- Check HTML syntax: Validate HTML structure
- Verify Tailwind classes: Ensure classes are valid
- Test in isolation: Test block outside of GrapesJS
- Check for JavaScript errors: Look in browser console
- Cache blocks: Blocks are cached for performance
- Optimize images: Use appropriate image sizes
- Limit complexity: Avoid overly complex blocks
- Lazy loading: Consider lazy loading for heavy blocks
-
Check route: Ensure
/admin/block-preview/{blockId}
route exists - Verify controller: Check AdminPageController exists
-
Clear route cache:
php artisan route:clear
- Check block IDs: Ensure frontend uses correct block IDs
Add custom GrapesJS attributes to blocks:
{{-- @block id="my-block" label="My Block" attributes='{"draggable": true, "droppable": false}' --}}
Create reusable block templates:
{{-- @block id="template-card" label="Template Card" description="Reusable card template" --}}
<div class="template-card" data-gjs-draggable="true" data-gjs-droppable="true">
<!-- Template content -->
</div>
Use Blade directives for conditional content:
@if(config('app.debug'))
<div class="debug-info">Debug information</div>
@endif
The system provides statistics about loaded blocks:
$blockService = new BlockService();
$stats = $blockService->getBlockStatistics();
// Returns:
[
'total_blocks' => 25,
'categories' => [
'components' => 5,
'content' => 6,
'forms' => 1,
'layouts' => 5,
'media' => 3
],
'active_blocks' => 23,
'inactive_blocks' => 2
]
- Plan the block: Determine purpose and category
- Create the file: Add to appropriate directory
-
Add metadata: Include
@block
comment - Write HTML: Use semantic HTML structure
- Add styling: Use Tailwind classes
-
Make editable: Add
data-gjs-*
attributes - Test: Verify in GrapesJS editor
- Document: Add to block documentation
- Regular review: Check for outdated blocks
- Performance monitoring: Monitor block loading times
- User feedback: Gather feedback on block usability
- Updates: Keep blocks compatible with new versions
- Semantic HTML: Use proper HTML structure
- Accessibility: Include ARIA labels and keyboard navigation
- Performance: Keep blocks lightweight and efficient
- Consistency: Maintain consistent styling across blocks
- Clean code: Write readable, maintainable code
- Comments: Add comments for complex logic
- Validation: Test blocks thoroughly
- Documentation: Document custom blocks
- Intuitive: Make blocks easy to understand and use
- Flexible: Allow customization where appropriate
- Responsive: Ensure blocks work on all devices
- Fast: Optimize for quick loading
The dynamic block system makes it easy to create, organize, and maintain reusable components for your Laravel projects using the LaraGrape package! 🧑🎨
With comprehensive error handling, automatic discovery, and robust fallbacks, the block system provides a reliable foundation for building dynamic, visual content.