Create a Page Bundle

December 2015 · 3 minute read

Adding on to the Global Bundle created in my previous article, the following will demonstrate how to create a Page Bundle with Symfony2 which is going to take care, specifically of handling page displays and features specific to pages, for the app I’m building.

1. First, in your applications module, create a new bundle called PageBundle containing a PageBundle.php file which will extend Bundle

namespace SelenaSmall\Bundle\PageBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class PageBundle extends Bundle {
}

2. The Bundle/PageBundle/DependencyInjection/Configuration.php will implement ConfigurationInterface and tell the bundle where it sits in the tree, following the root node ‘global’

namespace SelenaSmall\Bundle\PageBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface {

    public function getConfigTreeBuilder() {
        $treeBuilder = new TreeBuilder();

        $rootNode = $treeBuilder->root('global');
       return $treeBuilder;
    }
}

3. Again, similar to the GlobalBindle, the Bundle/PageBundle/DependencyInjection path, PageExtension.php will compile a list of configs for the bundles.

namespace SelenaSmall\Bundle\PageBundle\DependencyInjection;

use SelenaSmall\Bundle\GlobalBundle\Component\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class PageExtension extends Extension {
    public function load(array $configs, ContainerBuilder $container) {
        // Compile full bundle config array
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);
       // Set parameters for all config entries
        $this->setParameters($this->getAlias(), $config, $container);
        // Load services
        $this->loadConfig('services.yml', __DIR__ . '/../Resources/config', $container);
       // Add bundle to assetic
        $this->setAsseticBundle('PageBundle', $container);
    }
}

4. PageBundle/Routing/Loader.php will extend the AdvancedLoader and declare a public function to load all the routes declared in App/Resources/Config/routing.yml

namespace SelenaSmall\Bundle\PageBundle\Routing;

use SelenaSmall\Bundle\GlobalBundle\Component\Config\Loader\AdvancedLoader;
use Symfony\Component\Routing\RouteCollection;

class Loader extends AdvancedLoader {
	protected $type = 'advanced_page';

	public function load($resource, $type = null) {
		$collection = new RouteCollection();

		// Add admin controller
		$adminCollection = $this->import('@PageBundle/Controller/AdminController.php', 'annotation');
		$collection->addCollection($adminCollection);
		return $collection;
	}
}

5. The routing.yml file describes the type of resource the page refers to

page_routing:
  resource:   .
  type:       advanced_page

6. And just like in the GlobalBundle, services.yml describes a service for the RouteLoader

services:
  page.routing_loader:
    class:      SelenaSmall\Bundle\PageBundle\Routing\Loader
    arguments:  ['%kernel.bundles%']
    tags:
      - { name: routing.loader }

7. The Entity/Page.php will sit blank for now, but will later describe traits and relationships between data in the application

namespace SelenaSmall\Bundle\PageBundle\Entity;

8. The PageRepository.php will again, come in use later

namespace SelenaSmall\Bundle\PageBundle\Entity;

use SelenaSmall\Bundle\GlobalBundle\Component\Entity\Repository;

class PageRepository extends Repository {
    # region Find

    # endregion Find
}

9. Resources/translations/PageBundle.en.yml ensures that the default language of ‘Pages’ is English

admin:
  index:
    title:  'Pages'

10. Resources/Views/Admin/index.html.twig is the page that will be displayed in html in the web browser and must contain header and content blocks

{% extends 'AdminBundle::layout.html.twig' %}
{% trans_default_domain 'PageBundle' %}
{% block breadcrums %} {% endblock %}
{% block header %}
  <h1>{{ 'admin.index.title'|trans }}</h1>
{% endblock  header %}
{% block breadcrumbs %}
  {{ parent() }}
  <a href="{{ url('Pagebundle:Admin:index') }}">{{ 'admin.index.title'|trans }}</a>
{% endblock breadcrumbs %}
{% block content %}
    THIS is the page Index
{% endblock content %}

11. Lastly, ensure that the new PageBundle has been included into the AppKernel.php file so the rest of the application can talk to it.

new SelenaSmall\Bundle\PageBundle\PageBundle(),

12. Go to the localhost configured for this application and see a new blank, index page.