SlideShare a Scribd company logo
Terrific Composer Workshop
Terrific Composer
Makes your life easier…
Agenda

Concept

Terrific Composer
   ‣ Installation
   ‣ Twig
   ‣ Pages
   ‣ Modules & Skins
   ‣ Layout
   ‣ Dev -> Prod




Remo Brunschwiler   10. July 2012   #   3
Github
Take it. Make it better. Together.
Repositories

TerrificJS
   ‣ https://github.com/brunschgi/terrificjs

Terrific Composer (Symfony2 Edition)
   ‣ https://github.com/brunschgi/terrific-composer

Terrific Symfony2 Bundles
   ‣ https://github.com/brunschgi/TerrificCoreBundle
   ‣ https://github.com/brunschgi/TerrificComposerBundle




Remo Brunschwiler   10. July 2012                          #   5
Showcases
See Terrific in action
Remo Brunschwiler   14. August 2012   #   7
Concept
It’s really easy…
Hold on a minute!

Before we dive deeper into the Terrific Composer…




Remo Brunschwiler                                   #   9
Hold on a minute!

Before we dive deeper into the Terrific Composer…



Lets refresh our Terrific
knowledge!
http://www.slideshare.net/brunschgi/terrific-frontends




Remo Brunschwiler                                        #   9
Terrific Composer
Makes your life easier…
Terrific Composer

Frontend Development Framework
   ‣ Designed for building frontends / applications based on the
     Terrific concept
   ‣ Integrates TerrificJS
   ‣ Based on Symfony
   ‣ … still very young




Remo Brunschwiler   10. July 2012                                  #   11
Terrific Composer

Frontend Development Framework
   ‣ Designed for building frontends / applications based on the
     Terrific concept
   ‣ Integrates TerrificJS
   ‣ Based on Symfony
   ‣ … still very young



… melts dozens of best practices!




Remo Brunschwiler   10. July 2012                                  #   11
Documentation

Terrific Composer
   ‣ Unfortunately, a specific documentation does not exist yet
   ‣ Any help is gladly appreciated!!

Symfony Documentation
   ‣ http://symfony.com/doc/current/quick_tour/the_big_picture.html
     – quick tour
   ‣ http://symfony.com/doc/current/book/ – really great in-depth
     documentation!
   ‣ http://symfony.com/doc/current/cookbook/ – solutions and
     tutorials for common tasks
   ‣ http://symfony.com/doc/current/components/index.html –
     symfony components documentation



Remo Brunschwiler   10. July 2012                                   #   12
Installation
Very fast setup for your project!
Download it from: http://terrifically.org/composer/


 Installation




Remo Brunschwiler   10. July 2012                     # 14
Explore
… the sidebar and their possibilities
Create


                                    Add new Modules & Skins to your project.
                                    The Skeleton is generated for you so that
                                    you can start right away.




Remo Brunschwiler   10. July 2012                                        #   16
Open


                                    The Open dialog provides you fast access to
                                    all of your Modules and Pages.




Remo Brunschwiler   10. July 2012                                       #   17
Inspect


                                    The inspect mode shows you which modules
                                    are in use on the current page.




Remo Brunschwiler   10. July 2012                                    #   18
Twig
The flexible, fast, and secure template engine for PHP
Twig

Symfony comes with a powerful templating language called Twig
   ‣ http://symfony.com/doc/current/book/templating.html
   ‣ http://twig.sensiolabs.org/documentation



…I couldn’t have explained it better, so have a look at the links
above :-)




Remo Brunschwiler   10. July 2012                                   # 20
IDE Integration

Twig is a quite young project, but there is already support for
several IDEs:
   ‣ PhpStorm (native as of 2.1) – recommended!!
   ‣ Textmate via the Twig bundle
   ‣ Vim via the Jinja syntax plugin
   ‣ Netbeans via the Twig syntax plugin
   ‣ Eclipse via the Twig plugin
   ‣ Sublime Text via the Twig bundle
   ‣ Coda 2 via the other Twig syntax mode




Remo Brunschwiler   10. July 2012                                 #   21
Hands on!
Terrific Composer – Step by Step
Step by Step

Common Tasks
   ‣ Create a new page
   ‣ Create a new Module / Skin
   ‣ Create a new layout
   ‣ Development -> Productive




Remo Brunschwiler   10. July 2012   # 23
Pages
Play Lego!
… Let’s see it in action




Remo Brunschwiler   10. July 2012   # 25
Create a new page

Things to do
   1. Create a new or extend an existing controller
   2. Create an action in the controller
   3. Set annotations (@Template, @Route, @Composer)
   4. Create a view (twig file) in /Resources/views/




