Преглед на файлове

Merge pull request #2106 from toooni/tab_menu_dropdown

added tab_menu template to use dropdowns in tab menu
Thomas преди 10 години
родител
ревизия
e4c1eaa7ab

+ 1 - 0
DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php

@@ -300,6 +300,7 @@ class AddDependencyCallsCompilerPass implements CompilerPassInterface
             'base_list_field'          => 'SonataAdminBundle:CRUD:base_list_field.html.twig',
             'pager_links'              => 'SonataAdminBundle:Pager:links.html.twig',
             'pager_results'            => 'SonataAdminBundle:Pager:results.html.twig',
+            'tab_menu_template'        => 'SonataAdminBundle:Core:tab_menu_template.html.twig',
         ), $definedTemplates);
 
         $definition->addMethodCall('setTemplates', array($definedTemplates));

+ 1 - 0
DependencyInjection/Configuration.php

@@ -180,6 +180,7 @@ class Configuration implements ConfigurationInterface
                         ->scalarNode('base_list_field')->defaultValue('SonataAdminBundle:CRUD:base_list_field.html.twig')->cannotBeEmpty()->end()
                         ->scalarNode('pager_links')->defaultValue('SonataAdminBundle:Pager:links.html.twig')->cannotBeEmpty()->end()
                         ->scalarNode('pager_results')->defaultValue('SonataAdminBundle:Pager:results.html.twig')->cannotBeEmpty()->end()
+                        ->scalarNode('tab_menu_template')->defaultValue('SonataAdminBundle:Core:tab_menu_template.html.twig')->cannotBeEmpty()->end()
                     ->end()
                 ->end()
 

+ 32 - 0
Resources/doc/reference/advanced.rst

@@ -230,3 +230,35 @@ You will just need to change the way forms are configured in order to take into
             $form->add('year', 'integer');
         }
     }
+
+
+Dropdowns in Tab Menu
+---------------------
+
+You can use dropdowns inside the Tab Menu by default. This can be achieved by using
+the `"dropdown" => true` attribute:
+
+.. code-block:: php
+
+    <?php
+    // YourNS\AdminBundle\Admin\PersonAdmin.php
+
+    protected function configureTabMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null)
+    {
+        // ...other tab menu stuff
+
+        $menu->addChild('comments', array('attributes' => array('dropdown' => true)));
+        $menu['comments']->addChild('list', array('uri' => $admin->generateUrl('listComment', array('id' => $id))));
+        $menu['comments']->addChild('create', array('uri' => $admin->generateUrl('addComment', array('id' => $id))));
+    }
+
+
+If you want to use the Tab Menu in a different way, you can replace the Menu Template:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        sonata_admin:
+            templates:
+                tab_menu_template:  YourNSAdminBundle:Admin:own_tab_menu_template.html.twig

+ 1 - 0
Resources/doc/reference/configuration.rst

@@ -122,6 +122,7 @@ Full Configuration Options
                 base_list_field:      SonataAdminBundle:CRUD:base_list_field.html.twig
                 pager_links:          SonataAdminBundle:Pager:links.html.twig
                 pager_results:        SonataAdminBundle:Pager:results.html.twig
+                tab_menu_template:    SonataAdminBundle:Core:tab_menu_template.html.twig
 
             assets:
                 stylesheets:

+ 1 - 0
Resources/doc/reference/templates.rst

@@ -133,6 +133,7 @@ You can specify your templates in the config.yml file, like so:
                 add_block:           SonataAdminBundle:Core:add_block.html.twig
                 pager_links:         SonataAdminBundle:Pager:links.html.twig
                 pager_results:       SonataAdminBundle:Pager:results.html.twig
+                tab_menu_template:   SonataAdminBundle:Core:tab_menu_template.html.twig
                 history_revision_timestamp:  SonataAdminBundle:CRUD:history_revision_timestamp.html.twig
                 short_object_description:    SonataAdminBundle:Helper:short-object-description.html.twig
                 search_result_block: SonataAdminBundle:Block:block_search_result.html.twig

+ 1 - 1
Resources/views/CRUD/action.html.twig

@@ -18,7 +18,7 @@ file that was distributed with this source code.
 
 {% block tab_menu %}
     {% if action is defined %}
-        {{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active'}, 'list') }}
+        {{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': admin_pool.getTemplate('tab_menu_template')}, 'twig') }}
     {% endif %}
 {% endblock %}
 

+ 1 - 1
Resources/views/CRUD/base_edit.html.twig

@@ -31,7 +31,7 @@ file that was distributed with this source code.
     <li>{% include 'SonataAdminBundle:Button:create_button.html.twig' %}</li>
 {% endblock %}
 
-{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active'}, 'list') }}{% endblock %}
+{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': admin_pool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
 
 {% use 'SonataAdminBundle:CRUD:base_edit_form.html.twig' with form as parentForm %}
 

+ 1 - 1
Resources/views/CRUD/base_list.html.twig

@@ -15,7 +15,7 @@ file that was distributed with this source code.
     <li>{% include 'SonataAdminBundle:Core:create_button.html.twig' %}</li>
 {% endblock %}
 
-{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active'}, 'list') }}{% endblock %}
+{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': admin_pool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
 
 
 {% block list_table %}

+ 1 - 1
Resources/views/CRUD/base_show.html.twig

@@ -18,7 +18,7 @@ file that was distributed with this source code.
     <li>{% include 'SonataAdminBundle:Button:create_button.html.twig' %}</li>
 {% endblock %}
 
-{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active'}, 'list') }}{% endblock %}
+{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': admin_pool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
 
 {% block show %}
     <div class="sonata-ba-view">

+ 1 - 1
Resources/views/CRUD/batch_confirmation.html.twig

@@ -16,7 +16,7 @@ file that was distributed with this source code.
     <li>{% include 'SonataAdminBundle:Button:create_button.html.twig' %}</li>
 {% endblock %}
 
-{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active'}, 'list') }}{% endblock %}
+{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': admin_pool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
 
 {% block content %}
     <div class="sonata-ba-delete">

+ 1 - 1
Resources/views/CRUD/delete.html.twig

@@ -17,7 +17,7 @@ file that was distributed with this source code.
     <li>{% include 'SonataAdminBundle:Button:create_button.html.twig' %}</li>
 {% endblock %}
 
-{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active'}, 'list') }}{% endblock %}
+{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': admin_pool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
 
 {% block content %}
     <div class="sonata-ba-delete">

+ 108 - 0
Resources/views/Core/tab_menu_template.html.twig

@@ -0,0 +1,108 @@
+{% extends 'knp_menu.html.twig' %}
+
+{% block item %}
+{% import "knp_menu.html.twig" as macros %}
+{% if item.displayed %}
+    {%- set attributes = item.attributes %}
+    {%- set is_dropdown = attributes.dropdown|default(false) %}
+    {%- set divider_prepend = attributes.divider_prepend|default(false) %}
+    {%- set divider_append = attributes.divider_append|default(false) %}
+
+{# unset bootstrap specific attributes #}
+    {%- set attributes = attributes|merge({'dropdown': null, 'divider_prepend': null, 'divider_append': null }) %}
+
+    {%- if divider_prepend %}
+        {{ block('dividerElement') }}
+    {%- endif %}
+
+{# building the class of the item #}
+    {%- set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %}
+    {%- if matcher.isCurrent(item) %}
+        {%- set classes = classes|merge([options.currentClass]) %}
+    {%- elseif matcher.isAncestor(item, options.depth) %}
+        {%- set classes = classes|merge([options.ancestorClass]) %}
+    {%- endif %}
+    {%- if item.actsLikeFirst %}
+        {%- set classes = classes|merge([options.firstClass]) %}
+    {%- endif %}
+    {%- if item.actsLikeLast %}
+        {%- set classes = classes|merge([options.lastClass]) %}
+    {%- endif %}
+
+{# building the class of the children #}
+    {%- set childrenClasses = item.childrenAttribute('class') is not empty ? [item.childrenAttribute('class')] : [] %}
+    {%- set childrenClasses = childrenClasses|merge(['menu_level_' ~ item.level]) %}
+
+{# adding classes for dropdown #}
+    {%- if is_dropdown %}
+        {%- set classes = classes|merge(['dropdown']) %}
+        {%- set childrenClasses = childrenClasses|merge(['dropdown-menu']) %}
+    {%- endif %}
+
+{# putting classes together #}
+    {%- if classes is not empty %}
+        {%- set attributes = attributes|merge({'class': classes|join(' ')}) %}
+    {%- endif %}
+    {%- set listAttributes = item.childrenAttributes|merge({'class': childrenClasses|join(' ') }) %}
+
+{# displaying the item #}
+    <li{{ macros.attributes(attributes) }}>
+        {%- if is_dropdown %}
+            {{ block('dropdownElement') }}
+        {%- elseif item.uri is not empty and (not item.current or options.currentAsLink) %}
+            {{ block('linkElement') }}
+        {%- else %}
+            {{ block('spanElement') }}
+        {%- endif %}
+{# render the list of children#}
+        {{ block('list') }}
+    </li>
+
+    {%- if divider_append %}
+        {{ block('dividerElement') }}
+    {%- endif %}
+{% endif %}
+{% endblock %}
+
+{% block dividerElement %}
+{% if item.level == 1 %}
+    <li class="divider-vertical"></li>
+{% else %}
+    <li class="divider"></li>
+{% endif %}
+{% endblock %}
+
+{% block linkElement %}
+	<a href="{{ item.uri }}"{{ macros.attributes(item.linkAttributes) }}>
+		{% if item.attribute('icon') is not empty  %}
+    		<i class="{{ item.attribute('icon') }}"></i> 
+    	{% endif %}
+		{{ block('label') }}
+	</a>
+{% endblock %}
+
+{% block spanElement %}
+	<span>{{ macros.attributes(item.labelAttributes) }}>
+		{% if item.attribute('icon') is not empty  %}
+    		<i class="{{ item.attribute('icon') }}"></i> 
+    	{% endif %}
+		{{ block('label') }}
+	</span>
+{% endblock %}
+
+{% block dropdownElement %}
+    {%- set classes = item.linkAttribute('class') is not empty ? [item.linkAttribute('class')] : [] %}
+    {%- set classes = classes|merge(['dropdown-toggle']) %}
+    {%- set attributes = item.linkAttributes %}
+    {%- set attributes = attributes|merge({'class': classes|join(' ')}) %}
+    {%- set attributes = attributes|merge({'data-toggle': 'dropdown'}) %}
+    <a href="#"{{ macros.attributes(attributes) }}>
+    	{% if item.attribute('icon') is not empty  %}
+    		<i class="{{ item.attribute('icon') }}"></i> 
+    	{% endif %}
+    	{{ block('label') }} 
+    	<b class="caret"></b>
+    </a>
+{% endblock %}
+
+{% block label %}{{ item.label|trans }}{% endblock %}

+ 7 - 5
Resources/views/standard_layout.html.twig

@@ -237,11 +237,13 @@ file that was distributed with this source code.
                                 {% block sonata_page_content_nav %}
                                     {% if _tab_menu is not empty or _actions is not empty %}
                                         <nav class="navbar navbar-default" role="navigation">
-                                            {% if _navbar_title is not empty %}
-                                                <div class="navbar-header">
-                                                    <span class="navbar-brand">{{ _navbar_title|raw }}</span>
-                                                </div>
-                                            {% endif %}
+                                            {% block tab_menu_navbar_header %}
+                                                {% if _navbar_title is not empty %}
+                                                    <div class="navbar-header">
+                                                        <span class="navbar-brand">{{ _navbar_title|raw }}</span>
+                                                    </div>
+                                                {% endif %}
+                                            {% endblock %}
                                             <div class="container-fluid">
                                                 <div class="navbar-left">
                                                     {% if _tab_menu is not empty %}