Els bundles a symfony 2.

De wikiserver
La revisió el 01:13, 19 feb 2016 per Asalinas (Discussió | contribucions) (Es crea la pàgina amb «Un bundle és un concepte similar al dels plugins en altres aplicacions, però encara millor. La diferència clau és que '''en Symfony2 tot és un bundle''', incloent ta…».)
(dif) ← Versió més antiga | Versió actual (dif) | Versió més nova → (dif)
Dreceres ràpides: navegació, cerca

Un bundle és un concepte similar al dels plugins en altres aplicacions, però encara millor. La diferència clau és que en Symfony2 tot és un bundle, incloent tant la funcionalitat bàsica de la plataforma com el codi escrit per a la teva aplicació.

Els bundles són la part més important de Symfony2. Permeten utilitzar funcionalitats construïdes per tercers o empaquetar les teves pròpies funcionalitats per distribuir-les i reutilitzar-les en altres projectes. A més, faciliten molt l'activació o desactivació de determinades característiques dins d'una aplicació.

Un bundle simplement és un conjunt estructurat d'arxius que es troben en un directori i que implementen una sola característica. Pots crear per exemple un BlogBundle, un ForoBundle o un bundle per gestionar usuaris (molts d'ells ja existeixen com bundles de programari lliure). Cada directori conté tot el relacionat amb aquesta característica, incloent arxius PHP, plantilles, fulles d'estil, arxius Javascript, tests i qualsevol altra cosa necessària.

Les aplicacions Symfony es componen de bundles, tal com es defineix en el mètode registerBundles() de la classe AppKernel:

// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
        new Symfony\Bundle\SecurityBundle\SecurityBundle(),
        new Symfony\Bundle\TwigBundle\TwigBundle(),
        new Symfony\Bundle\MonologBundle\MonologBundle(),
        new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
        new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
        new Symfony\Bundle\AsseticBundle\AsseticBundle(),
        new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
    );
 
    if (in_array($this->getEnvironment(), array('dev', 'test'))) {
        $bundles[] = new Acme\DemoBundle\AcmeDemoBundle();
        $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
        $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
        $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
    }
 
    return $bundles;
}


Creació del primer bundle

Crea un bundle a la teva aplicació amb el nom Hola seguin la nomenclatura de bundles (NomAplicacio/NomFuncionalitatBundle) en format yml.

Creant un bundle

L'edició estàndard de Symfony inclou una comanda per crear bundles totalment funcionals d'una manera molt senzilla. Per descomptat, també pots crear els bundles a mà si ho prefereixes.

php app/console generate:bundle --namespace=NomAplicacio/NomFuncionalitatBundle --format=yml

Estructura de directoris d'un bundle