Remo Brunschwiler   10. July 2012                      # 26
1. Create / Extend Controller

<?php
namespace TerrificCompositionController;

use   SymfonyBundleFrameworkBundleControllerController;
use   TerrificComposerBundleAnnotationComposer;
use   SensioBundleFrameworkExtraBundleConfigurationRoute;
use   SensioBundleFrameworkExtraBundleConfigurationTemplate;

class DefaultController extends Controller
{
}

Things to consider
   ‣ PHP 5.3 namespace describes where the class is located
   ‣ Filename = ClassName, eg. DefaultController.php
     -> needed for classloading
   ‣ PHP 5.3 use statements for base controller and annotations


Remo Brunschwiler   10. July 2012                                  # 27
2. Create Action

class DefaultController extends Controller
{
    /**
      * @Composer("Welcome")
      * @Route("/", name="home")
      * @Template()
      */
    public function indexAction()
    {
         return array();
    }
}

Things to consider
   ‣ action name must end in Action
   ‣ return statement of an action is a Response object
     -> in our case it is and array: because of @Template()



Remo Brunschwiler   10. July 2012                             # 28
3. Set Annotations
/**
  * @Composer("Welcome")
  * @Route("/", name="home")
  * @Template()
  */
public function indexAction()
{
     return array();
}

@Composer(<name>)
   ‣ The given name will appear in the open dialog

@Route(“<path>”, name=”<name”)
   ‣ Describes the path under which the page is available
   ‣ For more options have a look at @Route

@Template()
   ‣ Specifies which template should be rendered (@Template documentation)



Remo Brunschwiler   10. July 2012                                      # 29
4. Create Twig View

/Resources/views/<ControllerName>/<actionName>.html.twig

   {% extends 'TerrificComposition::base.html.twig' %}

   {% block title %}Terrific Composer - Welcome{% endblock %}

   {% block body %}
   <div class="page">
     … here comes your stuff …
   </div>
   {% endblock %}



Things to consider
‣ Extend the layout of your choice
‣ Override / Extend the twig blocks you need


Remo Brunschwiler   10. July 2012                               # 30
Twig Blocks

Provided from TerrificCoreBundle::base.html.twig
   ‣ title – content of the <title> element
   ‣ meta – for meta tags (<meta charset="UTF-8"/> is always set)
   ‣ styles – the place for your stylesheets
   ‣ body_class – allows you to give your body a class
   ‣ composition – your content goes here
   ‣ jquery – jquery script element
   ‣ terrificjs – terrificjs script element
   ‣ scripts – the place for your javascripts
   ‣ bootstrap – the default terrificjs bootstrap



Remo Brunschwiler   10. July 2012                                   #   31
Hands on!

Create a new page that…
   ‣ is available under /workshop
   ‣ appears in the open dialog as “Workshop”
   ‣ has the same content as the homepage




Remo Brunschwiler   10. July 2012               # 32
Hands on!

Create a new page that…
   ‣ is available under /workshop
   ‣ appears in the open dialog as “Workshop”
   ‣ has the same content as the homepage

Enhance the page, so that…
   ‣ you can type an URL like /workshop/{title}
   ‣ the {title} is displayed as heading before the Intro module
   ‣ and if no title is given, “Terrific Composer” should be displayed
     instead




