Partial Content

Working with eZ Publish 5 - Templates

Starting Development

In Symfony, your development happens in Bundles. Bundles provide containers for your code, and can even allow you to override files from third parties or the core software itself. So we'll start off by generating a bundle to hold our work. 

Symfony provides a command line tool to help generate a new bundle. All you need to do is provide a namespace for your bundle. The namespace should be unique to your project, and the first element is usually your company or site name. Per Symfony standards, the final element in the namespace must end with the word 'Bundle'. On the command line, run the following from the ez publish root (htdocs in the sample code): 

php ezpublish/console generate:bundle --namespace="Blend/TutorialBlogBundle" 

This will kick off a wizard that will ask you a series of questions about your bundle. Just hit 'enter' for most of these, but use 'yml' for your configuration format, and let Symfony generate the whole directory structure and take all the automated steps to register your bundle. Your wizard session will look something like this: 

Bundle Generation Screenshot

Once the wizard is done, we'll have an extra directory structure under the 'src' directory. 

Contents of bundle directory - Finder screenshot

What's in here? Well, we'll come back to most of it, but a couple of things to note for now: 

  • Resources - this is where all of the non-PHP items for your bundle are stored, including config files, Twig templates, and javascript, CSS, and image assets.
  • Controller - any controllers you write will go here; we'll create one later
  • Tests - Symfony provides a testing framework for all code and encourages the creation of unit tests. This is beyond the scope of this tutorial, but I'll cover it in a future post.

Now that we have our bundle in place, let's start off by creating a Twig template that will define the structure of our site, the page layout template. This template will serve as the basis for all of our HTML pages. Twig uses a system of template inheritance, so other pages will replace specific pieces of our page layout with specific content later on. If we don't have a piece of a template available as a Twig template, eZ Publish will try to fill the content in from the legacy template system.

Create a file called 'pagelayout.html.twig' in src/Blend/PartialContentBundle/Resources/views, and add a basic template: 

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Title Here</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">

</head>
<body>
<header class="main-header">
    {% block header %}
        <div class="branding jumbotron subhead">
            <div class="container">
                <h1>This Site's Name</h1>
            </div>
        </div>
        <nav class="navbar navbar-inverse">
            <div class="navbar-inner">
                <div class="container">
                    {% block topnav %}
                        Top Menu will go here
                    {% endblock %}
                </div>
            </div>
        </nav>
    {% endblock %}
</header>

<div class="container">
    <div class="body">
        <div class="row">
            <div class="main span9">
                {% block content %}{% endblock %}
            </div>
            <aside class="sidebar span3">
                {% block sidebar %}
                    Sidebar stuff goes here
                {% endblock %}
            </aside>
        </div>
    </div>
</div>

<footer class="footer">
    {% block footer %}
        Footer stuff goes here
    {% endblock %}
</footer>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

</body>
</html>

With our pagelayout template in place, we need to tell eZ Publish to start using it. Edit the ezpublish/config/parameters.yml file and modify the 'ezpublish_legacy.view.default_layout' setting like so: 

ezpublish_legacy.view.default_layout: BlendTutorialBlogBundle::pagelayout.html.twig

If you refresh http://ez5tutorial.local, you should now have a very ugly-looking site: 

Screenshot of basic site with no styling

Where's all that stuff coming from? Well, since there are no Twig templates to render the content area, the legacy eZ Publish site is trying to render a basic blog. But if you examine the HTML, you should find that it's using our page layout. You'll also notice that the page doesn't have any styles, because we haven't provided any. We'll do that next. 

Asset Management

eZ Publish 4 provided a handy system for managing stylesheets and javascript called eZJSCore. Symfony provides an even handier system called Assetic, so we'll use that to add some styles to our site. 

For this project, I've used HTML5 Boilerplate and Twitter Bootstrap. The assets for these should go in the js, css, and images directories in our bundle's Resources/public folder. To save time and frustration, I've downloaded these for you in our next tutorial step on github, and also set a few settings in the legacy eZ Publish environment to help with some of the content formatting in the admin. Let's clear out our work and switch to that branch now. Note that this will erase any work you've done so far and replace it with the tutorial version, so if you've made customizations you want to save, create a new branch for them in git before proceeding.

To switch branches, first clean up the working area by typing: 

git checkout -- *
git clean -f -d 

Then switch to the next step in the tutorial: 

git checkout -b tutorial-2 origin/tutorial-2 

Note: if you have already looked at this branch, you'll get an error saying the branch already exists. In that case, simply type 'git checkout tutorial-2'

In this new branch, we've pulled down some new javascript, css, and image files into the Resources/public folder. To use them in the template, we'll use assetic to reference them. Add this to the header of your pagelayout.html.twig just below the meta tags: 

    {% stylesheets "bundles/blendtutorialblog/css/*" %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}
 
    {% javascripts
        "bundles/blendtutorialblog/js/modernizr.js"
        "bundles/blendtutorialblog/js/bootstrap.js"
    %}
        <script type="text/javascript" src="{{ asset_url }}"></script>
    {% endjavascripts %}

The {% stylesheets %} block will iterate over all files in "bundles/blendtutorialblog/css/*" and create the included <link> tag for each file it finds, loaded alphabetically. The {% javascripts %} block will load each of the named javascript files in turn and create the script tag. In a production environment, Assetic will also condense these into a single file. 

The paths used here are relative to the 'web' folder, since that's the Apache root. But if you look, you'll notie that there isn't a bundles/blendtutorialblog folder in the 'web' directory. You'll need to run a console command to symlink the assets there, which we haven't done. In the htdocs directory, run this from the terminal: 

php ezpublish/console assets:install --symlink 

Now the symlink for your bundle should appear, and refreshing http://ez5tutorial.local should grace us with a styled page.

Screenshot of styled page

With that out of the way, let's add some missing pieces by creating content templates.