#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. Извините за включение такого количества файлов, я хотел сделать это как можно более понятным, если что-то неясно, дайте мне знать.
Счастливого чистого кодирования!