Remo Brunschwiler   10. July 2012                                    # 32
Twig Module Macro
{#
      Renders terrific modules.

      @param   name {String} name of the module
      @param   view {String} name of the view to render (without html.twig suffix) [optional]
      @param   skins {Array} contains the skins to apply [optional]
      @param   connectors {Array} contains the channel ids to connect to [optional]
      @param   attrs {Object} contains the additional html attributes for the module [optional]
      @param   data {Object} contains the data to pass to embedded controllers [optional]
#}
{% macro module(name, view, skins, connectors, attrs, data) %}



To consider
     ‣ Twig 1.x does not support things like:
      {{ tc.module('Intro', attrs={'data-name' : 'einstein'}) }}
      -> this is going to change with Twig 2.0



Remo Brunschwiler    10. July 2012                                                   # 33
Render Modules #1

Simple views without logic

{# this render the template with the same name (intro.html.twig) #}
{{ tc.module('Intro') }}

{# this renders the mrterrific template from the Hero Module #}
{{ tc.module('Hero', 'mrterrific')}}

{# the 3rd param is the Skins array, ie. Mr. Terrific is getting decorated
with the Stealth Skin #}
{{ tc.module('Hero', 'mrterrific', [ 'Stealth' ])}}

{# the 4th param is an array with communication channel ids, ie. all
modules with the same id can talk with each other #}
{{ tc.module('Hero', 'mrterrific', ['Stealth'], ['talk'])}}

{# the 5th param is the attrs object #}
{{ tc.module('Hero', 'mrterrific', null, null, { ‘data-name’ :
‘Mr. Terrific‘})}}


Remo Brunschwiler   10. July 2012                                       # 34
Render Modules #2

Complex views
‣ the concept is – thanks to TWIG – very simple
  http://symfony.com/doc/current/book/
  templating.html#embedding-controllers
‣ have their own controllers, actions & templates
‣ gives you Multi-MVC out-of-the-box
‣ are used rarely in plain “templating” projects


{{ tc.module('Filter','Filter:overspeed', null, null, null, {'segment':'washing'})}}

                embeds the view of the FilterController/   the data passed to the
                 overspeedAction in the Filter module         overspeedAction




Remo Brunschwiler   10. July 2012                                                   # 35
Hands on!

Enhance your workshop page, so that…
   ‣ only two of the heroes can talk with each other
   ‣ the {title} is rendered inside the speech bubble of Einstein




Remo Brunschwiler   10. July 2012                                   # 36
Modules & Skins
Get more flexibility…
What we want to achieve

Create a new «Victim» module, that…
   ‣ consists of a normal image (drowning man) & a background
     image (bubble)
   ‣ uses less for better code
   ‣ is able to call our heroes for help




Remo Brunschwiler   10. July 2012                               # 38
Markup

<div class="bubble">
    <span class="message">help!</span>
</div>
<img src="
  {{ asset("bundles/terrificmodulevictim/img/drowning-victim.png") }}
"/>
<a class="base" href="#help">Call for help!</a>


                                            links to image asset in /web/bundles/…


But how is the drowning-victim.png got there?
   ‣ The composer copies all module images on the fly to
     /web/bundles/<bundle>/img/ (configurable in config_dev.yml)

How did you come up with that path?
   ‣ Symfony standard: app/console assets:install


Remo Brunschwiler   10. July 2012                                           # 39
Import directive (mixins, variables etc.)
/* import.less */
@import "colors.less";
@import "mixins.less";

/* colors.less */
@text: #74AE00;               variable

/* mixins.less*/
.scale(@ratio) {             mixin function
  -webkit-transform:        scale(@ratio);
     -moz-transform:        scale(@ratio);
      -ms-transform:        scale(@ratio);
       -o-transform:        scale(@ratio);
          transform:        scale(@ratio);
}




Remo Brunschwiler   10. July 2012             # 40
/* @group Module: victim */
@import "../../../../../Composition/Resources/public/css/import.less";

@media screen {
                                           cascaded import – import.less has other imports
    .mod-victim {
        position: relative;

           .bubble {   nested rules -> .mod-victim .bubble { … }
               background: transparent url('../bubble.png') no-repeat 0 0;
               ...
           }
                   access variable             relative to less file
           .message {
               color: @text;
               font-size: 36 / 16em;
               ...
           }                 calculation
           ...
      }
}




Remo Brunschwiler   10. July 2012                                                 #   41
There is even more to less! Have a look at the documentation
   ‣ http://lesscss.org




Remo Brunschwiler   10. July 2012                              # 42
TerrificJS

on:function (callback) {
    var self = this,
        $ctx = this.$ctx;

      $('a', $ctx).on('click', function() {
          var message = $('.message', $ctx).text();

            self.fire('message', { name: 'drowner', message: message });

            return false;
      });

      callback();
}



Nothing special here, but mention the new naming of the hooks in
TerrificJS v2.0



Remo Brunschwiler   10. July 2012                                          # 43
Hands on!

Create a skin for your Victim that lets him drown when there is no
help from one of the heroes
   ‣ Create skin “Drown” for your Victim
   ‣ Write a simple drown functionality (eg. fadeOut)
   ‣ Trigger this functionality automatically after ~5 seconds
   ‣ Do not let your Victim drown when he calls for help within the
     given time frame




Remo Brunschwiler   10. July 2012                                     # 44
Layouts
Let’s say thanks to TWIG & Assetic
Layouts

A layouts job is to do stuff that is common to several pages
   ‣ javascripts
   ‣ styles
   ‣ meta tags
   ‣ header, footer, sidebar etc.

Thanks to TWIG & Assetic, layouts are no longer a big & inflexible
thing…




Remo Brunschwiler   10. July 2012                                    # 46
Twig Layout Approach

In Twig a layout is nothing more than an inherited template
   ‣ http://symfony.com/doc/current/book/templating.html#template-
     inheritance-and-layouts

In your page:                       this is your layout


   {% extends 'TerrificComposition::base.html.twig' %}

   {% block title %}Terrific Composer - Welcome{% endblock %}

   {% block body %}
   <div class="page">
     … here comes your stuff …
   </div>
   {% endblock %}




Remo Brunschwiler   10. July 2012                               # 47
Twig Layout Approach

In TerrificComposition::base.html.twig

{% extends 'TerrificCoreBundle::base.html.twig' %}          Terrific Core Layout

{% block title %}Terrific Composer{% endblock %}
…
{# content that is the same on every page goes into composition #}
{% block composition %}

{# your page content goes into body #}
{% block body %}    this block is overridden in your page
{% endblock %}

{% endblock %}
…




Remo Brunschwiler   10. July 2012                                                  # 48
Including JavaScripts

Symfony comes bundled with a very nice Assetic integration

Including JavaScripts has never been easier
                                     concatenates – and minifies in production
{% block scripts %}                       mode – all files in this directory
    {# here comes your scripts #}
    {% javascripts
    '@TerrificComposition/Resources/public/js/*.*'
    output='js/compiled/statics.js'      the name of the compiled file
    %}
        <script src="{{ asset_url }}" type="text/javascript"></script>
    {% endjavascripts %}

    {# scripts from parent (terrific core) layout #}
    {{ parent() }}      includes the content of the parent block
{% endblock %}




Remo Brunschwiler   10. July 2012                                                # 49
Including Stylesheets

… and the same for stylesheets
                                       concatenates – and minifies in production
                                             mode – all of the given files
{% block styles %}
    {% stylesheets
        '@TerrificComposition/Resources/public/css/reset.less'
        '@TerrificComposition/Resources/public/css/grid.less'
        '@TerrificComposition/Resources/public/css/elements.less'
        output="css/compiled/project.css"     the name of the compiled file
    %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}

    {# styles from parent (terrific core) layout #}
    {{ parent() }}      includes the content of the parent block
{% endblock %}




Remo Brunschwiler   10. July 2012                                                  # 50
Dev -> Prod
Prepare your assets for the real world
Productive

The productive version is…
   ‣ available under / (instead of /app_dev.php)

Dumping assets
   ‣ php app/console assets:install web

Compile CSS / JS
   ‣ php app/console assetic:dump --env=prod




Remo Brunschwiler   10. July 2012                  # 52
Questions?
More…
More…

Lets keep talking
   ‣ http://terrifically.org
   ‣ remo@terrifically.org
   ‣ https://github.com/brunschgi
   ‣ http://twitter.com/#!/brunschgi




Remo Brunschwiler   10. July 2012      # 55
Remo Brunschwiler   10. July 2012   # 56
Thank you!

More Related Content

PDF
Plone and docker
PDF
PDF
HTML5 for PHP Developers - IPC
PDF
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
PDF
tut0000021-hevery
PDF
&lt;img src="../i/r_14.png" />
PPTX
Python/Flask Presentation
ODP
Vagrant move over, here is Docker
Plone and docker
HTML5 for PHP Developers - IPC
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
tut0000021-hevery
&lt;img src="../i/r_14.png" />
Python/Flask Presentation
Vagrant move over, here is Docker

What's hot (7)

PDF
Behavior & Specification Driven Development in PHP - #OpenWest
PDF
Flutter movie apps tutor
PPTX
Dockercon - Building a Chef cookbook testing pipeline with Drone.IO and Docker
PPTX
Creating Openbravo Workspace Widgets
PPTX
Introduction to Continous Integration with WordPress
PDF
Asynchronous Programming at Netflix
PDF
Maven 3.0 at Øredev
Behavior & Specification Driven Development in PHP - #OpenWest
Flutter movie apps tutor
Dockercon - Building a Chef cookbook testing pipeline with Drone.IO and Docker
Creating Openbravo Workspace Widgets
Introduction to Continous Integration with WordPress
Asynchronous Programming at Netflix
Maven 3.0 at Øredev
Ad

Viewers also liked (6)

PPS
德國氣球節
DOCX
這些年.這些事
PDF
WL4 Firewall
PDF
Developer sales staff amas power point presentation
DOC
Check mate infidelity test press release
PDF
VSTS in a nutshell for project lifecycle management
德國氣球節
這些年.這些事
WL4 Firewall
Developer sales staff amas power point presentation
Check mate infidelity test press release
VSTS in a nutshell for project lifecycle management
Ad

Similar to Terrific Composer Workshop (20)

PDF
Tips and Tricks for Using Visual Studio.Net Effectively
PDF
Chrome & Webkit overview
PDF
Full Stack React Workshop [CSSC x GDSC]
PDF
Terrific Frontends
PPTX
Guide: How to Build OpenCV 3.0.0
PPTX
web application.pptx
PDF
Fewd week1 slides
PDF
CEF.net
PDF
Fast Paced Drupal 8: Accelerating Development with Composer, Drupal Console a...
PPTX
Untangling4
PDF
JavaScript guide 2020 Learn JavaScript
PDF
Makefile
PDF
Desktop apps with node webkit
PDF
His162013 140529214456-phpapp01
PDF
C++ for hackers
PDF
Fewd week4 slides
PDF
Docker Introduction.pdf
PPTX
JavaScript Presentation Frameworks and Libraries
PDF
Hacking the Kinect with GAFFTA Day 1
PDF
C# 12 Pocket Reference: Instant Help for C# 12 Programmers Joseph Albahari
Tips and Tricks for Using Visual Studio.Net Effectively
Chrome & Webkit overview
Full Stack React Workshop [CSSC x GDSC]
Terrific Frontends
Guide: How to Build OpenCV 3.0.0
web application.pptx
Fewd week1 slides
CEF.net
Fast Paced Drupal 8: Accelerating Development with Composer, Drupal Console a...
Untangling4
JavaScript guide 2020 Learn JavaScript
Makefile
Desktop apps with node webkit
His162013 140529214456-phpapp01
C++ for hackers
Fewd week4 slides
Docker Introduction.pdf
JavaScript Presentation Frameworks and Libraries
Hacking the Kinect with GAFFTA Day 1
C# 12 Pocket Reference: Instant Help for C# 12 Programmers Joseph Albahari

Recently uploaded (20)

PDF
Mushroom cultivation and it's methods.pdf
PPTX
A Presentation on Artificial Intelligence
PPTX
1. Introduction to Computer Programming.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PPTX
Tartificialntelligence_presentation.pptx
PDF
Approach and Philosophy of On baking technology
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PDF
Heart disease approach using modified random forest and particle swarm optimi...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
August Patch Tuesday
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Spectroscopy.pptx food analysis technology
Mushroom cultivation and it's methods.pdf
A Presentation on Artificial Intelligence
1. Introduction to Computer Programming.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
MIND Revenue Release Quarter 2 2025 Press Release
cloud_computing_Infrastucture_as_cloud_p
Building Integrated photovoltaic BIPV_UPV.pdf
Univ-Connecticut-ChatGPT-Presentaion.pdf
Tartificialntelligence_presentation.pptx
Approach and Philosophy of On baking technology
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Unlocking AI with Model Context Protocol (MCP)
SOPHOS-XG Firewall Administrator PPT.pptx
Heart disease approach using modified random forest and particle swarm optimi...
Digital-Transformation-Roadmap-for-Companies.pptx
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Agricultural_Statistics_at_a_Glance_2022_0.pdf
August Patch Tuesday
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Spectroscopy.pptx food analysis technology

Terrific Composer Workshop

  • 3. Agenda Concept Terrific Composer ‣ Installation ‣ Twig ‣ Pages ‣ Modules & Skins ‣ Layout ‣ Dev -> Prod Remo Brunschwiler 10. July 2012 # 3
  • 4. Github Take it. Make it better. Together.
  • 5. Repositories TerrificJS ‣ https://github.com/brunschgi/terrificjs Terrific Composer (Symfony2 Edition) ‣ https://github.com/brunschgi/terrific-composer Terrific Symfony2 Bundles ‣ https://github.com/brunschgi/TerrificCoreBundle ‣ https://github.com/brunschgi/TerrificComposerBundle Remo Brunschwiler 10. July 2012 # 5
  • 7. Remo Brunschwiler 14. August 2012 # 7
  • 9. Hold on a minute! Before we dive deeper into the Terrific Composer… Remo Brunschwiler # 9
  • 10. Hold on a minute! Before we dive deeper into the Terrific Composer… Lets refresh our Terrific knowledge! http://www.slideshare.net/brunschgi/terrific-frontends Remo Brunschwiler # 9
  • 12. Terrific Composer Frontend Development Framework ‣ Designed for building frontends / applications based on the Terrific concept ‣ Integrates TerrificJS ‣ Based on Symfony ‣ … still very young Remo Brunschwiler 10. July 2012 # 11
  • 13. Terrific Composer Frontend Development Framework ‣ Designed for building frontends / applications based on the Terrific concept ‣ Integrates TerrificJS ‣ Based on Symfony ‣ … still very young … melts dozens of best practices! Remo Brunschwiler 10. July 2012 # 11
  • 14. Documentation Terrific Composer ‣ Unfortunately, a specific documentation does not exist yet ‣ Any help is gladly appreciated!! Symfony Documentation ‣ http://symfony.com/doc/current/quick_tour/the_big_picture.html – quick tour ‣ http://symfony.com/doc/current/book/ – really great in-depth documentation! ‣ http://symfony.com/doc/current/cookbook/ – solutions and tutorials for common tasks ‣ http://symfony.com/doc/current/components/index.html – symfony components documentation Remo Brunschwiler 10. July 2012 # 12
  • 15. Installation Very fast setup for your project!
  • 16. Download it from: http://terrifically.org/composer/ Installation Remo Brunschwiler 10. July 2012 # 14
  • 17. Explore … the sidebar and their possibilities
  • 18. Create Add new Modules & Skins to your project. The Skeleton is generated for you so that you can start right away. Remo Brunschwiler 10. July 2012 # 16
  • 19. Open The Open dialog provides you fast access to all of your Modules and Pages. Remo Brunschwiler 10. July 2012 # 17
  • 20. Inspect The inspect mode shows you which modules are in use on the current page. Remo Brunschwiler 10. July 2012 # 18
  • 21. Twig The flexible, fast, and secure template engine for PHP
  • 22. Twig Symfony comes with a powerful templating language called Twig ‣ http://symfony.com/doc/current/book/templating.html ‣ http://twig.sensiolabs.org/documentation …I couldn’t have explained it better, so have a look at the links above :-) Remo Brunschwiler 10. July 2012 # 20
  • 23. IDE Integration Twig is a quite young project, but there is already support for several IDEs: ‣ PhpStorm (native as of 2.1) – recommended!! ‣ Textmate via the Twig bundle ‣ Vim via the Jinja syntax plugin ‣ Netbeans via the Twig syntax plugin ‣ Eclipse via the Twig plugin ‣ Sublime Text via the Twig bundle ‣ Coda 2 via the other Twig syntax mode Remo Brunschwiler 10. July 2012 # 21
  • 24. Hands on! Terrific Composer – Step by Step
  • 25. Step by Step Common Tasks ‣ Create a new page ‣ Create a new Module / Skin ‣ Create a new layout ‣ Development -> Productive Remo Brunschwiler 10. July 2012 # 23
  • 27. … Let’s see it in action Remo Brunschwiler 10. July 2012 # 25
  • 28. Create a new page Things to do 1. Create a new or extend an existing controller 2. Create an action in the controller 3. Set annotations (@Template, @Route, @Composer) 4. Create a view (twig file) in /Resources/views/ Remo Brunschwiler 10. July 2012 # 26
  • 29. 1. Create / Extend Controller <?php namespace TerrificCompositionController; use SymfonyBundleFrameworkBundleControllerController; use TerrificComposerBundleAnnotationComposer; use SensioBundleFrameworkExtraBundleConfigurationRoute; use SensioBundleFrameworkExtraBundleConfigurationTemplate; class DefaultController extends Controller { } Things to consider ‣ PHP 5.3 namespace describes where the class is located ‣ Filename = ClassName, eg. DefaultController.php -> needed for classloading ‣ PHP 5.3 use statements for base controller and annotations Remo Brunschwiler 10. July 2012 # 27
  • 30. 2. Create Action class DefaultController extends Controller { /** * @Composer("Welcome") * @Route("/", name="home") * @Template() */ public function indexAction() { return array(); } } Things to consider ‣ action name must end in Action ‣ return statement of an action is a Response object -> in our case it is and array: because of @Template() Remo Brunschwiler 10. July 2012 # 28
  • 31. 3. Set Annotations /** * @Composer("Welcome") * @Route("/", name="home") * @Template() */ public function indexAction() { return array(); } @Composer(<name>) ‣ The given name will appear in the open dialog @Route(“<path>”, name=”<name”) ‣ Describes the path under which the page is available ‣ For more options have a look at @Route @Template() ‣ Specifies which template should be rendered (@Template documentation) Remo Brunschwiler 10. July 2012 # 29
  • 32. 4. Create Twig View /Resources/views/<ControllerName>/<actionName>.html.twig {% extends 'TerrificComposition::base.html.twig' %} {% block title %}Terrific Composer - Welcome{% endblock %} {% block body %} <div class="page"> … here comes your stuff … </div> {% endblock %} Things to consider ‣ Extend the layout of your choice ‣ Override / Extend the twig blocks you need Remo Brunschwiler 10. July 2012 # 30
  • 33. Twig Blocks Provided from TerrificCoreBundle::base.html.twig ‣ title – content of the <title> element ‣ meta – for meta tags (<meta charset="UTF-8"/> is always set) ‣ styles – the place for your stylesheets ‣ body_class – allows you to give your body a class ‣ composition – your content goes here ‣ jquery – jquery script element ‣ terrificjs – terrificjs script element ‣ scripts – the place for your javascripts ‣ bootstrap – the default terrificjs bootstrap Remo Brunschwiler 10. July 2012 # 31
  • 34. Hands on! Create a new page that… ‣ is available under /workshop ‣ appears in the open dialog as “Workshop” ‣ has the same content as the homepage Remo Brunschwiler 10. July 2012 # 32
  • 35. Hands on! Create a new page that… ‣ is available under /workshop ‣ appears in the open dialog as “Workshop” ‣ has the same content as the homepage Enhance the page, so that… ‣ you can type an URL like /workshop/{title} ‣ the {title} is displayed as heading before the Intro module ‣ and if no title is given, “Terrific Composer” should be displayed instead Remo Brunschwiler 10. July 2012 # 32
  • 36. Twig Module Macro {# Renders terrific modules. @param name {String} name of the module @param view {String} name of the view to render (without html.twig suffix) [optional] @param skins {Array} contains the skins to apply [optional] @param connectors {Array} contains the channel ids to connect to [optional] @param attrs {Object} contains the additional html attributes for the module [optional] @param data {Object} contains the data to pass to embedded controllers [optional] #} {% macro module(name, view, skins, connectors, attrs, data) %} To consider ‣ Twig 1.x does not support things like: {{ tc.module('Intro', attrs={'data-name' : 'einstein'}) }} -> this is going to change with Twig 2.0 Remo Brunschwiler 10. July 2012 # 33
  • 37. Render Modules #1 Simple views without logic {# this render the template with the same name (intro.html.twig) #} {{ tc.module('Intro') }} {# this renders the mrterrific template from the Hero Module #} {{ tc.module('Hero', 'mrterrific')}} {# the 3rd param is the Skins array, ie. Mr. Terrific is getting decorated with the Stealth Skin #} {{ tc.module('Hero', 'mrterrific', [ 'Stealth' ])}} {# the 4th param is an array with communication channel ids, ie. all modules with the same id can talk with each other #} {{ tc.module('Hero', 'mrterrific', ['Stealth'], ['talk'])}} {# the 5th param is the attrs object #} {{ tc.module('Hero', 'mrterrific', null, null, { ‘data-name’ : ‘Mr. Terrific‘})}} Remo Brunschwiler 10. July 2012 # 34
  • 38. Render Modules #2 Complex views ‣ the concept is – thanks to TWIG – very simple http://symfony.com/doc/current/book/ templating.html#embedding-controllers ‣ have their own controllers, actions & templates ‣ gives you Multi-MVC out-of-the-box ‣ are used rarely in plain “templating” projects {{ tc.module('Filter','Filter:overspeed', null, null, null, {'segment':'washing'})}} embeds the view of the FilterController/ the data passed to the overspeedAction in the Filter module overspeedAction Remo Brunschwiler 10. July 2012 # 35
  • 39. Hands on! Enhance your workshop page, so that… ‣ only two of the heroes can talk with each other ‣ the {title} is rendered inside the speech bubble of Einstein Remo Brunschwiler 10. July 2012 # 36
  • 40. Modules & Skins Get more flexibility…
  • 41. What we want to achieve Create a new «Victim» module, that… ‣ consists of a normal image (drowning man) & a background image (bubble) ‣ uses less for better code ‣ is able to call our heroes for help Remo Brunschwiler 10. July 2012 # 38
  • 42. Markup <div class="bubble"> <span class="message">help!</span> </div> <img src=" {{ asset("bundles/terrificmodulevictim/img/drowning-victim.png") }} "/> <a class="base" href="#help">Call for help!</a> links to image asset in /web/bundles/… But how is the drowning-victim.png got there? ‣ The composer copies all module images on the fly to /web/bundles/<bundle>/img/ (configurable in config_dev.yml) How did you come up with that path? ‣ Symfony standard: app/console assets:install Remo Brunschwiler 10. July 2012 # 39
  • 43. Import directive (mixins, variables etc.) /* import.less */ @import "colors.less"; @import "mixins.less"; /* colors.less */ @text: #74AE00; variable /* mixins.less*/ .scale(@ratio) { mixin function -webkit-transform: scale(@ratio); -moz-transform: scale(@ratio); -ms-transform: scale(@ratio); -o-transform: scale(@ratio); transform: scale(@ratio); } Remo Brunschwiler 10. July 2012 # 40
  • 44. /* @group Module: victim */ @import "../../../../../Composition/Resources/public/css/import.less"; @media screen { cascaded import – import.less has other imports .mod-victim { position: relative; .bubble { nested rules -> .mod-victim .bubble { … } background: transparent url('../bubble.png') no-repeat 0 0; ... } access variable relative to less file .message { color: @text; font-size: 36 / 16em; ... } calculation ... } } Remo Brunschwiler 10. July 2012 # 41
  • 45. There is even more to less! Have a look at the documentation ‣ http://lesscss.org Remo Brunschwiler 10. July 2012 # 42
  • 46. TerrificJS on:function (callback) { var self = this, $ctx = this.$ctx; $('a', $ctx).on('click', function() { var message = $('.message', $ctx).text(); self.fire('message', { name: 'drowner', message: message }); return false; }); callback(); } Nothing special here, but mention the new naming of the hooks in TerrificJS v2.0 Remo Brunschwiler 10. July 2012 # 43
  • 47. Hands on! Create a skin for your Victim that lets him drown when there is no help from one of the heroes ‣ Create skin “Drown” for your Victim ‣ Write a simple drown functionality (eg. fadeOut) ‣ Trigger this functionality automatically after ~5 seconds ‣ Do not let your Victim drown when he calls for help within the given time frame Remo Brunschwiler 10. July 2012 # 44
  • 48. Layouts Let’s say thanks to TWIG & Assetic
  • 49. Layouts A layouts job is to do stuff that is common to several pages ‣ javascripts ‣ styles ‣ meta tags ‣ header, footer, sidebar etc. Thanks to TWIG & Assetic, layouts are no longer a big & inflexible thing… Remo Brunschwiler 10. July 2012 # 46
  • 50. Twig Layout Approach In Twig a layout is nothing more than an inherited template ‣ http://symfony.com/doc/current/book/templating.html#template- inheritance-and-layouts In your page: this is your layout {% extends 'TerrificComposition::base.html.twig' %} {% block title %}Terrific Composer - Welcome{% endblock %} {% block body %} <div class="page"> … here comes your stuff … </div> {% endblock %} Remo Brunschwiler 10. July 2012 # 47
  • 51. Twig Layout Approach In TerrificComposition::base.html.twig {% extends 'TerrificCoreBundle::base.html.twig' %} Terrific Core Layout {% block title %}Terrific Composer{% endblock %} … {# content that is the same on every page goes into composition #} {% block composition %} {# your page content goes into body #} {% block body %} this block is overridden in your page {% endblock %} {% endblock %} … Remo Brunschwiler 10. July 2012 # 48
  • 52. Including JavaScripts Symfony comes bundled with a very nice Assetic integration Including JavaScripts has never been easier concatenates – and minifies in production {% block scripts %} mode – all files in this directory {# here comes your scripts #} {% javascripts '@TerrificComposition/Resources/public/js/*.*' output='js/compiled/statics.js' the name of the compiled file %} <script src="{{ asset_url }}" type="text/javascript"></script> {% endjavascripts %} {# scripts from parent (terrific core) layout #} {{ parent() }} includes the content of the parent block {% endblock %} Remo Brunschwiler 10. July 2012 # 49
  • 53. Including Stylesheets … and the same for stylesheets concatenates – and minifies in production mode – all of the given files {% block styles %} {% stylesheets '@TerrificComposition/Resources/public/css/reset.less' '@TerrificComposition/Resources/public/css/grid.less' '@TerrificComposition/Resources/public/css/elements.less' output="css/compiled/project.css" the name of the compiled file %} <link rel="stylesheet" href="{{ asset_url }}" /> {% endstylesheets %} {# styles from parent (terrific core) layout #} {{ parent() }} includes the content of the parent block {% endblock %} Remo Brunschwiler 10. July 2012 # 50
  • 54. Dev -> Prod Prepare your assets for the real world
  • 55. Productive The productive version is… ‣ available under / (instead of /app_dev.php) Dumping assets ‣ php app/console assets:install web Compile CSS / JS ‣ php app/console assetic:dump --env=prod Remo Brunschwiler 10. July 2012 # 52
  • 58. More… Lets keep talking ‣ http://terrifically.org ‣ remo@terrifically.org ‣ https://github.com/brunschgi ‣ http://twitter.com/#!/brunschgi Remo Brunschwiler 10. July 2012 # 55
  • 59. Remo Brunschwiler 10. July 2012 # 56