Makes your life easier…
Terrific Composer
Remo Brunschwiler 10. July 2012 #
Agenda
Concept
Terrific Composer
‣ Installation
‣ Twig
‣ Pages
‣ Modules & Skins
‣ Layout
‣ Dev -> Prod
3
GithubTake it. Make it better. Together.
Remo Brunschwiler 10. July 2012 #
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
5
ShowcasesSee Terrific in action
Remo Brunschwiler 14. August 2012 # 7
It’s really easy…
Concept
#Remo Brunschwiler
Hold on a minute!
9
Before we dive deeper into the Terrific Composer…
#Remo Brunschwiler
Hold on a minute!
9
Before we dive deeper into the Terrific Composer…
Lets refresh our Terrific knowledge!http://www.slideshare.net/brunschgi/terrific-frontends
Terrific ComposerMakes your life easier…
Remo Brunschwiler 10. July 2012 #
Terrific Composer
Frontend Development Framework
‣ Designed for building frontends / applications based on the Terrific concept
‣ Integrates TerrificJS
‣ Based on Symfony
‣ … still very young
11
Remo Brunschwiler 10. July 2012 #
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!
11
Remo Brunschwiler 10. July 2012 #
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
12
InstallationVery fast setup for your project!
Remo Brunschwiler 10. July 2012 #
Installation
14
Download it from: http://terrifically.org/composer/
Explore… the sidebar and their possibilities
Remo Brunschwiler 10. July 2012 #
Add new Modules & Skins to your project. The Skeleton is generated for you so that you can start right away.
16
Create
Remo Brunschwiler 10. July 2012 #
The Open dialog provides you fast access to all of your Modules and Pages.
17
Open
Remo Brunschwiler 10. July 2012 #
The inspect mode shows you which modules are in use on the current page.
18
Inspect
TwigThe flexible, fast, and secure template engine for PHP
Remo Brunschwiler 10. July 2012 #
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 :-)
20
Remo Brunschwiler 10. July 2012 #
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
21
Hands on!Terrific Composer – Step by Step
Remo Brunschwiler 10. July 2012 #
Step by Step
Common Tasks
‣ Create a new page
‣ Create a new Module / Skin
‣ Create a new layout
‣ Development -> Productive
23
PagesPlay Lego!
Remo Brunschwiler 10. July 2012 #
… Let’s see it in action
25
Remo Brunschwiler 10. July 2012 #
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/
26
Remo Brunschwiler 10. July 2012 #
1. Create / Extend Controller
<?phpnamespace Terrific\Composition\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Terrific\ComposerBundle\Annotation\Composer;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
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
27
Remo Brunschwiler 10. July 2012 #
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()
28
Remo Brunschwiler 10. July 2012 #
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)
29
Remo Brunschwiler 10. July 2012 #
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
30
Remo Brunschwiler 10. July 2012 #
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
31
Remo Brunschwiler 10. July 2012 #
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
32
Remo Brunschwiler 10. July 2012 #
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
32
Remo Brunschwiler 10. July 2012 #
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
33
Remo Brunschwiler 10. July 2012 #
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‘})}}
34
Remo Brunschwiler 10. July 2012 #
Render Modules #2
Complex views
‣ the concept is – thanks to TWIG – very simplehttp://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'})}}
35
embeds the view of the FilterController/overspeedAction in the Filter module
the data passed to the overspeedAction
Remo Brunschwiler 10. July 2012 #
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
36
Modules & SkinsGet more flexibility…
Remo Brunschwiler 10. July 2012 #
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
What we want to achieve
38
Remo Brunschwiler 10. July 2012 #
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>
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
39
links to image asset in /web/bundles/…
Remo Brunschwiler 10. July 2012 #
Import directive (mixins, variables etc.)/* import.less */@import "colors.less";@import "mixins.less";
/* colors.less */@text: #74AE00;
/* mixins.less*/.scale(@ratio) { -webkit-transform: scale(@ratio); -moz-transform: scale(@ratio); -ms-transform: scale(@ratio); -o-transform: scale(@ratio); transform: scale(@ratio);}
40
variable
mixin function
Remo Brunschwiler 10. July 2012 #
/* @group Module: victim */@import "../../../../../Composition/Resources/public/css/import.less";
@media screen { .mod-victim { position: relative;
.bubble { background: transparent url('../bubble.png') no-repeat 0 0; ... }
.message { color: @text; font-size: 36 / 16em; ... }
... }}
41
cascaded import – import.less has other imports
nested rules -> .mod-victim .bubble { … }
access variable
calculation
relative to less file
Remo Brunschwiler 10. July 2012 # 42
There is even more to less! Have a look at the documentation
‣ http://lesscss.org
Remo Brunschwiler 10. July 2012 #
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
43
Remo Brunschwiler 10. July 2012 #
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
44
LayoutsLet’s say thanks to TWIG & Assetic
Remo Brunschwiler 10. July 2012 #
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…
46
Remo Brunschwiler 10. July 2012 #
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:
{% extends 'TerrificComposition::base.html.twig' %}
{% block title %}Terrific Composer - Welcome{% endblock %}
{% block body %}<div class="page"> … here comes your stuff …</div>{% endblock %}
47
this is your layout
Remo Brunschwiler 10. July 2012 #
Twig Layout Approach
In TerrificComposition::base.html.twig
{% extends 'TerrificCoreBundle::base.html.twig' %}
{% 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 %}{% endblock %}
{% endblock %}…
48
Terrific Core Layout
this block is overridden in your page
Remo Brunschwiler 10. July 2012 #
Including JavaScripts
Symfony comes bundled with a very nice Assetic integration
Including JavaScripts has never been easier
{% block scripts %} {# here comes your scripts #} {% javascripts '@TerrificComposition/Resources/public/js/*.*' output='js/compiled/statics.js' %} <script src="{{ asset_url }}" type="text/javascript"></script> {% endjavascripts %} {# scripts from parent (terrific core) layout #} {{ parent() }}{% endblock %}
49
concatenates – and minifies in production mode – all files in this directory
the name of the compiled file
includes the content of the parent block
Remo Brunschwiler 10. July 2012 #
Including Stylesheets
… and the same for stylesheets
{% 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" %} <link rel="stylesheet" href="{{ asset_url }}" /> {% endstylesheets %}
{# styles from parent (terrific core) layout #} {{ parent() }}{% endblock %}
50
concatenates – and minifies in production mode – all of the given files
the name of the compiled file
includes the content of the parent block
Dev -> ProdPrepare your assets for the real world
Remo Brunschwiler 10. July 2012 #
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
52
Questions?
More…
Remo Brunschwiler 10. July 2012 #
More…
Lets keep talking
‣ http://terrifically.org
‣ https://github.com/brunschgi
‣ http://twitter.com/#!/brunschgi
55
Remo Brunschwiler 10. July 2012 # 56
Thank you!
Top Related