Symfony(2)Tour - Views Controllers Bundles

Symfony(2)Tour - Views Controllers Bundles

1. Twig Twig Twig
http://twig.sensiolabs.org/documentation

A Twig template is a text file that can generate any type of content (HTML, CSS, JavaScript, XML, CSV…)

{# array( ‘user’ => array(’name’ => ‘Fabien’)) #}
{{ user.name }}

or 
{{ user[’name’] }}

{# array(‘user’ => new User(‘Fabien')) #}
{{ user.name }}
{{ user.getName() }}

Decorating Templates
layout.html.twig
<div>
     {% block content %}
     {% endblock %}
</div>

hello.html.twig
{% extends “AcmeDemoBundle::layout.html.twig” %}
{% block content %}
     <h1>Hello {{ name }} !</h1>
{% endblock %}

Using Tags, Filters, and Functions
{{ article.title|trim|capitalize }}

This is really powerful, Embedding other Controllers
{# index.html.twig #}
{{ render(controller(“AcmeDemoBundle:Demo:topArticles”, {’num’: 10})) }}

Creating Links between Pages
<a href=“{{ path(‘_demo_hello’, { ’name’ : ‘Carl’ })  }}”>Go and have Fun!</a>

That name _demo_hello will match the name of the annotation in routing.

Including Assets: Images, JavaScripts and Stylesheets
    <link rel="icon" sizes="16x16" href="{{ asset('favicon.ico') }}" />
    <link rel="stylesheet" href="{{ asset('bundles/acmedemo/css/demo.css') }}" />

2. The Controller
Using Formats
Change the annotation as follow:
    /**
     * @Route("/hello/{name}", defaults={"_format"="xml"}, name="_demo_hello")
     * @Template()
     */
    public function helloAction($name)
    {
        return array('name' => $name);
    }

Directly write some codes in the Twig template
<hello>
    <name>{{ name }}</name>
</hello>

If we plan to support multiple format at one time, we need to add parameter in the routing.
The Routing annotation will changes as follow:
    /**
     * @Route(
     *  "/hello/{name}.{_format}",
     *  defaults={"_format"="html"},
     *  requirements = { "_format" = "html|xml|json"},
     *  name="_demo_hello")
     *  @Template()
     */

Redirecting and Forwarding
return $this->redirect($this->generateUrl(‘_demo_hello’, array(‘name’ =>”Sillycat’) ) );

return $this->forward(‘AcmeDemoBundle:Hello:index’, array(
     ‘name’ => $name,
     ‘color’  => ‘green'
));

Displaying Error Pages
404
throw $this->createNotFoundException();

500
throw new \Exception('Something went wrong!’); 

It is very important to put \ before Exception.

Getting Information from the Request
If our action has an argument that type is Symfony\Component\HttpFoundation\Request, we can have the Request info.

use Symfony\Component\HttpFoundation\Request;

public function someAction(Request $request){
     $request->isXmlHttpRequest(); //is it an Ajax request?
     $request->query->get(‘page’); //get a $_GET parameter
     $request->request->get(‘page’); //get a $_POST parameter
}

In the template, we can also access the variables in $request like this.
{{ app.request.query.get(‘page’) }}
{{ app.request.parameter(‘page’) }}

Persisting Data in the Session
HTTP protocol is stateless, between 2 requests, Symfony2 stores the attributes in a cookie by using native PHP sessions.

public function someAction(Request $request){
     $session = $this->request->getSession();
     $session->set(‘username’, ‘Carl’);
     $username = $session->get(‘username’);
     $username = $session->get(‘username’, ’DefaultName’); //get with default value
}

Before redirecting, we can store the Error Message/Successful Message in “Flash Messages”.
$session->getFlashBag()->add(‘’notice’,’congratulations,your action is succeeded!’);

In the template
<div> {{ app.session.flashbag.get(‘notice’) }} </div>

Caching Resources
Put that in the annotation right after @Template()
/**
* @Route(…)
* @Template()
* @Cache(maxage=“86400”)
*/

The unit for that cache configuration is second, 86400 is a day. 

3. The Architecture
app - application configuration
src
vendor - the third-party dependencies
web - web root

3.1 How the PHP Controller Start
Controller will load the app/AppKernel.php, In side the AppKernel.php, it will provide at least 2 methods.
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\AsseticBundle\AsseticBundle(),
            new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
            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;
    }

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
    }

3.2 Understanding the Bundle System
Bundle is a plugin, it is called bundle because everything is a bundle in Symfony2. You can use pre-built features packaged in third-party bundles or distribute your own bundles.

Registering a Bundle
AppKernel — registerBundles()
Each bundle is a directory that contains a single Bundle class that describes it.
For example, in the src directory, we have Acme\DemoBundle\AcmeDemoBundle.php
<?php
namespace Acme\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeDemoBundle extends Bundle
{
}

Then we have this line in the AppKernel.php
$bundles[] = new Acme\DemoBundle\AcmeDemoBundle();

For the third party Bundle
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Bundle\SecurityBundle\SecurityBundle(),
            new Symfony\Bundle\TwigBundle\TwigBundle(),

vendor/symfony/symfony/src/Symfony/Bundle

Configuring a Bundle
Look at app/config/config.yml. 
imports:
    - { resource: parameters.yml }
    - { resource: security.yml }

framework:
    #esi:             ~
    #translator:      { fallback: "%locale%" }
    secret:          "%secret%”
…snip…
# Twig Configuration
twig:
    debug:            "%kernel.debug%”

framework configures FrameworkBundle, twig configures TwigBundle.

DEV environment loads config_dev.yml and overwrites the config.yml.

Extending a Bundle
Logical File Names
@BUNDLE_NAME/path/to/file;
@AcmeDemoBundle/Controller/SecuredController.php

Logical Controller Names
BUNDLE_NAME:CONTROLLER_NAME:ACTION_NAME, for example, AcmeDemoBundle:Welcome:index

Logical Template Names
AcmeDemoBundle:Welcome:index.html.twig  ——> src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig

Extending Bundles
http://symfony.com/doc/current/cookbook/bundles/inheritance.html

Using Vendors
Symfony2 loads a lot of yaml and XML, we only do parse at the first request and then cache the plain PHP codes in app/cache. In the DEV environment, Symfony2 will flush the cache when we change a file.
But in the production environment, we take the responsibility to clear the cache.

app/logs/

Using the Command Line Interface
>php app/console --help
>php app/console -V
Symfony version 2.4.5 - app/dev/debug

>php app/console --env=dev server:run
This command default run PHP built-in server based on development environment.

Go further, read this book http://symfony.com/doc/current/book/index.html

References:
http://symfony.com/doc/current/quick_tour/the_view.html
http://symfony.com/doc/current/cookbook/bundles/inheritance.html
http://symfony.com/doc/current/book/index.html


你可能感兴趣的:(controller)