Professional Documents
Culture Documents
TEORA:
PHPcomnvs TWIG Herenciadeplantillas Filters (escapado!) Tags Assets (CSS,JS,IMGs) Internal linking (path) Internal linking conparmetros Internal linking urlsabsolutas(url) Debugging
EJERCICIOS:
Vistabsica Controladorbsicoypasodevariables Controladorquecuentanmerodeaccesos Controladorquemuestraunmensajeflashentrevisitaspares /curso/flashmessage Controladorquemuestracabeceras,informacindesesionesyRequest completo/curso/todo
84
Templating TIP:
TWIGsyntax highlight ennotepad++
Parafacilitarlaedicin,haremosquenotepad++tratelosarchivostwig comohtml,paraquehagaelhighlight delasintaxis. Paraelficheroactual:Cuandoestemoseditandoelarchivo,vamosa Lenguaje>H>HTML Paratodoslosficheros.html.twig:
Vista>Configuradordeestilo>HTML>yaadirlaextensintwig
TEMPLATING:TWIG
SYMFONYusaelsistemadetemplates TWIG: PHP
<!DOCTYPEhtml> <! this is the main template index.twig.html > <html> <head> <title>Welcome to Symfony!</title> </head> <body> <h1><?php echo strtoupper ($page_title) ?></h1> <ul id="navigation"> <?php foreach ($navigation as $item):?> <li> <ahref="<?php echo$item>getHref()?>"> <?php echo $item>getCaption()?> </a> </li> <?php endforeach;?> </ul> </body> </html> http://twig.sensiolabs.org/ <!DOCTYPEhtml> {#this is the main template index.twig.html #} <html> <head> <title>Welcome to Symfony!</title> </head> <body> <h1>{{page_title|upper }}</h1> <ul id="navigation"> {%for item innavigation %} <li> <ahref="{{item.href }}">{{item.caption }}</a> </li> {%endfor %} </ul> </body> </html>
TEMPLATING:herencia
LayoutBASE
<!DOCTYPEhtml> {#this is the main template src/curso/EjemploBundle/Resources/views/Default/index.twig.html #} <html> <head> <title>Welcome to Symfony!</title> </head> <body> <h1>{{page_title|upper }}</h1> <ul id="navigation"> {%for item innavigation %} <li> <ahref="{{item.href }}">{{item.caption }}</a> </li> {%endfor %} </ul> {%block content %} //REWRITEME! {%endblock content %} </body> </html>
Layoutqueheredaeincluye
{#src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #} {%extends EjemploBundle::index.html.twig"%} {#elcontenidoser igualqueindex.html.twig salvoelbloquecontent #} {%block content %} {%enelbloquecontent voyaincluirunaplantilla%} {%include "AcmeDemoBundle:Demo:embedded.html.twig"%} {%endblock %}
Se permite la herencia entre plantillas (incluso de distintos Bundles) Se permite inclusin de otras plantillas (incluso de distintos Bundles) FLEXIBLE. POTENTE. ESTRUCTURADO. Ojo en produccin
87
TEMPLATING:FILTERS
date:da formato tipo fecha. Ejemplos:
{{"Ilike %sand %s."|format(foo,"bar")}}
http://twig.sensiolabs.org/doc/tags/index.html
{{post.published_at|date("m/d/Y")}}{{"now"|date("m/d/Y")}}
format:reemplaza placeholders con valores de las variables. Ejemplo: la siguiente lnea dar como resultado I like foo and bar si la var foo==foo replace:Similar a format. Ejemplo:
{{"Ilike %this%and %that%."|replace({'%this%':foo,'%that%':"bar"})}} {{9800.333|number_format(2,',','.')}}
number_format:Formateo de nmeros: decimales, separador decimal y separador de miles url_encode:Aplica la funcin urlencode de php {{data|url_encode()}} title
{{'myfirst car'|title }}{#outputs 'MyFirst Car'#} {{'myfirst car'|capitalize }}{#outputs 'Myfirst car'#}
capitalize
nl2br{{"Ilike upper
Twig.\nYou will like it too."|nl2br }}{#outputs Ilike Twig.<br/>You will like it too.#}
striptags:Ejecutastriptags
default:el valor de var o var is not defined si var no est definida reverse:{{'1234'|reverse
}}{#outputs 4321#}
** por defecto est en entorno {%autoescape true %}por lo que NO es necesario escapar las variables.
raw:para evitar el autoescapado de caracteres. P ejemplo:{{enlace|default(<ahref=/anotherpage.html>click!</a>>)|raw)}} slice:tomar una parte (como array_slice para arrays y substr para cadenas). Admite notacin abreviada
{{'1234'[1:2]}} {{'1234'|slice(1,2)}}{#outputs 23#}
88
TEMPLATING:escapado
Cuando segeneraHTMLdesde una plantilla existe elriesgo deque una variabledelaplantilla pueda contener HTMLo cdigo javascript nocontrolado.Elresultado es que lapgina serenderizara malo,aun peor,lleve aunataque deXSS (CrossSiteScripting). Por ejemplo:
Hello{{name}}
89
TEMPLATING:ejercicioV0
Realizar la plantilla ejercicioV0.html.twig usando variables y valores por defecto. Los mnimos:
- cabecera que contenga el $titulo de la pgina, -barra de mens ($menu) y zona para el $contenido -$pie: para informacin de copyright, fecha
BSICO:PlantillabsicaconseparacinCSS/HTMLendosficheros:http://dl.dropbox.com/u/11088509/templates/template4_sinImgs_MUY_SIMPLE.zip MEDIO:PlantillabsicaconseparacinCSS/HTMLeimgenes:http://dl.dropbox.com/u/11088509/templates/template3_sinImgs.zip
Si el layout elegido tiene CSS o IMGS, crea en c:\wamp2.2\www\ las carpetas IMGyCSSy mete all los CSS e IMGS asociados. Ms adelante veremos cmo gestionar este tipo de ASSETS de una forma ms elegante. Si el layout tiene CSS, comprmelo usando http://www.csscompressor.com/ y observa los tiempos de carga con HttpWatch.
90
TEMPLATING:TAGSejercicio
Siincluimosnicamentevariablesyfilters,tenemosunaSOLUCIN quefunciona,peronoesdemasiadotil(salvoquenuestroproyecto seamuypequeo)
Qu sucedera si quisiramos hacer herencia de plantillas? Con la solucin de arriba, complicado. UsaremosBLOQUES.
91
TEMPLATING:TAGS
block yextends sirven para gesionar la HERENCIA de plantillas. Por
ejemplo, podemos tomar el siguiente como base.html.twig y derivar otras plantillas a partir de esta. Definimos en la plantilla padre (base.html.twig) cuatro bloques que sus plantillas derivadas podrn sobreescribir. <!DOCTYPEhtml> <html> <head> {%block head %} <linkrel="stylesheet"href="style.css"/> <title>{%block title %}{%endblock %} MyWebpage</title> {%endblock %} </head> <body> <div id="content">{%block content %}{%endblock %}</div> <div id="footer"> {%block footer %} ©Copyright2011by<ahref="http://domain.invalid/">you</a>. {%endblock %} </div> </body> </html>
http://twig.sensiolabs.org/doc/tags/index.html
{%extends "base.html"%} {%block title %}Index{%endblock %} {%block head %} {{parent()}} <style type="text/css"> .important {color:#336699;} </style> {%endblock %} {%block content %} <h1>Index</h1> <pclass="important"> Welcome on myawesome homepage. </p> {%endblock content%}
extends debe ser lo primero que aparezca en plantillas heredadas parent()devuelve lo mismo que devolva la funcin padre Para repetir el contenido de un bloque podemos invocar a block(nombrebloque) Se permite terminar el bloque con endblock endblock nombrebloque (por motivos de legibilidad)
92
TEMPLATING:TAGS
for
:similar al bucle for en php: {%for user inusers %} <li>{{user.username|e }}</li> {%endfor %} No tiene break/continue, pero s de evitar ciertos elementos: {%for user inusers if user.active %} <li>{{user.username|e }}</li> {%endfor %} Tambin opcin de else por si no se puede iterar {%for user inusers %} <li>{{user.username|e }}</li> {%else %} <li><em>nouser found</em></li> {%endfor %} Se puede iterar sobre las claves de un vector {%for key inusers|keys %} <li>{{key }}</li> {%endfor %} Y sobre las claves y valores... {%for key,user inusers %} <li>{{key }}:{{user.username|e }}</li> {%endfor %}
http://twig.sensiolabs.org/doc/tags/index.html
OJO CON LAS VARIABLES NO DEFINIDAS (DISTINTO DE VACAS!). Hay que controlarlas... (if varname is defined )
93
TEMPLATING:TAGS
http://twig.sensiolabs.org/doc/tags/index.html
Lostags bsicosquedebesconocersonlossubrayados
if
condicional habitual {%if kenny.sick %} Kennyis sick. {%elseif kenny.dead %} You killed Kenny!You bastard!!! {%else %} Kennylooksokay sofar {%endif %}
macro similares a las funciones en los lenguajes de programacin usuales. Por ejemplo:
{%macroinput(name,value,type,size)%} <input type="{{type|default('text')}}"name="{{name }}"value="{{value|e }}"size="{{size|default(20)}}"/> {%endmacro %}
import
importar macros, plantillas o elementos en otros ficheros. {%import "forms.html"asforms %} <p>{{forms.input('username')}}</p> <p>{{forms.input('password',null,'password')}}</p>
from
set asignar valor a variables DENTRO de twig (en templates). Incluso se pueden asignar trozos de texto:
{%setfoo =[1,2]%} {%setfoo %}<div id="pagination">...</div>{%endset %}
94
TEMPLATING:TAGS
include incluir en el namespace actual elementos de otras plantillas
{%include 'header.html'%}Body{%include 'footer.html'%}
http://twig.sensiolabs.org/doc/tags/index.html
raw partes que no deben ser parseadas (texto que saldr tal cual lo escribamos) use herencias horizontales y multiherencia (avanzado). spaceless eliminar espacios ENTRE ETIQUETAS HTML.
{%spaceless %} <div> <strong>foo</strong> </div> {%endspaceless %} {#outputwill be<div><strong>foo</strong></div>#}
flush vaciar los bufferes de salida do como {{...}}pero sin print de nada {%do1+2%}
95
TWIG:Herencia(I)
Podemossobreescribir bloques yadefinidos,aadirnuevos,incluirotros {#src/curso/e5Bundle/Resources/views/Default/plantillaPadre.html.twig #} {{block header }} {{block title }} <title>{{title|default(CursoSymfony)}} {{endblock title }} {{endblock header }}
{#src/curso/e5Bundle/Resources/views/Default/plantillaHija.html.twig #} {%extends "cursoe5Bundle:Default:plantillaPadre.html.twig"%} {{block header }} {{block title }} <title>{{title|default(AdministradorCursoSymfony)}} {{endblock title }} {{block metadescription }} ... {{endblock metadescription }} ... {%include 'cursoe5Bundle:Default:MySidebar.html.twig'%} {{endblock header }}
TWIG:Herencia(II)
Einclusorepetirelcontenidodeunbloqueenvariaszonasdelcdigousandolafuncin block(nombredelblock)
<title>{{block title }}{{titulo|default(Sintitulo)}}{{endblock title }}</title> ... <h1>{{block(title')}}</h1> <! repetir,dentrodeunH1,elcontenidodelblock title >
Osobreescribir bloquesdelpadre,aadiendocosas
{%extends "base.html"%} {%block title %}Index{%endblock %} {%block head %} {{parent()}} {#quierotodolodelhead delpadre yms!#} <style type="text/css">.important {color:#336699;}</style> {%endblock %}
TEMPLATING:espaciosysaltosdelnea>PERTAGCONTROL
http://twig.sensiolabs.org/doc/templates.html#whitespacecontrol
$keywords=array("keywordwithspaces1","keyword2","keyword3");
CODE
<! DELETEME> <div id="milista"> {%for kw inkeywords %} {{kw }}, {%endfor %} </div> <! /DELETEME>
OUTPUT
<! DELETEME> <div id="milista"> keyword with spaces 1, keyword2, keyword3, </div> <! /DELETEME>
<! DELETEME> <div id="milista"> {%for kw inkeywords %} {{ kw }}, {%endfor %} </div> <! /DELETEME>
<! DELETEME> <div id="milista"> keyword with spaces 1, keyword2, keyword3, </div> <! /DELETEME>
<! DELETEME> <div id="milista"> {% for kw inkeywords %} {{ kw }}, {% endfor %} </div> <! /DELETEME>
98
TEMPLATING:TAGSejercicio
Partiendodelejemploanterior(ejercicioV0.html.twig), convertirloaunaplantillabase(ejercicioV1.html.twig) conlosbloquesHEAD,TITULO,MENU,DESCRIPTION, KEYWORDS,CONTENIDOyESTILO.Laskeywords sepasarn comounarrayynohabr saltodelneaentreellas. Crearunaplantillaheredada(ejercicioV2.html.twig)enla quenosemuestreningnmen yhayaunnuevobloque llamadostylesheets dentrodelbloqueheader)
99
TEMPLATING:ASSETS
Ningnsitioweb actualprescindedelusodeCSS,JSeimgenes.EnTWIG,podemosincluirdirectamentelasrutas absolutasdelasimgenes,css ojs.Porejemplo,siguardamosestasen$DOCUMENTROOT/imagenes/*, procederemos: <img src=/imagenes/logo.png /> Pero,sitenemosvariosproyectos(oversionesdelmismo),todaslasimgenesestaranmezcladasenunamisma carpeta,loquecomplicalagestin.Adems,espocoflexible(sicambioel$DOCUMENTROOT,tengoque cambiartodaslasURLs) Lafuncinasset nosabstraealgomsdelpath fsicoypermitequeguardemoslosassets juntoalproyecto(en Resources/Views/public),deformaqueunaposiblemigracinfueramssimple.
<img src="{{asset(bundles/vendorbundlename/images/logo.png')}}"alt="Symfony!"/>
100
TEMPLATING:EjercicioASSETS
Modificatuplantilla paraincluirficheroCSSexternoyeliminaelbloquedeestilos anterior
{%block estilo%} <linkhref="{{asset('bundles/cursoe5/css/ejercicioV2.css')}}"rel="stylesheet"type="text/css"/> {%endblock estilo%}
CreaelficheroCSSen Ejecuta:
101
TEMPLATING:ASSETS
LagestindeAssets funcionacorrectamente,peroresultainsuficienteenproyectosmedio/grandes.Symfony ofrece unaformamsavanzadadegestionarAssets:ASSETIC.
102
TEMPLATING:Assetic
{%javascripts '@AcmeFooBundle/Resources/public/js/jquery1.7min.js '@AcmeFooBundle/Resources/public/js/myfunction.js' %} <scripttype="text/javascript" src="{{asset_url }}"></script> <scriptsrc="/app_dev.php/js/abcd123.js"></script> {%endjavascripts %}
103
TEMPLATING:Assetic
MecanismodecontroldeURL (virtualenDEV,realenPROD).
{%stylesheets '@cursoe5Bundle/Resources/public/css/layout/mainStyle.css' '@cursoe5Bundle/Resources/public/css/layout/reset.css' '@cursoe5Bundle/Resources/public/css/layout/colors.css' %} <linkhref="{{asset_url }}" type="text/css"rel="stylesheet"media="screen"/> {%endstylesheets %} <linkhref="/Symfony/web/app_dev.php/css/fc5783b_mainStyle_1.css"type="text/css"rel="stylesheet"media="screen"/> <linkhref="/Symfony/web/app_dev.php/css/fc5783b_reset_2.css"type="text/css"rel="stylesheet"media="screen"/> <linkhref="/Symfony/web/app_dev.php/css/fc5783b_colors_3.css"type="text/css"rel="stylesheet"media="screen"/>
{%stylesheets '@cursoe5Bundle/Resources/public/css/layout/mainStyle.css' '@cursoe5Bundle/Resources/public/css/layout/reset.css' '@cursoe5Bundle/Resources/public/css/layout/colors.css' output='styles/compiled/styles.css' %} <linkhref="{{asset_url }}" type="text/css"rel="stylesheet"media="screen"/> {%endstylesheets %} <linkhref="/Symfony/web/app_dev.php/css/compiled/styles_mainStyle_1.css"type="text/css"rel="stylesheet"media="screen"/> <linkhref="/Symfony/web/app_dev.php/css/compiled/styles_reset_2.css"type="text/css"rel="stylesheet"media="screen"/> <linkhref="/Symfony/web/app_dev.php/css/compiled/styles_colors_3.css"type="text/css"rel="stylesheet"media="screen"/>
104
TEMPLATING:Assetic
Desarrollo:Assetic generarutasquenoexistenfsicamente.
Symfony losabreinternamentedesulocalizacinfsicarealysirveel contenido(despusdeejecutarlosfiltros),esdecir,lossirvedeforma dinmica.Laventajaesquepuedesverinmediatamenteelestadodelos activosquecambies.Ladesventajaeslalentitud(mximecuandoelnmero defiltroscrece)(yproblemassiborrasC:\Windows\Temp\ )
Produccin:Enentornodeproduccinnopodemospermitirnosla
lentitud.Hayquerealizarelvolcadodeassets cadavezquedesplieguesla aplicacinenelentornodeproduccin(php app/console assetic:dump env=prod nodebug).Estogenerayescribe fsicamentelosarchivosnecesitados.Siactualizastusarchivos,debers ejecutarlonuevamente.
105
TEMPLATING:Assetic
{%stylesheets '@cursoe5Bundle/Resources/public/css/layout/mainStyle.css' '@cursoe5Bundle/Resources/public/css/layout/reset.css' '@cursoe5Bundle/Resources/public/css/layout/colors.css' output='css/compiled/styles.css filter ='yui_css' %} <linkhref="{{asset_url }}"type="text/css"rel="stylesheet"media="screen"/> {%endstylesheets %} {%endblock styles %}
106
TEMPLATING:EjercicioAssetic
Crearlarutayelcontroladorparaqueen/ejercicioV4 serenderice lasiguienteplantilla
ModificarlaplantillaejercicioV4.html.twig siguienteparaevitarelusodeasset() yutilizarAssetic
<!DOCTYPEhtml PUBLIC"//W3C//DTDXHTML1.0Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"dir="ltr"lang=esES"> <head> <title>CursoSymfony ejercicioV4</title> <linkhref="{{asset('bundles/cursoe5/css/ejercicioV4.css')}}"type="text/css" rel="stylesheet"media="screen"/> </head> <body> Sitodohaidobien,elfondodebesernegro.Yestaletra,blanca. </body> </html>
UtilizaelsiguienteficheroejercicioV4.css quedebesguardaren
src\curso\e5Bundle\Resources\public\css\ejerciciov4.css body{background:#000;color:#FFF}
Recuerdaelcomandoparahacereldump deAssetic:
[php app/console cache:clear] php app/console [env=dev]assetic:dump [nodebug]
SiASSETICtedaproblemas,sigueelpaso3(y,opcionalmente,el4)de
http://www.leccionespracticas.com/informaticaweb/symfonyyuicsscompressionwithasseticonwindowswamp systemssolved/
107
TEMPLATING:EjercicioAssetic
Ejemploutilizacindefiltros[avanzado] Descarga:http://www.leccionespracticas.com/ejercicioV5.zip Descomprimeycolocalosarchivos(dentrodetuproyecto,enlacarpetasrc/curso/e5Bundle/Resources>public paraimgs,css,js yResources>View paraelfich .html.twig) Siguelasinstruccionesdehttp://www.leccionespracticas.com/informaticaweb/symfonyyuicsscompression withasseticonwindowswampsystemssolved/ paraquefuncioneelfiltroyui_css Crealarutayelcontroladornecesariosparaquerespondana/ejercicioV5
Sialejecutarphp app/console assetic:dump terminasinfallosperonofunciona,limpialacache(php app/console cache:clear).Siusaswindows esprobablequetengasquedarpermisosalusuarioactualparaescribiren app/cacheyapp/logs (botnderechosobrelacarpeta,Propiedades>Seguridad>Editar>Controltotalparael usuarioqueestemosusando).
108
TEMPLATING:internal linking
Unadelastareasmscomunesencualquiersite consisteencrearenlacesparaqueelvisitantepuedanavegarentrelaspginas. EnvezdemeterURLs directamenteenlasplantillas,usaremoslafuncinpath deTwig paragenerarlasURLs basndonosenla configuracinderutas.Ventajas?Sideseascambiarlaurl deunapginaenconcreto,solodeberscambiarlaconfiguracin delasrutasylostemplates automticamentegenerarnlasURLs correctas. DOSFUNCIONES: (1)path: (2)url:
generaURLRELATIVA generaURLABSOLUTA
109
TEMPLATING:internal linking
*EJERCICIO*:modificar elfichero derutas para que nuestra pgina principalcargue en/curso/nuevo en lugar de/curso ycomprobar cmo las rutas delos breadcrumbsfuncionan bien...
110
111
TEMPLATING:debugging
{{dump(articles)}}~similaravar_dump(articles)
Ejemplo:
{#src/Acme/ArticleBundle/Resources/views/Article/recentList.html.twig #} {{dump(articles)}} {%for article inarticles %} <ahref="/article/{{article.slug }}"> {{article.title }} </a> {%endfor %}
enPHP
Hayqueactivarloexplcitamenteenlacfg
#app/config/config.yml services: acme_hello.twig.extension.debug: class:Twig_Extension_Debug tags: {name:'twig.extension'}
112