Автоматическое включение action-exclusive JS / CSS в Symfony 3

#php #twig #symfony #twig-extension

#php #twig #symfony #twig-расширение

Вопрос:

У меня часто есть некоторые правила CSS и функции JavaScript, которые используются только в одном файле Twig, который отображается одним действием контроллера. Я использую отдельные файлы для этих правил CSS и функций JavaScript и структурировал их следующим образом:

Структура файла пакета

У меня есть один контроллер Jd34TestController в этом пакете, который содержит frontAction и requestAction , рендеринг front.html.twig и request.html.twig . Оба файла Twig включают один общий файл Twig, app/Resources/views/base.html.twig . Я ищу способ автоматического (волшебного) включения Jd34Test/front.js и Jd34Test/front.css Jd34Test/front.html.twig отображения, а также то же самое для действия запроса и любого другого действия. Если какой-либо из этих файлов css / js не существует, он должен пропустить это включение и не создавать исключения.

Каков наилучший подход для автоматизации этого? Я пытался использовать Twig_Extension функции и макросы, но кажется слишком рискованным угадывать пути css / js на основе возвращаемого значения $this->requestStack->getCurrentRequest()->get('_controller') .

Ответ №1:

Я работаю над огромными веб-приложениями и в основном использую ту же структуру, что и вы, где я включаю только файлы JS и CSS в файлы twig, которые в них нуждаются. Иногда вы обнаруживаете, что определенный JS-плагин нужен только на определенной странице, а не на других, поэтому имеет смысл вставлять его только на страницу, которая этого требует. Это то, что я делаю.

В зависимости от размера приложения с точки зрения функций и страниц; У меня может быть один файл base.html.twig и несколько файлов layout.html.twig, которые расширяют файл base.html.twig. Таким образом, base.html.twig содержит только файлы css и js, которые требуются для всех файлов layout.html.twig. Затем каждый файл layout.html.twig включает файлы JS и CSS, необходимые для всех файлов, которые будут его расширять. Допустим, у вас есть три страницы, которые расширяют определенный файл layout.html.twig, все они будут иметь JS и CSS этого файла layout.html.twig, и каждая из них может добавить необходимые дополнительные JS и CSS.

Вот как я это делаю:

base.html.twig будет выглядеть примерно так:

 <!DOCTYPE html>
<!--[if IE 8]> <html lang="en" class="ie8 no-js"> <![endif]-->
<!--[if IE 9]> <html lang="en" class="ie9 no-js"> <![endif]-->
<!--[if !IE]><!-->
<html lang="en" class="no-js">
<!--<![endif]-->
<!-- BEGIN HEAD -->
<head>
    <meta charset="utf-8">
    {% block mainPageTitle %}
        <title>Snappic | Photobooth Software</title>
    {% endblock %}
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <meta content="" name="description">
    <meta content="" name="author">

    <!-- BEGIN GLOBAL MANDATORY STYLES -->
    {% stylesheets
    "bundles/snappicadmin/css/layout/components-md.css"
    "bundles/snappicadmin/plugins/bootstrap/css/bootstrap.css"
    "bundles/snappicadmin/plugins/web-icons/web-icons.min.css"
    "bundles/snappicadmin/css/layout/layout.css"%}

    <link rel="stylesheet" href="{{ asset_url }}" />

    {% endstylesheets %}

    <!-- END GLOBAL MANDATORY STYLES -->

    <!-- BEGIN PAGE SPECIFIC STYLES -->

    {% block pageCSS %}
    {% endblock %}

    <!-- END PAGE STYLES -->


    <link rel="icon" href="{{ asset('bundles/snappicadmin/images/icon/plain_logo-32x32.png') }}" sizes="32x32" />

</head>
<!-- END HEAD -->
<!-- BEGIN BODY -->

<body class="page-md">

    <!-- GENERAL LAYOUT CONTENT HERE e.g Main menu -->


    {% block content %}
    {% endblock %}

<!-- BEGIN JAVASCRIPTS -->
<!-- BEGIN CORE PLUGINS -->
<!--[if lt IE 9]>
{% javascripts
"@SnappicAdminBundle/Resources/public/plugins/respond.min.js"
"@SnappicAdminBundle/Resources/public/plugins/excanvas.min.js"%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
<![endif]-->

{% javascripts
"@SnappicAdminBundle/Resources/public/plugins/fullcalendar/lib/moment.min.js"
"@SnappicAdminBundle/Resources/public/plugins/jquery.browser.min.js"
"@SnappicAdminBundle/Resources/public/js/utilities/utilities.js"
"@SnappicAdminBundle/Resources/public/plugins/jquery.min.js"%}

<script src="{{ asset_url }}"></script>

{% endjavascripts %}


{% block pagescript %}
{% endblock %}


<script>

    jQuery(document).ready(function() {
        App.init(); 
        Layout.init(); 

        initSlideOut();
    });
</script>
<!-- END JAVASCRIPT -->
</body>
<!-- END BODY -->
</html>
  

Обратите {% block pageCSS %} внимание, что именно здесь будет использоваться CSS, специфичный для вашей страницы, и то же самое для JS {% block pagescript %} .

Вот как будет выглядеть страница, расширяющая base.html.twig:

 {% extends "@SnappicAdmin/Layout/base.html.twig" %}

{% block mainPageTitle %}<title>Snappic - Dashboard</title>{% endblock %}

{% block pageCSS %}
    {% stylesheets
    "bundles/snappicadmin/css/layout/plugins.min.css"
    "@SnappicAdminBundle/Resources/public/css/dashboard/dashboard.css"%}

    <link rel="stylesheet" href="{{ asset_url }}" />

    {% endstylesheets %}
{% endblock %}

 {% block content %}
     <!-- BEGIN PAGE CONTENT INNER -->
        This is where your page content goes
     <!-- END PAGE CONTENT INNER -->
{% endblock %}

 {% block pagescript %}
     {% javascripts
     "bundles/snappicadmin/plugins/fullcalendar/lib/moment.min.js"
     "@SnappicAdminBundle/Resources/public/js/dashboard/dashboard.js"
     %}

     <script src="{{ asset_url }}"></script>

     {% endjavascripts %}

 {% endblock %}
  

Ключевым моментом здесь является использование [Наследование шаблонов (наследование веток)][1] путем определения блоков. Это сделает ваш код намного более управляемым, не говоря уже о лучшем рендеринге.

Я считаю, что это намного проще и чище, чем вводить файлы через контроллер.

PS. Извините за включение такого количества файлов, я хотел сделать это как можно более понятным, если что-то неясно, дайте мне знать.

Счастливого чистого кодирования!