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

Simple Hmvc Bundle Laravel Package

beyerz/simple-hmvc-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require beyerz/simple-hmvc-bundle
    

    Add the bundle to config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):

    Beyerz\SimpleHMVCBundle\BeyerzSimpleHMVCBundle::class => ['all' => true],
    
  2. Generate a Page Use the command to scaffold a new HMVC page:

    php bin/console beyerz:simple-hmvc:page create MyPage
    

    This creates:

    src/Controller/MyPage/
    ├── MyPageController.php
    ├── MyPage.php          # Page class (HMVC entry point)
    └── templates/
        └── MyPage.html.twig
    
  3. First Use Case: Embedding a Widget In MyPage.php, define an element to embed:

    public function getElements()
    {
        return [
            'sidebar' => 'SidebarElement',
        ];
    }
    

    Render it in MyPage.html.twig:

    {{ render(element('sidebar')) }}
    

Implementation Patterns

Core Workflow

  1. Page Structure

    • Pages (MyPage.php) act as root controllers, orchestrating elements.
    • Elements (SidebarElement.php) are modular controllers with their own logic/views.
    • Use getElements() in Page classes to declare embeddable elements.
  2. Element Rendering

    • Render elements in Twig via {{ render(element('element_name')) }}.
    • Pass data to elements using setData() in the page controller:
      $this->getElement('sidebar')->setData(['title' => 'Hello']);
      
  3. Nested Elements Elements can embed other elements recursively. Example:

    // SidebarElement.php
    public function getElements()
    {
        return ['user_card' => 'UserCardElement'];
    }
    

    Render in SidebarElement.html.twig:

    {{ render(element('user_card')) }}
    
  4. Reusing Logic Extend base controllers for shared functionality:

    // BaseElementController.php
    abstract class BaseElementController extends Controller
    {
        protected function commonLogic() { ... }
    }
    
  5. Routing Elements are auto-routed under their parent page. Example:

    • Page: /page/my-page
    • Element: /page/my-page/sidebar

Integration Tips

  • Symfony Forms: Use createForm() in elements like any controller.
  • Services: Inject services into elements via constructor or setContainer().
  • Events: Dispatch events in elements to decouple logic:
    $this->get('event_dispatcher')->dispatch('sidebar.render', new SidebarEvent($data));
    
  • Twig Extensions: Extend Twig for custom element helpers:
    // src/Twig/Extension/ElementExtension.php
    class ElementExtension extends \Twig_Extension
    {
        public function getFunctions()
        {
            return [
                new \Twig_SimpleFunction('custom_element', [$this, 'renderCustomElement']),
            ];
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Circular Dependencies

    • Avoid recursive element inclusion (e.g., ElementA embedding ElementB, which embeds ElementA). Symfony’s dependency injection may fail silently.
    • Fix: Use if checks in Twig or lazy-load elements.
  2. Route Conflicts

    • Elements share routes with their parent page. Overlapping routes (e.g., /page/my-page and /page/my-page/sidebar) may cause 404s.
    • Fix: Use _route in Twig to specify full paths:
      {{ render(element('sidebar', {'_route': 'my_page_sidebar'})) }}
      
  3. Stale Cache

    • Twig cache may retain old element outputs. Clear cache after changes:
      php bin/console cache:clear
      
  4. Missing use Statements

    • Forgetting to use the ElementController trait in custom elements:
      use Beyerz\SimpleHMVCBundle\Controller\ElementController;
      
    • Symptom: Elements fail to render with "Method not found" errors.
  5. Data Binding

    • Data passed to elements via setData() is not automatically available in Twig. Use getData() in the element controller and pass it to the view:
      // SidebarElementController.php
      public function indexAction()
      {
          return $this->render('SidebarElement.html.twig', [
              'title' => $this->getData()['title'] ?? '',
          ]);
      }
      

Debugging

  • Check Element Existence Use Twig’s dump() to verify elements are registered:
    {{ dump(element('sidebar')) }}
    
  • Log Element Calls Override ElementController::render() to log calls:
    public function render($view, array $parameters = [])
    {
        $this->get('logger')->info('Rendering element: '.$view);
        return parent::render($view, $parameters);
    }
    
  • Route Debugging List all routes to spot conflicts:
    php bin/console debug:router
    

Tips

  1. Command-Line Generation Regenerate pages/elements after refactoring:

    php bin/console beyerz:simple-hmvc:page update MyPage
    
  2. Element Templates Store element templates in src/Resources/views/ for better organization:

    // SidebarElementController.php
    public function indexAction()
    {
        return $this->render('@MyBundle/SidebarElement.html.twig');
    }
    
  3. Configuration Override default paths in config/packages/beyerz_simple_hmvc.yaml:

    beyerz_simple_hmvc:
        page_dir: '%kernel.project_dir%/src/Controller/Pages'
        element_dir: '%kernel.project_dir%/src/Controller/Elements'
    
  4. Testing Elements Test elements in isolation using Symfony’s WebTestCase:

    public function testSidebarElement()
    {
        $client = static::createClient();
        $client->request('GET', '/page/my-page/sidebar');
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
    }
    
  5. Performance For static elements, use Twig’s {% include %} instead of {{ render() }} to bypass controller overhead.

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.
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium