Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Content Block Bundle Laravel Package

anh/content-block-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle to your project via Composer:

    composer require anh/content-block-bundle
    

    Enable it in config/bundles.php:

    Anh\ContentBlockBundle\AnhContentBlockBundle::class => ['all' => true],
    
  2. Database & Admin Setup Run migrations (if any) and clear cache:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    php bin/console cache:clear
    

    Register the bundle in config/packages/anh_admin.yaml (if using anh/admin-bundle):

    anh_admin:
        resources:
            AnhContentBlockBundle:
                title: Content Blocks
    
  3. First Use Case Create a content block type via the admin interface (if available) or manually via Doctrine:

    use Anh\ContentBlockBundle\Entity\ContentBlock;
    use Anh\ContentBlockBundle\Entity\ContentBlockType;
    
    // Create a new block type
    $blockType = new ContentBlockType();
    $blockType->setName('Hero Section');
    $blockType->setDescription('A hero section with title and image');
    $blockType->setFields([
        'title' => ['type' => 'text', 'label' => 'Title'],
        'image' => ['type' => 'image', 'label' => 'Background Image'],
    ]);
    $entityManager->persist($blockType);
    $entityManager->flush();
    
    // Create a block instance
    $block = new ContentBlock();
    $block->setType($blockType);
    $block->setData(['title' => 'Welcome', 'image' => '/path/to/image.jpg']);
    $entityManager->persist($block);
    $entityManager->flush();
    

Implementation Patterns

Workflows

  1. Dynamic Content Blocks Use the bundle to create reusable, configurable blocks (e.g., hero sections, testimonials, call-to-actions) that can be managed via the admin panel.

    // Fetch blocks by type in a controller
    $blocks = $entityManager->getRepository(ContentBlock::class)
        ->findBy(['type' => $heroBlockType]);
    
  2. Embedding in Templates Render blocks in Twig using a custom loop:

    {% for block in blocks %}
        {% if block.type.name == 'Hero' %}
            <section class="hero">
                <h1>{{ block.data.title }}</h1>
                <img src="{{ block.data.image }}" alt="{{ block.data.title }}">
            </section>
        {% endif %}
    {% endfor %}
    
  3. Field Validation & Serialization Validate block data before saving:

    use Anh\ContentBlockBundle\Validator\Constraints as ContentBlockAssert;
    
    $block->addValidatorConstraint(
        new ContentBlockAssert\RequiredField('title')
    );
    
  4. Integration with Doctrine Resource Bundle Extend anh/doctrine-resource-bundle to manage blocks as resources:

    # config/packages/anh_doctrine_resource.yaml
    anh_doctrine_resource:
        resources:
            Anh\ContentBlockBundle\Entity\ContentBlock:
                title: Content Blocks
                list: AnhContentBlockBundle:ContentBlock/list.html.twig
                show: AnhContentBlockBundle:ContentBlock/show.html.twig
    

Integration Tips

  • Custom Field Types: Extend the bundle to support custom field types (e.g., rich text, nested blocks) by implementing Anh\ContentBlockBundle\Field\FieldTypeInterface.
  • Caching: Cache frequently accessed blocks to improve performance:
    $blocks = Cache::remember("blocks_{$typeId}", 3600, function () use ($typeId) {
        return $entityManager->getRepository(ContentBlock::class)->findBy(['type' => $typeId]);
    });
    
  • API Exposure: Use Symfony’s serializer to expose blocks via an API:
    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
    
    $normalizer = new ObjectNormalizer();
    $blockData = $normalizer->normalize($block, null, [
        'groups' => ['block_data'],
    ]);
    

Gotchas and Tips

Pitfalls

  1. Missing Dependencies Ensure anh/doctrine-resource-bundle and anh/admin-bundle are installed and configured. The bundle relies on these for CRUD operations and admin integration.

    composer require anh/doctrine-resource-bundle anh/admin-bundle
    
  2. Field Data Serialization The data field in ContentBlock is stored as a JSON string. Ensure your field types can be serialized/deserialized properly. Use json_encode()/json_decode() or a library like symfony/serializer for complex data.

  3. Admin Panel Limitations The admin panel (if available) may not support all field types out of the box. Customize the admin templates or override the field rendering logic in your theme.

  4. Migration Issues If you modify ContentBlockType fields, ensure you handle backward compatibility. Consider using a migration to update existing block data:

    // Example: Adding a new field to existing blocks
    $blocks = $entityManager->getRepository(ContentBlock::class)->findAll();
    foreach ($blocks as $block) {
        $block->setData(array_merge($block->getData(), ['new_field' => null]));
        $entityManager->persist($block);
    }
    $entityManager->flush();
    

Debugging

  • Validate Block Data Use the ContentBlockAssert constraints to validate data before saving:

    $validator = $this->get('validator');
    $errors = $validator->validate($block);
    if (count($errors) > 0) {
        throw new \RuntimeException('Block validation failed: ' . (string) $errors);
    }
    
  • Check Field Types If a field isn’t rendering or saving correctly, verify its type in ContentBlockType:

    $blockType->getFields(); // Debug the field definitions
    
  • Clear Cache After modifying bundle configurations or templates, clear the cache:

    php bin/console cache:clear
    

Extension Points

  1. Custom Field Types Create a new field type by implementing FieldTypeInterface:

    namespace App\ContentBlock\Field;
    
    use Anh\ContentBlockBundle\Field\FieldTypeInterface;
    
    class CustomFieldType implements FieldTypeInterface
    {
        public function getType(): string
        {
            return 'custom';
        }
    
        public function render($value, array $options = [])
        {
            // Custom rendering logic
        }
    }
    

    Register it in your bundle’s services:

    services:
        App\ContentBlock\Field\CustomFieldType:
            tags: { name: anh_content_block.field_type }
    
  2. Override Templates Override the default templates (e.g., list.html.twig, show.html.twig) in your theme to customize the admin interface:

    templates/
        AnhContentBlockBundle/
            ContentBlock/
                list.html.twig
                show.html.twig
    
  3. Event Listeners Listen to block events (e.g., prePersist, preUpdate) to add custom logic:

    use Anh\ContentBlockBundle\Event\ContentBlockEvents;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class ContentBlockSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                ContentBlockEvents::PRE_PERSIST => 'onPrePersist',
            ];
        }
    
        public function onPrePersist(ContentBlockEvent $event)
        {
            $block = $event->getBlock();
            // Custom logic
        }
    }
    

    Register the subscriber in services.yaml:

    services:
        App\EventSubscriber\ContentBlockSubscriber:
            tags: { name: kernel.event_subscriber }
    
  4. Query Builder Extensions Extend the ContentBlockRepository to add custom query methods:

    namespace App\Repository;
    
    use Anh\ContentBlockBundle\Entity\ContentBlock;
    use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
    
    class ContentBlockRepository extends ServiceEntityRepository
    {
        public function findByTypeAndPublished(string $type, bool $published = true)
        {
            return $this->createQueryBuilder('cb')
                ->andWhere('cb.type = :type')
                ->andWhere('cb.published = :published')
                ->setParameter('type', $type)
                ->setParameter('published', $published)
                ->getQuery()
                ->getResult();
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky