Sei sulla pagina 1di 23

Manual simple de Symfony en castellano

Creacin de pginas en Symfony2


1) Antes de empezar, lo primero es crear un BUNDLE
Un bundle no es nada ms que un directorio que alberga todo lo relacionado con una caracterstica
especica, inclu!endo las clases de "#", la coniguraci$n, e incluso %o&as de estilo ! los arc%i'os
(a'a)cript
"ara crear un paquete llamado AcmeHelloBundle *un paquete que usted 'a a construir en
este captulo), e&ecute el comando siguiente ! siga las instrucciones que aparecen en pantalla
*utilizar todas las opciones por deecto)+
php app / generate consola: paquete - namespace = Acme / HelloBundle - format = yml
,on este comando se crea el directorio+
src-Acme-#elloBundle
. se a/ade una lnea al arc%i'o app-App0ernel1p%p para que el bundle - paquete se registre con el
0ernel1
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Acme\HelloBundle\AcmeHelloBundle(),
);
// ...
return $bundles;
}
Creacin de una pgina en Symfony2
)on s$lo 2 pasos+
2) ,rear un camino o ruta+ una ruta deine una U3L *e&+ -about) a tu pgina ! especiica un
controlador que s!mon!2 e&ecutar cuando la U3L de petici$n coincida con la ruta padre1
"or deecto la coniguraci$n de rutas en las aplicaciones )!mon!2 est en+
app/config/routing.yml1 *se puede escoger e4tensi$n "#", o 56L)
,uando se %a creado el Bundle o paquete, en este arc%i'o se %a a/adido las siguientes
lineas+
7 app-conig-routing1!ml
AcmeelloBundle!
resource! "#AcmeelloBundle/$esources/config/routing.yml"
prefi%! /
En la lnea resource se indica el camino de la coniguraci$n de enrutamiento de dentro del
bundle Acme#elloBundle1 *src-Acme-#elloBundle-3esources-conig-routing1!ml)
El contenido de este arc%i'o es el siguiente en este caso+
7 src-Acme-#elloBundle-3esources-conig-routing1!ml
hello!
pattern! /hello/{name&
defaults! { 'controller! AcmeelloBundle!ello!inde% &
pattern! es la ($) *ue la ruta e+ecutar,. {name& es un par,metro de la ($).
-efaults! especifica el controlador *ue ser, e+ecutado.
8) ,rear un controlador+ es una unci$n "#" que recoge las peticiones de entrada ! la
transorma en un ob&eto 3E)"9N)E de )!mon!2 que se de'uel'e al usuario1
El controlador : Acme#elloBundle+ #ello+inde4 es el nombre l$gico del controlador, ! se
asigna al m;todo inde4Action de una clase "#" llamado Acme < #elloBundle <
,ontrolador < #ello1
-- src-Acme-#elloBundle-,ontroller-#ello,ontroller1p%p
namespace Acme.elloBundle./ontroller;
use 0ymfony./omponent.ttp1oundation.$esponse;
class ello/ontroller
{
public function inde%Action($name)
{
return ne2 $esponse(34html54body5ello 3.$name.364/body54/html53);
&
&
El controlador es simple+ se crea un nue'o ob&eto de respuesta, cu!o primer argumento es el
contenido que se debe utilizar en la respuesta *una peque/a pgina #=6L en este e&emplo)1
>?elicitaciones@ Despu;s de crear s$lo una ruta ! un controlador, que !a tiene una pgina
completamente uncional@ )i usted tiene todo lo conigurado correctamente, la aplicaci$n
debe darle la bien'enida+
%ttp+--local%ost-appAde'1p%p-%ello-3!an
B) "aso opcional+ crear un template1
El template te permite mo'er toda la presentaci$n *e&+ c$digo #=6L) en un arc%i'o
separado ! reusarlo1 En lugar de escribir el #=6L dentro del controlador, se renderiza una
template1
-- src-Acme-#elloBundle-,ontroller-#ello,ontroller1p%p
namespace Acme.elloBundle./ontroller;
use 0ymfony.Bundle.1rame2or7Bundle./ontroller./ontroller;
class ello/ontroller e%tends /ontroller
{
public function inde%Action($name)
{
return $this85render(3AcmeelloBundle!ello!inde%.html.t2ig39
array(3name3 =5 $name));
// render a :: template instead
// return $this85render(3AcmeelloBundle!ello!inde%.html.php39
array(3name3 =5 $name));
&
&
El m;todo render *) crea un ob&eto de respuesta rellleno con el contenido de la template
renderizada1 Al igual que cualquier otro controlador, que en Cltima instancia 'a a de'ol'er
ese ob&eto 3esponse1

El controlador renderiza la template Acme#elloBundle-#ello-inde41%tml1tDig , el cual usa la
siguiente con'enci$n de nombres+
BundleName+ControllerName+TemplateName
Este es el nombre l$gico de la template, el cual es mapeado en la localizaci$n sica+
/path/to/BundleName-3esources-'ieDs-ControllerName-TemplateName
En este caso+
Acme#elloBundle es el nombre del bundle1
#ello es el controlador1
Ende41%tml1tDig es la template - plantilla1
F7 src-Acme-#elloBundle-3esources-'ieDs-#ello-inde41%tml1tDig 7G
{; e%tends 3!!base.html.t2ig3 ;&
{; bloc7 body ;&
ello {{ name &&6
{; endbloc7 ;&
Tareas comunes del controlador
Redireccion ( mtodo redirect() )
Para redirigir al usuario a otra pgina.
public function inde%Action()
{
return $this85redirect($this85generate(rl(3homepage3));
&
<l m=todo generate(rl es una funci>n *ue genera la ($) de una ruta dada.
:or defecto el m=todo redirect() e+ecuta un redirect ?@A (temporal) . :ara
e+ecutar un redirect ?@B (permanente) se modifica el segundo argumento.
public function inde%Action()
{
return $this85redirect($this85generate(rl(3homepage3)9 ?@B);
&
orwarding()
!irigir a otro controlador con el mtodo "orward() #ue de$uel$e el o%&eto
respuesta #ue de$uel$e ese controlador.
'&(
public function inde%Action($name)
{
$response = $this85for2ard(3AcmeelloBundle!ello!fancy39 array(
3name3 =5 $name9
3color3 =5 3green3
));
// further modify the response or return it directly
return $response;
&
Renderi)ar plantillas
'l mtodo render*iew() renderi)a una plantilla + de$uel$e su contenido.
'l contenido de la template puede ser usado para crear un o%&eto Response.
'&(
$content = $this85renderCie2(3AcmeelloBundle!ello!inde%.html.t2ig39
array(3name3 =5 $name));
return ne2 $esponse($content);
> en una lDnea!
return $this85render(3AcmeelloBundle!ello!inde%.html.t2ig39 array(3name3 =5
$name));
<n ambos casos9 la template $esources/Eie2s/ello/inde%.html.t2ig de
AcmeelloBundle ser, renderiFada.
Accediendo a otros ser$icios
$re*uest = $this85get$e*uest();
$templating = $this85get(3templating3);
$router = $this85get(3router3);
$mailer = $this85get(3mailer3);
:ara Eer la lista de los serEicios habilitados!
php app/console container!debug
,estionando errores + pginas -.- (pginas no encontradas)
/uando no se encuentra algun recurso9 se debe deEolEer una respuesta del tipo
G@G. :ara hacer esto9 se lanFa una e%cepci>n especial.
public function inde%Action()
{
$product = // retrieEe the ob+ect from database
if (6$product) {
thro2 /t0is12create3otound'4ception(3Hhe product does not e%ist3);
&
return $this85render(...);
&
<l m=todo createIot1ound<%ception() crea un ob+eto especial
Iot1oundttp<%ception9 el cu,l lanFar, triggers G@G HH: response dentro de
0ymfony.
,estionando sesiones
0ymfonyA proEee un ob+eto agradable de sesi>n *ue se puede utiliFar para
almacenar informaci>n del usuario entre peticiones.
:or defecto9 0ymfonyA almacena los atributos en una coo7ie usando las sesiones
:: natiEas.
<+emplo de codigo en un controlador!
$session = $this85get$e*uest()85get0ession();
// store an attribute for reuse during a later user re*uest
$session85set(3foo39 3bar3);
// in another controller for another re*uest
$foo = $session85get(3foo3);
// set the user locale
$session85set)ocale(3fr3);
5ensa&es 6A7H(
:uedes almacenar pe*ueJos mensa+es *ue ser,n guardados en la sesi>n del usuario
para una petici>n adicional.
<sto es muy Ktil cuando se procesa un formulario9 cuando *uieres redirigir y
mostrar un mensa+e especial en la siguiente petici>n.
<ste tipo de mensa+es se llaman mensa+es 1)A0.
Lmagina *ue est,s procesando el enEDo de un formulario!
public function updateAction()
{
$form = $this85create1orm(...);
$form85bind$e*uest($this85get$e*uest());
if ($form85isCalid()) {
// do some sort of processing
$this85get(3session3)85set1lash(3notice39 3Mour changes 2ere saEed63);
return $this85redirect($this85generate(rl(...));
&
return $this85render(...);
&
<l nombre 3notice3 no es importante9 se utiliFa para identificar el tipo de
mensa+e.
<n la plantilla de la siguiente acci>n9 el siguiente c>digo podrDa ser usado para
renderiFar el mensa+e 3noticia3
{; if app.session.has1lash(3notice3) ;&
4diE class="flash8notice"5
{{ app.session.flash(3notice3) &&
4/diE5
{; endif ;&
'l o%&eto R'7P837'
<l Knico re*uisito para un controlador es deEolEer un ob+eto $<0:NI0<.
)a clase $<0:NI0< es una abstraccion :: de la respuesta HH:.
// create a simple $esponse 2ith a A@@ status code (the default)
$response = ne2 $esponse(3ello 3.$name9 A@@);
// create a O0NI8response 2ith a A@@ status code
$response = ne2 $esponse(+son'encode(array(3name3 =5 $name)));
$response85headers85set(3/ontent8Hype39 3application/+son3);
'l o%&eto R'9:'7T
<l controlador tambi=n tiene acceso al ob+eto $e*uest cuando e%tiende la clase
base /ontroller.
$re*uest = $this85get$e*uest();
$re*uest85isPmlttp$e*uest(); // is it an A+a% re*uestQ
$re*uest85get:referred)anguage(array(3en39 3fr3));
$re*uest85*uery85get(3page3); // get a $'R<H parameter
$re*uest85re*uest85get(3page3); // get a $':N0H parameter

Routing
0ymfonyA te permite definir ($)0 *ue mapean diferentes ,reas de tu aplicaci>n.
Routing en acci;n
(na ruta es un mapa a partir de un modelo de direcci>n ($) a un controlador. :or
e+emplo9 supongamos *ue usted *uiere para adaptarse a cual*uier ($) como
/blog/my8post o /blog/all8about8symfony y lo enEDa a un controlador *ue puede
mirar para arriba y renderiFar esa entrada de blog. )a ruta es simple!
S app/config/routing.yml
blog'sho2!
pattern! /blog/{slug&
defaults! { 'controller! AcmeBlogBundle!Blog!sho2 &
<l modelo definido por el pattern blog'sho2 actKa como /blog/T9 donde el comodDn
es dado por el nombre UslugV.
Controlador dado en defaults:
// src/Acme/BlogBundle//ontroller/Blog/ontroller.php
namespace Acme.BlogBundle./ontroller;
use 0ymfony.Bundle.1rame2or7Bundle./ontroller./ontroller;
class Blog/ontroller e%tends /ontroller
{
public function sho2Action($slug)
{
$blog = // use the $slug Earible to *uery the database
return $this85render(3AcmeBlogBundle!Blog!sho2.html.t2ig39 array(
3blog3 =5 $blog9
));
&
&
Routing, %a&o la capuc0a(
/uando una petici>n se realiFa a tu aplicaci>n9 contiene una direcci>n e%acta al
recurso *ue el cliente est, pidiendo.
<sta direcci>n se llama ($) o (($L) y podria ser! /contact /blog/read8me o algo
parecido.
/omo e+emplo tomaremos! R<H /blog/my8blog8post
<l ob+etiEo del sistema de rutas de 0ymfonyA es parsear esta ($) y determinar *u=
controlador deberDa ser e+ecutado. <l proceso completo serDa el siguiente!
B. )a petici>n es mane+ada por el fron controller de symfonyA (e+! app.php)
A. <l core de 0ymfonyA (es decir el Kernel) pide al router inspeccionar la
petici>n
?. <l router empare+a /iguala la ($) entrante a una ruta especDfica y deEuelEe
informaci>n sobre la ruta9 incluyendo el controlador *ue deberDa ser e+ecutado.
G. <l Kernel de 0ymfonyA e+ecuta el controlador el cu,l deEuelEe el ob+eto
$<0:NI0<.
<reando Rutas
0ymfony carga todas las rutas para su aplicaci>n a partir de un Knico archiEo de
configuraci>n de enrutamiento. <l archiEo suele ser app/config/routing.yml9 pero
puede ser configurado para ser cual*uier cosa (incluyendo un archiEo PW) o ::) a
traE=s del archiEo de configuraci>n de la aplicaci>n.
S app/config/config.yml
frame2or7!
S ...
router! { resource! ";7ernel.root'dir;/config/routing.yml" &
<on"iguraci;n de ruta %sica
-efinir una ruta es sencillo9 y una aplicaci>n tendr, muchDsimas rutas definidas!
(na ruta b,sica tiene dos partes9 el pattern para empare+ar9 y el array de"aults.
<+emplo!
'2elcome!
pattern! /
defaults! { 'controller! Acme-emoBundle!Wain!homepage &
<sta ruta empare+a la raiF ( / ) y la mapea al controlador
Acme-emoBundle!Wain!homepage
Routing con marcadores
'&emplo(
blog'sho2!
pattern! /blog/{slug&
defaults! { 'controller! AcmeBlogBundle!Blog!sho2 &
<ste pattern empare+ar, cual*uier cosa *ue se pareFca a /blog/T.
<n otras palabras9 si la ($) es /blog/hello82orld la Eariable $slug tendr, el
Ealor Uhello82orldV.
<l pattern no empare+ar, simplemente la ($) /blog por*ue por defecto todos los
marcadores son necesarios.
5arcadores re#ueridos + opcionales
blog!
pattern! /blog/{page&
defaults! { 'controller! AcmeBlogBundle!Blog!inde%9 page! B &
=%log >page} ? @
=%log=@ >page} ? @
=%log=A >page} ? A
ABadiendo re#uerimientos(
blog!
pattern! /blog/{page&
defaults! { 'controller! AcmeBlogBundle!Blog!inde%9 page! B &
blog'sho2!
pattern! /blog/{slug&
defaults! { 'controller! AcmeBlogBundle!Blog!sho2 &
<l problema est, *ue solo se Ea a e+ecutar la ruta UblogV y nunca la Ublog'sho2V
por*ue ambas tienen un par,metro9 la primera par,metro UpageV9 la segunda
par,metro UslugV.
<l enrutador de symfonyA siempre escoger, la primera ruta *ue coincida /empare+e
con la ($).
blog!
pattern! /blog/{page&
defaults! { 'controller! AcmeBlogBundle!Blog!inde%9 page! B &
re*uirements!
page! .dX
<l re*uerimiento .dX re*uirement es una e%presi>n regular *ue indica *ue el Ealor
del par,metro {pageY debe ser un dDgito.
/on eso solucionamos *ue las ($)0 del tipo /blog/? Eayan por la primera ruta9 y
*ue las ($)0 del tipo /blog/hello82orld Eayan por la segunda ruta.
<sto significa *ue el orden de las rutas es muy importante.
Ntros e+emplos!
homepage!
pattern! /{culture&
defaults! { 'controller! Acme-emoBundle!Wain!homepage9 culture! en &
re*uirements!
culture! enZfr
:ara peticiones entrantes!
/ {culture& = en
/en {culture& = en
/fr {culture& = fr
/es won't match this route
ABadiendo Re#uerimientos de mtodo HTTP
Adem,s puedes indicar en la ruta el m=todo *ue se utiliFa en la petici>n
entrante. (R<H9 <A-9 :N0H9 :(H9 -<)<H<).
<+emplo! suponemos *ue tenemos un formulario de contacto con dos controladores
(uno para mostrar el formulario en una petici>n R<H). M otro para procesar el
formulario cuando es enEiado (en una petici>n :N0H).
Ejemplo de configuracin de ruta:
contact!
pattern! /contact
defaults! { 'controller! Acme-emoBundle!Wain!contact &
re*uirements!
'method! R<H
contact'process!
pattern! /contact
defaults! { 'controller! Acme-emoBundle!Wain!contact:rocess &
re*uirements!
'method! :N0H
0i no se especifica el m=todo de re*uerimiento la ruta empare+ar, con todos los
m=todos.
,enerando :R67
<n realidad el sistema de routing de 0ymfonyA es un sistema bidireccional!
mapea la ($) a un controladorXparametros y de una rutaXparametros deEuelEe una
($).
)os m=todos matc0() y generate() forman este sistema bidireccional.
$params = $router85matc0(3/blog/my8blog8post3);
// array(3slug3 =5 3my8blog8post39 3'controller3 =5 3AcmeBlogBundle!Blog!sho23)
$uri = $router85generate(3blog'sho239 array(3slug3 =5 3my8blog8post3));
// /blog/my8blog8post
class Wain/ontroller e%tends /ontroller
{
public function sho2Action($slug)
{
// ...
$url = $this85get(3router3)85generate(3blog'sho239 array(3slug3 =5 3my8
blog8post3));
&
&
,enerando :R67 a%solutas
:or defecto el router genera direcciones relatiEas. :ara generar direcciones ($)
absolutas s>lo hay *ue pasarle al tercer argumento del m=todo generate() el Ealor
H$(<.
$router85generate(3blog'sho239 array(3slug3 =5 3my8blog8post3)9 true);
// http!//222.e%ample.com/blog/my8blog8post
,enerando :R67 con 9uer+ 7trings
$router85generate(3blog39 array(3page3 =5 A9 3category3 =5 30ymfony3));
// /blog/AQcategory=0ymfony
,enerando :R67 desde una plantilla = template
4a href="{{ pat0(3blog'sho239 { 3slug3! 3my8blog8post3 &) &&"5
$ead this blog post.
4/a5
Hambien se pueden generar ($)0 absolutas!
4a href="{{ url(3blog'sho239 { 3slug3! 3my8blog8post3 &) &&"5
$ead this blog post.
4/a5
T'5P6AT'7
<n symfonyA se suele usar como templates el lenguage H2ig.
H2ig define dos tipos de sinta%is especial!
46-N/HM:< html5
4html5
4head5
4title5[elcome to 0ymfony64/title5
4/head5
4body5
4hB5{{ page'title &&4/hB5
4ul id="naEigation"5
{; for item in naEigation ;&
4li54a href="{{ item.href &&"5{{ item.caption &&4/a54/li5
{; endfor ;&
4/ul5
4/body5
4/html5
{{ ... &&! es como el echo9 para imprimir una Eariable o el resultado de una
e%presi>n.
{; ... ;&! hace algo. (na eti*ueta *ue controla la l>gica de la plantilla9 es
usada para e+ecutar sentencias como los bucles9 los ifs...
/rear comentarios! {S this is a comment S&
Hambi=n usa filtros *ue modifican el contenido antes de renderiFarlo!
<+! {{ titleZupper && a*uD la Eariable title se pone en Wayusculas antes de
renderiFarla.
<+emplo de plantilla H[LR!
4ul5
{; for user in users ;&
4li5{{ user.username &&4/li5
{; else ;&
4li5Io users found4/li5
{; endfor ;&
4/ul5
Herencia de plantillas + la+outs
:rimero construimos un archiEo con el layout base.
{S app/$esources/Eie2s/base.html.t2ig S&
46-N/HM:< html5
4html5
4head5
4meta http8e*uiE="/ontent8Hype" content="te%t/html; charset=utf8\" /5
4title5{; bloc7 title ;&Hest Application{; endbloc7 ;&4/title5
4/head5
4body5
4diE id="sidebar"5
{; bloc7 sidebar ;&
4ul5
4li54a href="/"5ome4/a54/li5
4li54a href="/blog"5Blog4/a54/li5
4/ul5
{; endbloc7 ;&
4/diE5
4diE id="content"5
{; bloc7 body ;&{; endbloc7 ;&
4/diE5
4/body5
4/html5
<sta plantilla base define el es*ueleto base HW) en una p,gina de dos columnas.
<n este e+emplo ? {; bloc7 ;& areas son definidos (title9 sidebar y body). /ada
blo*ue puede ser sobreescrito por una plantilla hi+a o mantener su implementaci>n
por defecto.
(na plantilla hi+a podrDa ser asD!
{S src/Acme/BlogBundle/$esources/Eie2s/Blog/inde%.html.t2ig S&
{; e%tends 3!!base.html.t2ig3 ;&
{; bloc7 title ;&Wy cool blog posts{; endbloc7 ;&
{; bloc7 body ;&
{; for entry in blog'entries ;&
4hA5{{ entry.title &&4/hA5
4p5{{ entry.body &&4/p5
{; endfor ;&
{; endbloc7 ;&
)a plantilla padre se identifica con una sinta%is de cadena especial
(!! base.html.t2ig) *ue indica *ue la plantilla EiEe en el directorio
app/$esources/Eie2s.
/uando se traba+a con herencia de plantillas hay *ue tener en cuenta lo
siguiente!
0i se usa {; e%tends ;& en una plantilla9 debe ser el primer tag en esa
plantilla.
/uantas m,s eti*uetas {; bloc7 ;& tengas en tu plantilla base me+or9 para
*ue asi tu plantilla sea m,s fle%ible. )as plantillas hi+as no pueden
definir blo*ues.
0i necesitas conseguir el contenido de un blo*ue de la plantilla base9
puedes usar la funcion {{ parent() &&
<s muy util si se *uiere aJadir los contenidos del blo*ue padre en EeF de
sobreescribirlo.
{; bloc7 sidebar ;&
4h?5Hable of /ontents4/h?5
...
{{ parent() &&
{; endbloc7 ;&
3om%res de las plantillas + d;nde se locali)an = guardan
-os localiFaciones!
1) app/$esources/Eie2s/
2) path/to/bundle/$esources/Eie2s/
0ymfonyA usa un sinta%is %undle!controller!template para las plantillas.
<+emplo! AcmeBlogBundle!Blog!inde%.html.t2ig.
<sto significa lo siguiente!
AcmeBlogBundle! (bundle) la plantilla se encuentra dentro de la carpeta
src/Acme/BlogBundle
Blog! (controller) indica *ue la plantilla se encuentra dentro del subdirectorio
UBlogV en $esources/Eie2s
inde%.html.t2ig! (plantilla) el nombre actual de la plantilla.
<l path final serDa! src=Acme=BlogBundle=Resources=$iews=Blog=inde4.0tml.twig.

Cncludes de otras templates
<sta serDa la plantilla *ue *ueremos reutiliFar!
{S src/Acme/ArticleBundle/$esources/Eie2s/Article/article-etails.html.t2ig S&
4hA5{{ article.title &&4/hA5
4h? class="byline"5by {{ article.authorIame &&4/h?5
4p5
{{ article.body &&
4/p5
Incluimos esta plantilla en otra plantilla:
{S src/Acme/ArticleBundle/$esources/Article/list.html.t2ig S&
{; e%tends 3AcmeArticleBundle!!layout.html.t2ig3 ;&
{; bloc7 body ;&
4hB5$ecent Articles4hB5
{; for article in articles ;&
{; include DAcmeArticleBundle(Article(article!etails.0tml.twigD wit0
>DarticleD( article} ;&
{; endfor ;&
{; endbloc7 ;&
'm%e%iendo controladores
Lmaginemos *ue tienes una Fona en tu plantilla *ue contiene los ? articulos mas
recientes.
/onseguir estos ? Kltimos artDculos re*uerir, una consulta a la base de datos *ue
no puede ser realiFado dentro de una plantilla (debe hacerse desde un
controlador)
)a soluci>n es simplemente embeber el resultado de un controlador enteramente en
tu plantilla.
:rimero Eamos a crear el controlador *ue renderiFa un cierto nKmero de artDculos!
// src/Acme/ArticleBundle//ontroller/Article/ontroller.php
class Article/ontroller e%tends /ontroller
{
public function recentArticlesAction($ma% = ?)
{
// ma7e a database call or other logic to get the "$ma%" most recent
articles
$articles = ...;
return /t0is12render(DAcmeArticleBundle(Article(recent6ist.0tml.twigD,
arra+(DarticlesD ?2 /articles));
&
&
la plantilla recent)ist.html.t2ig contendr, el siguiente c>digo!
{S src/Acme/ArticleBundle/$esources/Eie2s/Article/recent)ist.html.t2ig S&
{; for article in articles ;&
4a href="/article/{{ article.slug &&"5
{{ article.title &&
4/a5
{; endfor ;&
:ara incluir el controlador9 se debe usar la sinta%is de cadena est,ndar para los
controladores (es decir bundle!controller!action)
{S app/$esources/Eie2s/base.html.t2ig S&
...
4diE id="sidebar"5
{; render "AcmeArticleBundle!Article!recentArticles" 2ith {3ma%3! ?& ;&
4/diE5
6inEando a pginas desde una plantilla
/rear lin7s a otras p,ginas en una aplicaci>n con symfony es el traba+o m,s comKn
de una template.
0e suele usar el m=todo pat0() para generar ($)0 basadas en la configuraci>n de
routing.
Ejemplo sencillo:
/onfiguracion de routing de la p,gina 2elcome.
'2elcome!
pattern! /
defaults! { 'controller! Acme-emoBundle![elcome!inde% &
:ara lin7ar a esta p,gina solamente usa el m=todo path en la plantilla!
4a href="{{ path(3'2elcome3) &&"5ome4/a5
Ejemplo con una ruta con parmetros:
article'sho2!
pattern! /article/{slug&
defaults! { 'controller! AcmeArticleBundle!Article!sho2 &
<n este caso se necesita especificar el el nombre de la ruta (article'sho2) y un
Ealor para el par,metro {slug&
{S src/Acme/ArticleBundle/$esources/Eie2s/Article/recent)ist.html.t2ig S&
{; for article in articles ;&
4a href="{{ pat0(3article'sho239 { 3slug3! article.slug &) &&"5
{{ article.title &&
4/a5
{; endfor ;&
Hambi=n se pueden generar una ($) absoluta de =sta manera!
4a href="{{ url(3'2elcome3) &&"5ome4/a5
6inEando a los "ic0eros = imgenes = arc0i$os = &a$ascripts...
1unci>n asset()
4img src="{{ asset(3images/logo.png3) &&" alt="0ymfony6" /5
4lin7 href="{{ asset(3css/blog.css3) &&" rel="stylesheet" type="te%t/css" /5
Cnclu+endo 0o&as de estilo + &a$ascripts en plantillas Twig
<mpeFamos aJadiendo dos blo*ues en tu plantilla base *ue contendr,n tus assets
(st+les0eets dentro de la eti*ueta head y &a$ascripts +usto antes del cierre de
la eti*ueta body)
{S 3app/$esources/Eie2s/base.html.t2ig3 S&
4html5
4head5
{S ... S&
{; bloc7 st+les0eets ;&
4lin7 href="{{ asset(3/css/main.css3) &&" type="te%t/css"
rel="stylesheet" /5
{; endbloc7 ;&
4/head5
4body5
{S ... S&
{; bloc7 &a$ascripts ;&
4script src="{{ asset(3/+s/main.+s3) &&"
type="te%t/+aEascript"54/script5
{; endbloc7 ;&
4/body5
4/html5
<s muy f,cil.
]M *ue ocurrirDa si se *uisiera incluir una ho+a de estilos o c>digo +aEascript
desde una plantilla hi+aQ
:lantilla hi+a!
{S src/Acme/-emoBundle/$esources/Eie2s//ontact/contact.html.t2ig S&
{; e%tends 3!!base.html.t2ig3 ;&
{; bloc7 stylesheets ;&
{{ parent() &&
4lin7 href="{{ asset(3/css/contact.css3) &&" type="te%t/css" rel="stylesheet"
/5
{; endbloc7 ;&
{S ... S&
0implemente se sobreescribe el blo*ue stylesheets9 pero si no *ueremos modificar
el contenido del blo*ue stylesheet base por*ue lo *ue *ueremos es aJadir nueEo
c>digo9 entonces es importante poner {{ parent && para incluir todo el contenido
del blo*ue stylesheets de la plantilla base.
*aria%les glo%ales de plantilla
)a Eariable UappV es una instancia de RlobalCariables
(0ymfony/Bundle/1rame2or7Bundle/Hemplating/RlobalCariables)
app.securit+ The security conte!t"
app.user The current user o#$ect"
app.re#uest The re%uest o#$ect"
app.session The session o#$ect"
app.en$ironment The current en&ironment 'de&( prod( etc)"
app.de%ug True if in de#ug mode" *alse other+ise"
<+emplo de uso!
4p5(sername! {{ app.user.username &&4/p5
{; if app.debug ;&
4p5$e*uest method! {{ app.re*uest.method &&4/p5
4p5Application <nEironment! {{ app.enEironment &&4/p5
{; endif ;&
Bases de datos + doctrine
-octrine es una biblioteca cuyo Knico ob+etiEo es ofrecer herramientas muy Ktiles
y poderosas para hacer f,cil el acceso a la bbdd.
-octrine est, totalmente desacoplada de 0ymfony y su uso es opcional.
<ste capDtulo trata sobre -octrine N$W el cu,l tiene como ob+etiEo permitir el
mapeo de ob+etos hacia una base de datos relacional (mys*l9 postgres*l9 microsoft
s*l)
:asos para este e+emplo!
B) Reneramos un bundle Acme0toreBundle
php app/console generate:bundle --namespace=Acme/StoreBundle
A) /onfigurando la base de datos.
<n an app/config/parameters.ini
Ahora *ue -octrine conoce tu bbdd9 usted puede crear la base de datos.
/on el comando! php app/console doctrine!database!create
?) /reamos una entidad producto en Usrc/Acme/0toreBundle/<ntity/:roduct.phpV
// src/Acme/0toreBundle/<ntity/:roduct.php
namespace Acme.0toreBundle.<ntity;
class :roduct
{
protected $name;
protected $price;
protected $description;
&
G) (sustitucion del paso ?)
:uedes crear esta clase / entidad a traE=s de la biblioteca -octrine.
php app/console doctrine!generate!entity 88entity="Acme0toreBundle!:roduct"
88fields="name!string(A^^) price!float description!te%t"
^) AJadir informaci>n de mapeo
:ara *ue -octrine sea capaF de hacer este mapeo9 se debe crear el UmetadataV o la
configuraci>n *ue le dice a -octrine e%actamente como deberDan ser mapeadas la
clase :roducto y sus propiedades a la bbdd.
<ste metadata puede ser especificado en diferentes formatos (MAW)9 PW) o
directamente a traE=s de anotaciones en la clase :roducto)
,enerando ,etters y Setters
Aun*ue -octrine ahora sabe como persistir un ob+eto :roducto a la bbdd9 la clase
:roducto en si misma no es muy Ktil.
_) 0e deben crear m=todos de inicialiFaci>n de los atributos y de recogida de
esos atributos (puesto *ue las propiedades est,n protegidas ` protected 8 )
<+! getIame()9 setIame().
A"ortunadamente !octrine puede 0acer sto por tF e&ecutando el comando(
php app/console doctrine!generate!entities Acme/0toreBundle/<ntity/:roduct
<ste comando te asegura *ue todos los getters y setters son generados para la
clase :roducto. <s un comando seguro ` se puede e+ecutar tantas Eeces como se
*uiera. 0olo genera getters y setters *ue no e%istan9 es decir9 no reemplaFa tus
m=todos ya e%istentes.
<+ecutando el comando9 se han creado en el archiEo
src/Acme/0toreBundle/<ntity/:roduct.php los m=todos!
public function getLd(); public function setIame($name); public function
getIame(); public function set:rice($price); public function get:rice(); public
function set-escription($description); y public function get-escription().
<l comando doctrine!generate!entities guarda una copia de seguridad de la product1p%p
original nombrandolo product1p%p H1 En algunos casos, la presencia de este arc%i'o puede causar un
error del tipo INo se puede redeclare claseI )e puede quitar sin problemas1
0e pueden generar todas las entidades conocidas de un bundle o de un nombre de
espacios entero!
php app/console doctrine!generate!entities Acme0toreBundle
php app/console doctrine!generate!entities Acme
<reando el es#uema = ta%las de la %%dd
J) -octrine y la creaci>n de la nueEa tabla de productos.
Ahora tenemos una clase :roducto con informaci>n de mapeo para *ue -octrine
sepa e%actamente como se persiste en bbdd. -e momento no tenemos creada
ninguna tabla en bbdd para los productos. -octrine nos puede ayudar a crear
todas las tablas de la bbdd *ue se necesiten para cada entidad en tu
aplicaci>n.
0e e+ecuta el siguiente comando!
p%p app-console doctrine+sc%ema+update ::orce
Persisting 8%&ects to t0e !ata%ase
K) Una 'ez que se tiene la entidad "roducto mapeada, ! la tabla product correspondiente a los productos, se est
preparado para poder persistir datos en la base de datos1
Lsto se realiza desde el interior de un controlador *controller)1
)e a/ade el siguiente m;todo al controller por deecto del bundle Acme)toreBundle
*src-Acme-)toreBundle-,ontroller-Deault,ontroller1p%p)1
-- src-Acme-)toreBundle-,ontroller-Deault,ontroller1p%p
use Acme.0toreBundle.<ntity.:roduct;
use 0ymfony./omponent.ttp1oundation.$esponse;
// ...
public function createAction()
{
//se crea un nueEo producto y se inicialiFan sus propiedades.
$product = ne2 :roduct();
$product85setIame(3A 1oo Bar3);
$product85set:rice(3Ba.aa3);
$product85set-escription(3)orem ipsum dolor3);
//esta linea recoge el ob+eto gestor de la entidad9 el cual es responsable de
mane+ar el proceso de persistencia y recoleccion de ob+etos hacia y desde la
bbdd.
$em = $this85get-octrine()85get<ntityWanager();
//el m=todo persists le indica a -octrine *ue mane+e el ob+eto $product. <sto no
e+ecuta ninguna *uery sobre la bbdd todaEDa.
$em85persist($product);
// -octrine mira todos los ob+etos *ue est, mane+ando para Eer si necesitan ser
persistentes en la bbdd. A*ui es donde se e+ecuta la *uery9 en este caso9 de
inserci>n.
$em85flush();
return ne2 $esponse(3/reated product id 3.$product85getLd());
&
M) "ara probar este e&emplo se necesita crear una ruta que apunte a esta acci$n para probar que
unciona1
En mi caso %e modiicado+ app-conig-routing1!ml
! en lugar de
Acme)toreBundle+
7 resource+ INAcme)toreBundle-,ontroller-I
7 t!pe+ annotation
7 prei4+ -
#e escrito+
Acme)toreBundle+
resource+ INAcme)toreBundle-3esources-conig-routing1!mlI
prei4+ -
Luego, %e creado el arc%i'o src-Acme-)toreBundle-3esources-conig-routing1!ml
Acme)toreBundleA%omepage+
pattern+ -store-
deaults+ F Acontroller+ Acme)toreBundle+Deault+create G
. e&ecutando la siguiente ruta+
%ttp+--DDD1gas'i1com-appAde'1p%p-store-
)e a/ade un nue'o registro en la tabla product de la bbdd
-ecoger o#$etos de la BB..
En el controlador *src/Acme/StoreBundle/Controller/.efaultController"php) se a/ade una nue'a unci$n
*unction s%oDAction*Oid))
public unction s%oDAction*Oid)
F
Oproduct P Ot%is:QgetDoctrine*)
:Qget3epositor!*RAcme)toreBundle+"roductR)
:Qind*Oid)S
i *@Oproduct) F
t%roD Ot%is:QcreateNot?oundE4ception*RNo product ound or id R1Oid)S
G
-- do somet%ing, liTe pass t%e Oproduct ob&ect into a template
--return neD 3esponse*R)e %a conseguido el producto con id R1Oproduct:QgetEd*)1RUbrQ El nombre es + R1Oproduct:
QgetDescription*)1RUbrQ El precio del producto es+ R1Oproduct:Qget"rice*))S
return Ot%is:Qrender*RAcme)toreBundle+Deault+s%oD1%tml1tDigR, arra!*RproductR PQ Oproduct))S
G
--llamada a la 'ista s%oD1%tml1tDig que se encuentra en src-Acme-)toreBundle-'ieDs-Deault-
En src-Acme-)toreBundle-3esources-conig-routing1!ml se a/ade la siguiente ruta+
Acme)toreBundleAs%oDproduct+
pattern+ -store-FidG
deaults+ F Acontroller+ Acme)toreBundle+Deault+s%oD G
7u%ir los css, imagenes etc instalados en
%undle=Resources=pu%lic a we%=%undles=%undledemo=
/omando! php app/console assets!install 2eb
<omo generar entidades desde una %ase de datos e4istente
<l primer paso hacia la construcci>n de las entidades de una base de datos
e%istente es pedir a -octrine la introspecci>n la base de datos y generar los
archiEos de metadatos correspondientes. )os archiEos de metadatos describen la
entidad para generar sobre la base de los campos de las tablas.
p0p app=console doctrine(mapping(con$ert 4ml
.=src=Acme=7toreBundle=Resources=con"ig=doctrine=metadata=orm 11"rom1data%ase
11"orce
<s posible generar los metadatos en formato MAW) cambiado el primer argumento a
yml
(na EeF *ue los archiEos de metadatos se generan9 usted puede pedir a -octrine
importar el es*uema y construir las clases relacionadas con la entidad mediante
la e+ecuci>n de los siguientes dos comandos.
p0p app=console doctrine(mapping(import Acme7toreBundle annotation
p0p app=console doctrine(generate(entities Acme7toreBundle
El primer comando genera las clases de entidad con mapas de anotaciones, tu puedes por supuesto
cambiar el argumento annotation a 4ml o !ml1
El segundo comando genera todos los getters ! setters para sus entidades
php doctrine orm!conEert8mapping 88from8database yml
src/Acme/0toreBundle/$esources/config/doctrine/metadata/orm/(suarios.orm.yml

Potrebbero piacerti anche