Symfony 2.8 ltsでブログを作成する[パート5]







部品ナビゲーション
パート1-Symfony2とテンプレートの構成

パート2-連絡先ページ:バリデーター、フォーム、およびメール

パート3-Doctrine 2とデータフィクスチャ

パート4-Doctrine 2のコメントモデル、リポジトリ、移行

パート6-ユニットおよび機能テスト







Githubプロジェクト

必要なマニュアルの一部をインストールする方法については、 リンクでリポジトリの説明を参照してください 。 (たとえば、前のレッスンを経ずにこのレッスンから始めたい場合)





ホームページ 投稿とコメント。





メインページに最近のエントリのリストが表示されるようになりましたが、これらのエントリのコメントに関する情報はありません。 エッセンスコメントがあります。この情報を提供するためにメインページに戻ることができます。 BlogエンティティとCommentエンティティの間に関係を確立したので、Doctrine 2は投稿に対するコメントを受信できることを知っています( $ commentsオブジェクトをBlogエンティティに追加したことを思い出してください)。 ホームページテンプレートを更新しましょう

src / Blogger / BlogBu​​ndle / Resources / views / Page / index.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/index.html.twig #}

{# .. #}
<footer class="meta">
    <p>Comments: {{ blog.comments|length }}</p>
    <p>Posted by <span class="highlight">{{ blog.author }}</span> at {{ blog.created|date('h:iA') }}</p>
    <p>Tags: <span class="highlight">{{ blog.tags }}</span></p>
</footer>

{# .. #}

      
      









comments getter , Twig length . , http://localhost:8000/ .



, Doctrine 2 $comments Blog Comment. Blog.

src/Blogger/BlogBundle/Entity/Blog.php
// src/Blogger/BlogBundle/Entity/Blog.php

/**
 * @ORM\OneToMany(targetEntity="Comment", mappedBy="blog")
 */
protected $comments;


      
      









, , Doctrine 2 , $comments Comment? BlogRepository, ( ) , Comment .

src/Blogger/BlogBundle/Repository/BlogRepository.php
// src/Blogger/BlogBundle/Repository/BlogRepository.php

public function getLatestBlogs($limit = null)
{
    $qb = $this->createQueryBuilder('b')
               ->select('b')
               ->addOrderBy('b.created', 'DESC');

    if (false === is_null($limit))
        $qb->setMaxResults($limit);

    return $qb->getQuery()
              ->getResult();
}

      
      









, Doctrine 2 , , Comment , , {{blog.comments | length}}. , . , , Doctrine 2 . Doctrine 2 , … , HTTP-.







Doctrine 2 , Doctrine 2 HTTP.







, . , getLatestBlogs() BlogRepository. , , . WHERE t0.blog_id = ? , ? (id ). {{blog.comments}} . , , Doctrine 2 (lazily) Comment, Blog.



, . Doctrine2 , . , Blog Comment . QueryBuilder BlogRepository.

src/Blogger/BlogBundle/Repository/BlogRepository.php
// src/Blogger/BlogBundle/Repository/BlogRepository.php

public function getLatestBlogs($limit = null)
{
    $qb = $this->createQueryBuilder('b')
               ->select('b, c')
               ->leftJoin('b.comments', 'c')
               ->addOrderBy('b.created', 'DESC');

    if (false === is_null($limit))
        $qb->setMaxResults($limit);

    return $qb->getQuery()
              ->getResult();
}

      
      









, Doctrine 2 , . , comment blog.



, . 2 , , . , . , , Doctrine 2. , .



, , .

src/Blogger/BlogBundle/Resources/views/Page/index.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/index.html.twig #}

{# .. #}

<footer class="meta">
    <p>Comments: <a href="{{ path('BloggerBlogBundle_blog_show', { 'id': blog.id }) }}#comments">{{ blog.comments|length }}</a></p>
    <p>Posted by <span class="highlight">{{ blog.author }}</span> at {{ blog.created|date('h:iA') }}</p>
    <p>Tags: <span class="highlight">{{ blog.tags }}</span></p>
</footer>

{# .. #}

      
      







.



(sidebar)



symblog . .





, . . BlogRepository . BlogRepository

src/Blogger/BlogBundle/Repository/BlogRepository.php
// src/Blogger/BlogBundle/Repository/BlogRepository.php

public function getTags()
{
    $blogTags = $this->createQueryBuilder('b')
                     ->select('b.tags')
                     ->getQuery()
                     ->getResult();

    $tags = array();
    foreach ($blogTags as $blogTag)
    {
        $tags = array_merge(explode(",", $blogTag['tags']), $tags);
    }

    foreach ($tags as &$tag)
    {
        $tag = trim($tag);
    }

    return $tags;
}

public function getTagWeights($tags)
{
    $tagWeights = array();
    if (empty($tags))
        return $tagWeights;

    foreach ($tags as $tag)
    {
        $tagWeights[$tag] = (isset($tagWeights[$tag])) ? $tagWeights[$tag] + 1 : 1;
    }
    // Shuffle the tags
    uksort($tagWeights, function() {
        return rand() > rand();
    });

    $max = max($tagWeights);

    // Max of 5 weights
    $multiplier = ($max > 5) ? 5 / $max : 1;
    foreach ($tagWeights as &$tag)
    {
        $tag = ceil($tag * $multiplier);
    }

    return $tagWeights;
}

      
      







, (CSV) , . getTags(). getTagWeights() , «» , . , .



, .

src/Blogger/BlogBundle/Controller/PageController.php
// src/Blogger/BlogBundle/Controller/PageController.php

public function sidebarAction()
{
    $em = $this->getDoctrine()
               ->getManager();

    $tags = $em->getRepository('BloggerBlogBundle:Blog')
               ->getTags();

    $tagWeights = $em->getRepository('BloggerBlogBundle:Blog')
                     ->getTagWeights($tags);

    return $this->render('BloggerBlogBundle:Page:sidebar.html.twig', array(
        'tags' => $tagWeights
    ));
}

      
      







, 2 BlogRepository , .

src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig #}

<section class="section">
    <header>
        <h3>Tag Cloud</h3>
    </header>
    <p class="tags">
        {% for tag, weight in tags %}
            <span class="weight-{{ weight }}">{{ tag }}</span>
        {% else %}
            <p>There are no tags</p>
        {% endfor %}
    </p>
</section>

      
      









. «» . for , , tag , weight . for, Twig.



BloggerBlogBundle, src/Blogger/BlogBundle/Resources/views/layout.html.twig , (placeholder) . . , Twig render , sidebar Page.



{# src/Blogger/BlogBundle/Resources/views/layout.html.twig #}

{# .. #}

{% block sidebar %}
    {{ render(controller('BloggerBlogBundle:Page:sidebar' ))}} 
{% endblock %}


      
      







.

src/Blogger/BlogBundle/Resources/public/css/sidebar.css
.sidebar .section { margin-bottom: 20px; }
.sidebar h3 { line-height: 1.2em; font-size: 20px; margin-bottom: 10px; font-weight: normal; background: #eee; padding: 5px;  }
.sidebar p { line-height: 1.5em; margin-bottom: 20px; }
.sidebar ul { list-style: none }
.sidebar ul li { line-height: 1.5em }
.sidebar .small { font-size: 12px; }
.sidebar .comment p { margin-bottom: 5px; }
.sidebar .comment { margin-bottom: 10px; padding-bottom: 10px; }
.sidebar .tags { font-weight: bold; }
.sidebar .tags span { color: #000; font-size: 12px; }
.sidebar .tags .weight-1 { font-size: 12px; }
.sidebar .tags .weight-2 { font-size: 15px; }
.sidebar .tags .weight-3 { font-size: 18px; }
.sidebar .tags .weight-4 { font-size: 21px; }
.sidebar .tags .weight-5 { font-size: 24px; }

      
      







, . BloggerBlogBundle main

src/Blogger/BlogBundle/Resources/views/layout.html.twig
{# src/Blogger/BlogBundle/Resources/views/layout.html.twig #}

{# .. #}

{% block stylesheets %}
    {{ parent() }}
    <link href="{{ asset('bundles/bloggerblog/css/blog.css') }}" type="text/css" rel="stylesheet" />
    <link href="{{ asset('bundles/bloggerblog/css/sidebar.css') }}" type="text/css" rel="stylesheet" />
{% endblock %}

{# .. #}

      
      













assets web, assets.

$ php app/console assets:install web

      
      









. , «» (), .







, .



-, . CommentRepository

src/Blogger/BlogBundle/Repository/CommentRepository.php
<?php
// src/Blogger/BlogBundle/Repository/CommentRepository.php

public function getLatestComments($limit = 10)
{
    $qb = $this->createQueryBuilder('c')
                ->select('c')
                ->addOrderBy('c.id', 'DESC');

    if (false === is_null($limit))
        $qb->setMaxResults($limit);

    return $qb->getQuery()
              ->getResult();
}

      
      









sidebar

src/Blogger/BlogBundle/Controller/PageController.php
// src/Blogger/BlogBundle/Controller/PageController.php

public function sidebarAction()
{
    // ..

    $commentLimit   = $this->container
                           ->getParameter('blogger_blog.comments.latest_comment_limit');
    $latestComments = $em->getRepository('BloggerBlogBundle:Comment')
                         ->getLatestComments($commentLimit);

    return $this->render('BloggerBlogBundle:Page:sidebar.html.twig', array(
        'latestComments'    => $latestComments,
        'tags'              => $tagWeights
    ));
}

      
      









blogger_blog.comments.latest_comment_limit . ,

src/Blogger/BlogBundle/Resources/config/config.yml

# src/Blogger/BlogBundle/Resources/config/config.yml

parameters:
    # ..

    # Blogger max latest comments
    blogger_blog.comments.latest_comment_limit: 10


      
      









, .

src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig #}

{# .. #}

<section class="section">
    <header>
        <h3>Latest Comments</h3>
    </header>
    {% for comment in latestComments %}
        <article class="comment">
            <header>
                <p class="small"><span class="highlight">{{ comment.user }}</span> commented on
                    <a href="{{ path('BloggerBlogBundle_blog_show', { 'id': comment.blog.id }) }}#comment-{{ comment.id }}">
                        {{ comment.blog.title }}
                    </a>
                    [<em><time datetime="{{ comment.created|date('c') }}">{{ comment.created|date('Y-m-d h:iA') }}</time></em>]
                </p>
            </header>
            <p>{{ comment.comment }}</p>
            </p>
        </article>
    {% else %}
        <p>There are no recent comments</p>
    {% endfor %}
</section>

      
      









, .







Twig





, , 2011-04-21. , , , , , 3 . Comment , {{comment.created|date (' h:iA Y-m-d')}}.



, Comment. , Twig. Twig , Extension.



extension Twig , . Twig , .

{{ comment.created|created_ago }}. , 2 .







Twig

src/Blogger/BlogBundle/Twig/Extensions/BloggerBlogExtension.php
<?php
// src/Blogger/BlogBundle/Twig/Extensions/BloggerBlogExtension.php

namespace Blogger\BlogBundle\Twig\Extensions;

class BloggerBlogExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
new \Twig_SimpleFilter('created_ago', array($this, 'createdAgo')),        
);
    }

    public function createdAgo(\DateTime $dateTime)
    {
        $delta = time() - $dateTime->getTimestamp();
        if ($delta < 0)
            throw new \InvalidArgumentException("createdAgo is unable to handle dates in the future");

        $duration = "";
        if ($delta < 60)
        {
            // Seconds
            $time = $delta;
            $duration = $time . " second" . (($time > 1) ? "s" : "") . " ago";
        }
        else if ($delta <= 3600)
        {
            // Mins
            $time = floor($delta / 60);
            $duration = $time . " minute" . (($time > 1) ? "s" : "") . " ago";
        }
        else if ($delta <= 86400)
        {
            // Hours
            $time = floor($delta / 3600);
            $duration = $time . " hour" . (($time > 1) ? "s" : "") . " ago";
        }
        else
        {
            // Days
            $time = floor($delta / 86400);
            $duration = $time . " day" . (($time > 1) ? "s" : "") . " ago";
        }

        return $duration;
    }

    public function getName()
    {
        return 'blogger_blog_extension';
    }
}

      
      









. getFilters() , . created_ago. createdAgo, DateTime , DateTime.







, Twig ,

src/Blogger/BlogBundle/Resources/config/services.yml
services:
    blogger_blog.twig.extension:
        class: Blogger\BlogBundle\Twig\Extensions\BloggerBlogExtension
        tags:
            - { name: twig.extension }


      
      









BloggerBlogExtension Twig .







Twig . created_at .

src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig #}

{# .. #}

<section class="section">
    <header>
        <h3>Latest Comments</h3>
    </header>
    {% for comment in latestComments %}
        {# .. #}
        <em><time datetime="{{ comment.created|date('c') }}">{{ comment.created|created_ago }}</time></em>
        {# .. #}
    {% endfor %}
</section>


      
      









http://localhost:8000/ , Twig.



.

src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig
{# src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig #}

{% for comment in comments %}
    <article class="comment {{ cycle(['odd', 'even'], loop.index0) }}" id="comment-{{ comment.id }}">
        <header>
            <p><span class="highlight">{{ comment.user }}</span> commented <time datetime="{{ comment.created|date('c') }}">{{ comment.created|created_ago }}</time></p>
        </header>
        <p>{{ comment.comment }}</p>
    </article>
{% else %}
    <p>There are no comments for this post. Be the first to comment...</p>
{% endfor %}

      
      













Twig, Twig-Extensions GitHub. pull request , , .





Url



URL id . , SEO. , URL http://localhost:8000/1 , - http://localhost:8000/1/a-day-with-symfony2 . slug URL. slug , ASCII .







slug.

src/Blogger/BlogBundle/Resources/config/routing.yml
# src/Blogger/BlogBundle/Resources/config/routing.yml

BloggerBlogBundle_blog_show:
    path:  /{id}/{slug}
    defaults: { _controller: "BloggerBlogBundle:Blog:show" }
    requirements:
        methods:  GET
        id: \d+


      
      











id, slug ,

src/Blogger/BlogBundle/Controller/BlogController.php
// src/Blogger/BlogBundle/Controller/BlogController.php

public function showAction($id, $slug)
{
    // ..
}


      
      







.







, , . Symfony2 . , . defaults.



BloggerBlogBundle_blog_show:
    path:  /{id}/{slug}
    defaults: { _controller: "BloggerBlogBundle:Blog:show", comments: true }
    requirements:
        methods:  GET
        id: \d+

      
      







public function showAction($id, $slug, $comments)
{
    // ..
}

      
      





, http://localhost:8000/1/symfony2-blog $comments true showAction





Slug



, slug , slug. , slug Blog .



Blog


Blog slug.

src/Blogger/BlogBundle/Entity/Blog.php
// src/Blogger/BlogBundle/Entity/Blog.php

class Blog
{
    // ..

    /**
     * @ORM\Column(type="string")
     */
    protected $slug;

    // ..
}

      
      









$slug. .



$ php app/console doctrine:generate:entities Blogger

      
      







.



$ php app/console doctrine:migrations:diff

$ php app/console doctrine:migrations:migrate

      
      







slug slugify symfony1 Jobeet . slugify Blog

src/Blogger/BlogBundle/Entity/Blog.php
// src/Blogger/BlogBundle/Entity/Blog.php

public function slugify($text)
{
    // replace non letter or digits by -
    $text = preg_replace('#[^\\pL\d]+#u', '-', $text);

    // trim
    $text = trim($text, '-');

    // transliterate
    if (function_exists('iconv'))
    {
        $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
    }

    // lowercase
    $text = strtolower($text);

    // remove unwanted characters
    $text = preg_replace('#[^-\w]+#', '', $text);

    if (empty($text))
    {
        return 'n-a';
    }

    return $text;
}

      
      









, slug slug, . setTitle slug. Blog

src/Blogger/BlogBundle/Entity/Blog.php
// src/Blogger/BlogBundle/Entity/Blog.php

public function setTitle($title)
{
    $this->title = $title;

    $this->setSlug($this->title);
}

      
      









setSlug.

src/Blogger/BlogBundle/Entity/Blog.php
// src/Blogger/BlogBundle/Entity/Blog.php

public function setSlug($slug)
{
    $this->slug = $this->slugify($slug);
}


      
      









slug.



$ php app/console doctrine:fixtures:load

      
      











, . .



src/Blogger/BlogBundle/Resources/views/Page/index.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/index.html.twig #}

{% extends 'BloggerBlogBundle::layout.html.twig' %}

{% block body %}
    {% for blog in blogs %}
        <article class="blog">
            <div class="date"><time datetime="{{ blog.created|date('c') }}">{{ blog.created|date('l, F j, Y') }}</time></div>
            <header>
                <h2><a href="{{ path('BloggerBlogBundle_blog_show', { 'id': blog.id, 'slug': blog.slug }) }}">{{ blog.title }}</a></h2>
            </header>

            <img src="{{ asset(['images/', blog.image]|join) }}" />
            <div class="snippet">
                <p>{{ blog.blog(500) }}</p>
                <p class="continue"><a href="{{ path('BloggerBlogBundle_blog_show', { 'id': blog.id, 'slug': blog.slug }) }}">Continue reading...</a></p>
            </div>

            <footer class="meta">
                <p>Comments: <a href="{{ path('BloggerBlogBundle_blog_show', { 'id': blog.id, 'slug': blog.slug }) }}#comments">{{ blog.comments|length }}</a></p>
                <p>Posted by <span class="highlight">{{ blog.author }}</span> at {{ blog.created|date('h:iA') }}</p>
                <p>Tags: <span class="highlight">{{ blog.tags }}</span></p>
            </footer>
        </article>
    {% else %}
        <p>There are no blog entries for symblog</p>
    {% endfor %}
{% endblock %}

      
      







,

src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig #}

{# .. #}

<a href="{{ path('BloggerBlogBundle_blog_show', { 'id': comment.blog.id, 'slug': comment.blog.slug }) }}#comment-{{ comment.id }}">
    {{ comment.blog.title }}
</a>

{# .. #}


      
      









createAction Comment . Comment

src/Blogger/BlogBundle/Controller/CommentController.php
// src/Blogger/BlogBundle/Controller/CommentController.php

public function createAction($blog_id)
{
    // ..

    if ($form->isValid()) {
        // ..

        return $this->redirect($this->generateUrl('BloggerBlogBundle_blog_show', array(
            'id'    => $comment->getBlog()->getId(),
            'slug'  => $comment->getBlog()->getSlug())) .
            '#comment-' . $comment->getId()
        );
    }

    // ..
}

      
      







, http://localhost:8000/ , slug URL.





Symfony2. Symfony2 - . Symfony2 3- :



dev

test

prod



, , - . , . , . , . , . — , ..

test . , unit . , …



Front




. - web/app_dev.php :

$kernel = new AppKernel('dev', true);

      
      





, - , web/app.php :

$kernel = new AppKernel('prod', false);

      
      





, AppKernel .

- app_test.php.





, - , . , . app/config config.yml. , config.yml 3 ; config_dev.yml, config_test.yml config_prod.yml. . config_dev.yml .



imports:
    - { resource: config.yml }

      
      







imports config.yml, imports 2 , config_test.yml config_prod.yml. , config.yml . development, app/config/config_dev.yml , .

# app/config/config_dev.yml
web_profiler:
    toolbar: true

      
      





, .





, .

-, Symfony2.



$ php app/console cache:clear --env=prod

      
      







http://localhost:8000/app.php.



, , . , http://localhost:8000/app.php/999.







, . .



, app/logs/prod.log . , , .







http://localhost:8000/app.php app.php? , , index.html index.php, , app.php ? RewriteRule web/.htaccess



RewriteRule ^(.*)$ app.php [QSA,L]

, , , ^(.*)$ app.php.



Apache, mod_rewrite.c, app.php URL, http://localhost:8000/app.php/.









Symfony2 , , , , . , .

, . cookbook Symfony2, .



Assetic





Symfony2.8 Asseti , assetic. composer.json



"require": {
      //...
       "symfony/assetic-bundle": "dev-master"
    },

      
      







composer update 

      
      





.





app/AppKernel.php
//app/AppKernel.php

  public function registerBundles()
    {
        $bundles = array(
            // ...
            new Symfony\Bundle\AsseticBundle\AsseticBundle(),
        );

        // ...
    }

      
      











app/config/config.yml
# app/config/config.yml
assetic:
    debug:          '%kernel.debug%'
    use_controller: '%kernel.debug%'
    filters:
        cssrewrite: ~

# ...

      
      









Kris Wallsmith Python webassets.



Assetic 2- assets, assets , , JavaScript , . , CSS JavaScript, CoffeeScript CoffeeScript assets , HTTP .



Twig asset assets .

<link href="{{ asset('bundles/bloggerblog/css/blog.css') }}" type="text/css" rel="stylesheet" />

      
      







Assets



Assetic asset :

Assetic asset - , . Asset , .

, assets , , .

Assetic BloggerBlogBundle

app/config/config.yml
# ..
assetic:
    bundles:    [BloggerBlogBundle]
    # ..


      
      









Assetic BloggerBlogBundle , Assetic. bundles .





asset BloggerBlogBundle.
src/Blogger/BlogBundle/Resources/views/layout.html.twig
{# src/Blogger/BlogBundle/Resources/views/layout.html.twig #}

{# .. #}

{% block stylesheets %}
    {{ parent () }}

    {% stylesheets
        '@BloggerBlogBundle/Resources/public/css/*'
    %}
        <link href="{{ asset_url }}" rel="stylesheet" media="screen" />
    {% endstylesheets %}
{% endblock %}

{# .. #}

      
      









2 CSS-, Assetic . Assetic , CSS src/Blogger/BlogBundle/Resources/public/css 1 , . , . HTTP- . * css .

{# src/Blogger/BlogBundle/Resources/views/layout.html.twig #}

{# .. #}

{% block stylesheets %}
    {{ parent () }}

    {% stylesheets
        '@BloggerBlogBundle/Resources/public/css/blog.css'
        '@BloggerBlogBundle/Resources/public/css/sidebar.css'
    %}
        <link href="{{ asset_url }}" rel="stylesheet" media="screen" />
    {% endstylesheets %}
{% endblock %}

{# .. #}

      
      









. * , , CSS , CSS Assetic. , .



HTML http://localhost:8000/ , CSS (, ).



<link href="/css/d8f44a4_part_1_blog_1.css" rel="stylesheet" media="screen" />
<link href="/css/d8f44a4_part_1_sidebar_2.css" rel="stylesheet" media="screen" />

      
      







, 2 . , Assetic 1 CSS . , symblog . Assetic , false

{# src/Blogger/BlogBundle/Resources/views/layout.html.twig #}

{# .. #}

{% stylesheets
    '@BloggerBlogBundle/Resources/public/css/*'
    debug=false
%}
    <link href="{{ asset_url }}" rel="stylesheet" media="screen" />
{% endstylesheets %}

{# .. #}

      
      









, HTML - .

<link href="/css/3c7da45.css" rel="stylesheet" media="screen" />

      
      





, 2 CSS , blog.css sidebar.css 1 . CSS . , output

{% stylesheets
    '@BloggerBlogBundle/Resources/public/css/*'
    output='css/blogger.css'
%}
    <link href="{{ asset_url }}" rel="stylesheet" media="screen" />
{% endstylesheets %}

      
      









, , , assets.



app/Resources/views/base.html.twig
{# app/Resources/views/base.html.twig #}

{# .. #}

{% block stylesheets %}
    <link href='http://fonts.googleapis.com/css?family=Irish+Grover' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=La+Belle+Aurore' rel='stylesheet' type='text/css'>
    {% stylesheets
        'css/*'
    %}
        <link href="{{ asset_url }}" rel="stylesheet" media="screen" />
    {% endstylesheets %}
{% endblock %}

{# .. #}

      
      









JavaScripts


- JavaScript , Assetic ,
{% javascripts
    '@BloggerBlogBundle/Resources/public/js/*'
%}
    <script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}


      
      













Assetic — . assets assets. , , :



CssMinFilter: CSS

JpegoptimFilter: JPEG

Yui\CssCompressorFilter: CSS YUI

Yui\JsCompressorFilter: JavaScript YUI

CoffeeScriptFilter: CoffeeScript JavaScript



Assetic Readme.



, YUI , , , / , .



YUI 2.4.7 ( , , 2.4.8 ), yuicompressor-2.4.7.jar build app/Resources/java/.







Java





Assetic CSS YUI .

app/config/config.yml
# app/config/config.yml

# ..

assetic:
    filters:
        cssrewrite: ~
        yui_css:
            jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"

# ..


      
      









yui_css, YUI Compressor Java . assets , . yui_css

src/Blogger/BlogBundle/Resources/views/layout.html.twig
{# src/Blogger/BlogBundle/Resources/views/layout.html.twig #}

{# .. #}

{% stylesheets
    '@BloggerBlogBundle/Resources/public/css/*'
    output='css/blogger.css'
    filter='yui_css'
%}
    <link href="{{ asset_url }}" rel="stylesheet" media="screen" />
{% endstylesheets %}

{# .. #}


      
      









, Assetic , . , , JavaScript. , ?


{% stylesheets
    '@BloggerBlogBundle/Resources/public/css/*'
    output='css/blogger.css'
    filter='?yui_css'
%}
    <link href="{{ asset_url }}" rel="stylesheet" media="screen" />
{% endstylesheets %}


      
      









assets





, Assetic css javascript . , , Symfony ( ).

assets , , assets . , . , .

, Assetic assets , .

asset.

$ php app/console assetic:dump

      
      







, CSS- web/css blogger.css. , - symblog http://localhost:8000/app.php .







asset , asset web/, Assetic .









Symfony2, Symfony2 Assetic asset . .



. unit . , Symfony2 , , -, , , .



:



https://symfony.com/

http://tutorial.symblog.co.uk/

http://twig.sensiolabs.org/

How to Use Assetic for Asset Management

How to Minify JavaScripts and Stylesheets with YUI Compressor

How to Use Assetic For Image Optimization with Twig Functions

How to Apply an Assetic Filter to a Specific File Extension



Post Scriptum
, , , .




1 — Symfony2

2 — : ,

3 — Doctrine 2

4 — , Doctrine 2

6 —





, . .



All Articles