douren6035 2016-10-09 20:24
浏览 37

在Symfony 3中自动包含动作专用的JS / CSS

I often have some CSS rules and JavaScript functions that are only used in a single Twig file that is rendered by a single controller action. I use seperate files for those CSS rules and JavaScript functions and structured them like this:

Bundle File Structure

I have one controller Jd34TestController in this bundle that contains the frontAction and requestAction, rendering front.html.twig and request.html.twig. Both Twig files include one common Twig file, app/Resources/views/base.html.twig. I am looking for a way to automatically (magically) include Jd34Test/front.js and Jd34Test/front.css when Jd34Test/front.html.twig is rendered and the same for the request action and any other action. If any of these css/js files doesn't exist, it should skip that including and don't throw exceptions.

What is the best approach to automate this? I tried using Twig_Extension functions and macros, but it seems too risky to guess the css/js paths based on the return value of $this->requestStack->getCurrentRequest()->get('_controller').

  • 写回答

1条回答 默认 最新

  • duanne9313 2016-10-11 08:48
    关注

    I work on huge web apps and I basically use the same structure as you where I only include JS and CSS files in twig files that need them. Sometimes you find that a certain JS plugin is only needed on a certain page and not on others, as such it only makes sense to insert it only on the page that requires it. This is what I do.

    Depending on how big, in terms of features and pages, the app is; I can have a single base.html.twig file and multilple layout.html.twig files that extends base.html.twig file. This way, base.html.twig only has the css and js files that are required by all layout.html.twig files. Then each layout.html.twig file includes JS and CSS files required by all files that will extend it. Say you have three pages that extend a certain layout.html.twig file, they will all have the JS and CSS of that layout.html.twig file and each can add extra JS and CSS required.

    Here is how I do it:

    base.html.twig would look something like this:

    <!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>
    

    Notice the {% block pageCSS %}, this is where your page specific CSS will go and same for JS in {% block pagescript %}.

    Here is how a page that extends base.html.twig would look like:

    {% 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 %}
    

    The key here is to use [Template Inheritance (Twig inheritance)][1] by defining blocks. It will make your code much more manageable, not to mention better rendering.

    I believe this is much easier and cleaner than injecting the files via the controller.

    PS. Sorry for including so many files, I wanted to make it as clearer as possible, if anything is unclear, give me a shout.

    Happy clean coding!

    评论

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)