L'estructura de directoris d'un bundle és simple i flexible. Per defecte el sistema de bundles segueix una sèrie de convencions que ajuden a mantenir el codi consistent entre tots els bundles Symfony2. Fa un cop d'ull a AcmeHelloBundle, ja que conté alguns dels elements més comuns d'un bundle:

  • Controller/: conté els controladors del bundle (per exemple, HelloController.php).
  • DependencyInjection/: conté elements relacionats amb el contenidor d'injecció de dependències. Entre unes altres, conté les extensions per a les classes d'injecció de dependències, la configuració que importen els serveis i registra un o més passades del compilador (aquest directori no és obligatori).
  • Resources/config/: conté la configuració, incloent la configuració de enrutamiento (per exemple, routing.yml).
  • Resources/views/: conté les plantilles organitzades segons el nom del controlador (per exemple, Hello/index.html.twig).
  • Resources/public/: conté recursos web (imatges, fulles d'estil, etc.) i és copiat o enllaçat simbòlicament al directori web/ del projecte amb el comando assets:install.
  • Tests/: té els tests unitaris i funcionals del bundle.

Configurant l'aplicació

L'aplicació està formada per una col·lecció de bundles que representen totes les característiques i capacitats de la teva aplicació. Cada bundle es pot personalitzar a través d'arxius de configuració escrits en YAML, XML o PHP. De forma predeterminada, l'arxiu de configuració principal es troba en el directori app/config/ i es diu config.yml, config.xml o config.php en funció del format que prefereixis.

# app/config/config.yml
imports:
    - { resource: parameters.yml }
    - { resource: security.yml }

framework:
    secret:          "%secret%"
    router:          { resource: "%kernel.root_dir%/config/routing.yml" }
    # ...
 
# Twig Configuration
twig:
    debug:            "%kernel.debug%"
    strict_variables: "%kernel.debug%"
 
# ...

Ara que ja està configurat el bundle, pots començar a construir la teva aplicació dins del bundle.

Exemple per crear l'aplicació

  • Pas 1: Creant la ruta

Per defecte, l'arxiu de configuració d'encaminament en una aplicació Symfony2 es troba en app/config/routing.yml. Si ho prefereixes, i igual que en la resta de la configuració en Symfony2, pots utilitzar el format XML o PHP per configurar les teves rutes.

Si et fixes en l'arxiu d'encaminament principal, veuràs que Symfony ja ha agregat una entrada en generar el bundle ProvesHolaBundle:

# app/config/routing.yml
acme_hello:
    resource: "@ProvesHolaBundle/Resources/config/routing.yml"
    prefix:   /

Aquesta directiva de configuració li diu a Symfony que carregui la configuració d'encaminament de l'arxiu Resources/config/routing.yml que es troba a l'interior del bundle ProvesHolaBundle.

En altres paraules, pots configurar les teves rutes directament en l'arxiu app/config/routing.yml o pots definir-les en diverses parts de l'aplicació i després les importes des d'aquest arxiu.

Ara que l'arxiu routing.yml del bundle s'importa des de l'arxiu d'encaminament principal de l'aplicació, afegeix la nova ruta que defineix la URL de la pàgina que ets a punt de crear:

# src/Proves/HolaBundle/Resources/config/routing.yml
hello:
    path:     /hello/{name}
    defaults: { _controller: ProvesHolaBundle:Hola:index }

La ruta es compon bàsicament de dues parts: el path, que és la URL amb la qual ha de coincidir la petició de l'usuari per activar la ruta, i un array anomenat defaults, que especifica el controlador que s'executa. Les parts de la URL tancades entre cometes indiquen que el seu valor pot variar. D'aquesta forma, {name} significa que les URL /hello/Ryan, /hello/Fabien o qualsevol altra URI similar coincidirà amb aquesta ruta. El valor de les parts variables també es passa al controlador, que pot accedir a ells a través del nom assignat en la pròpia ruta (name en aquest cas).

  • Pas 2: Creant el controlador

Quan l'usuari sol·licita la URL /hello/Ryan, s'activa la ruta hello, a la qual correspon el controlador ProvesHolaBundle:Hola:index, que és realment el codi que s'executa. El segon pas del procés de creació de pàgines consisteix precisament a crear aquest controlador.

La cadena ProvesHolaBundle:Hola:index és el nom lògic del controlador, que es tradueix com el mètode indexAction() d'una classe PHP Proves\HolaBundle\Controller\Hola. Crea en primer lloc aquest arxiu dins del teu bundle ProvesHolaBundle:

// src/Proves/HolaBundle/Controller/HolaController.php
namespace Proves\HolaBundle\Controller;
 
use Symfony\Component\HttpFoundation\Response;
 
class HolaController
{
}

En realitat, el controlador no és més que un mètode PHP que tu creguis i Symfony executa. Aquí és on el codi utilitza la informació de la petició per construir i preparar el recurs sol·licitat. Excepte en alguns casos avançats, el resultat final d'un controlador sempre és el mateix: un objecte Response de Symfony2.

Crea el mètode indexAction que Symfony executarà quan se serveixi la ruta hola:

// src/Proves/HolaBundle/Controller/HolaController.php
 
// ...
class HolaController
{
    public function indexAction($name)
    {
        return new Response('<html><body>Hola '.$name.'!</body></html>');
    }
}

El controlador és molt senzill: crea un nou objecte de tipus Response i el primer argument del qual és el contingut que s'utilitza per crear la resposta enviada a l'usuari (en aquest cas, una pàgina HTML molt simple).

Enhorabona! Després de crear solament una ruta i un controlador ja tens una pàgina completament funcional! Si tot ho has configurat correctament, l'aplicació ha de donar-te la benvinguda en accedir a la següent URL:

http://localhost/app_dev.php/hola/alex

També pots generar controladors de manera automàtica utilitzant una comanda:

php app/console generate:controller

El tercer i últim pas per crear una pàgina és opcional però gairebé totes les aplicacions ho fan: crear una plantilla.

Pas 3 opcional: Creant la plantilla

Les plantilles et permeten moure tota la part de la vista (és a dir, el codi HTML) a un arxiu separat i reutilitzar diferents parts del disseny de la pàgina. En comptes d'escriure el codi HTML dins del controlador, genera el codi HTML a partir d'una plantilla en format TWIG:

// src/Proves/HolaBundle/Controller/HolaController.php
namespace Acme\HelloBundle\Controller;
 
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 
class HolaController extends Controller
{
    public function indexAction($name)
    {
        return $this->render('ProvesHolaBundle:Hello:index.html.twig', array('name' => $name));
 
    }
}

El mètode render() crea un objecte Response i li afegeix el contingut resultant de renderizar la plantilla. Així que com qualsevol altre controlador, el codi anterior realment està retornant un objecte de tipus Response.

Tingues en compte que pots processar les plantilles de dues formes diferents. Per defecte Symfony2 admet dos llenguatges de plantilles: les clàssiques plantilles creades amb PHP i les noves i concises plantilles creades amb Twig. No t'espantis perquè pots triar lliurement quin utilitzar o fins i tot barrejar les dues en el mateix projecte.

En processar la plantilla ProvesHolaBundle:Hola:index.html.twig, el controlador utilitza la següent convenció de nomenclatura:

NombreBundle:NombreControlador:NombrePlantilla

Aquest és el nom lògic de la plantilla, que es tradueix a un arxiu físic utilitzant la següent convenció:

</ruta/a/Nombrebundle>/Resources/views/<NombreControlador>/<NombrePlantilla>

En aquest cas, ProvesHolaBundle és el nom del bundle, Hola és el controlador i index.html.twig la plantilla:

{# src/Proves/HolaBundle/Resources/views/Hola/index.html.twig #}
{% extends '::base.html.twig' %}
 
{% block body %}
    Hello {{ name }}!
{% endblock %}

Vegem la situació a través de la plantilla Twig línia per línia:

L'etiqueta extends indica que s'utilitza una plantilla pare on es defineix el disseny del lloc web. L'etiqueta block indica que tot el seu contingut s'ha de col·locar dins d'un bloc anomenat body. Com s'explicarà més endavant, la plantilla pare (base.html.twig) és la responsable de definir aquest bloc i de mostrar-ho a la pàgina HTML adequadament. La plantilla pare s'indica com ::base.html.twig, per la qual cosa no inclou ni la part del nom del bundle ni la del nom del controlador (d'aquí els dos punts dobles (::) al principi). Això significa que la plantilla no es troba dins de cap bundle, sinó en el directori app del projecte:

{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>{% block title %}Welcome!{% endblock %}</title>
    {% block stylesheets %}{% endblock %}
    <link rel="shortcut icon" href="{{ asset('favicon.ico') }}" />
    </head>
    <body>
    {% block body %}{% endblock %}
    {% block javascripts %}{% endblock %}
    </body>
</html>