Skip to content

Commit

Permalink
Merge 679a794 into 4693d5f
Browse files Browse the repository at this point in the history
  • Loading branch information
kunicmarko20 committed Feb 23, 2018
2 parents 4693d5f + 679a794 commit 020bffc
Show file tree
Hide file tree
Showing 39 changed files with 338 additions and 64 deletions.
2 changes: 1 addition & 1 deletion docs/reference/batch_actions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ of objects to manipulate. We can override this behavior by changing our list tem
{# src/AppBundle/Resources/views/CRUD/list__batch.html.twig #}
{# see @SonataAdmin/CRUD/list__batch.html.twig for the current default template #}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
<input type="checkbox" name="idx[]" value="{{ admin.id(object) }}" />
Expand Down
38 changes: 29 additions & 9 deletions docs/reference/templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,32 @@ specify the templates to use in the ``Admin`` service definition:
.. note::

A ``setTemplates(array $templates)`` (notice the plural) function also exists, that allows
you to set multiple templates at once. Notice that, if used outside of the service definition
context, ``setTemplates(array $templates)`` will replace the whole template list for that
``Admin`` class, meaning you have to explicitly pass the full template list in the
``$templates`` argument.

Changes made using the ``setTemplate()`` and ``setTemplates()`` functions override the customizations
made in the configuration file, so you can specify a global custom template and then override that
customization on a specific ``Admin`` class.
A ``setTemplates(array $templates)`` (notice the plural) method also
exists, that allows you to set multiple templates at once. Notice that,
if used outside of the service definition context,
``setTemplates(array $templates)`` will replace the whole template list
for that ``Admin`` class, meaning you have to explicitly pass the full
template list in the ``$templates`` argument.

Changes made using the ``setTemplate()`` and ``setTemplates()`` methods
override the customizations made in the configuration file, so you can specify
a global custom template and then override that customization on a specific
``Admin`` class.

Finding configured templates
----------------------------
Templates that are set using the ``setTemplate()`` or ``setTemplates()``
methods can be accessed through the ``getTemplate($name)`` method of an
Admin.

Within Twig templates, you can use the ``get_admin_template($name, $adminCode)``
function to access the templates of the current Admin, or the
``get_admin_pool_template($name)`` function to access global templates.

.. code-block:: html+jinja

{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
{# ... #}
{% endblock %}
76 changes: 69 additions & 7 deletions src/Admin/BaseFieldDescription.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ abstract class BaseFieldDescription implements FieldDescriptionInterface
*/
protected $help;

/**
* @var array[] cached object field getters
*/
private static $fieldGetters = [];

public function setFieldName($fieldName): void
{
$this->fieldName = $fieldName;
Expand Down Expand Up @@ -277,6 +282,10 @@ public function getFieldValue($object, $fieldName)
}

if (is_string($fieldName) && '' !== $fieldName) {
if ($this->hasCachedFieldGetter($object, $fieldName)) {
return $this->callCachedGetter($object, $fieldName, $parameters);
}

$camelizedFieldName = Inflector::classify($fieldName);

$getters[] = 'get'.$camelizedFieldName;
Expand All @@ -286,15 +295,21 @@ public function getFieldValue($object, $fieldName)

foreach ($getters as $getter) {
if (method_exists($object, $getter)) {
$this->cacheFieldGetter($object, $fieldName, 'getter', $getter);

return call_user_func_array([$object, $getter], $parameters);
}
}

if (method_exists($object, '__call')) {
$this->cacheFieldGetter($object, $fieldName, 'call');

return call_user_func_array([$object, '__call'], [$fieldName, $parameters]);
}

if (isset($object->{$fieldName})) {
$this->cacheFieldGetter($object, $fieldName, 'var');

return $object->{$fieldName};
}

Expand Down Expand Up @@ -359,7 +374,7 @@ public function getLabel()
return $this->getOption('label');
}

public function isSortable()
public function isSortable(): bool
{
return false !== $this->getOption('sortable', false);
}
Expand All @@ -379,13 +394,60 @@ public function getTranslationDomain()
return $this->getOption('translation_domain') ?: $this->getAdmin()->getTranslationDomain();
}

/**
* Return true if field is virtual.
*
* @return bool
*/
public function isVirtual()
public function isVirtual(): bool
{
return false !== $this->getOption('virtual_field', false);
}

private function getFieldGetterKey($object, $fieldName): ?string
{
if (!\is_string($fieldName)) {
return null;
}
$components = [\get_class($object), $fieldName];
$code = $this->getOption('code');
if (\is_string($code) && '' !== $code) {
$components[] = $code;
}

return implode('-', $components);
}

private function hasCachedFieldGetter($object, $fieldName): bool
{
return isset(
self::$fieldGetters[$this->getFieldGetterKey($object, $fieldName)]
);
}

private function callCachedGetter($object, $fieldName, array $parameters = [])
{
$getterKey = $this->getFieldGetterKey($object, $fieldName);
if (self::$fieldGetters[$getterKey]['method'] === 'getter') {
return \call_user_func_array(
[$object, self::$fieldGetters[$getterKey]['getter']],
$parameters
);
} elseif (self::$fieldGetters[$getterKey]['method'] === 'call') {
return \call_user_func_array(
[$object, '__call'],
[$fieldName, $parameters]
);
}

return $object->{$fieldName};
}

private function cacheFieldGetter($object, $fieldName, $method, $getter = null): void
{
$getterKey = $this->getFieldGetterKey($object, $fieldName);
if (null !== $getterKey) {
self::$fieldGetters[$getterKey] = [
'method' => $method,
];
if (null !== $getter) {
self::$fieldGetters[$getterKey]['getter'] = $getter;
}
}
}
}
4 changes: 4 additions & 0 deletions src/Resources/config/twig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,9 @@
<argument>%sonata.admin.twig.extension.x_editable_type_mapping%</argument>
</call>
</service>
<service id="sonata.templates.twig.extension" class="Sonata\AdminBundle\Twig\Extension\TemplateRegistryExtension" public="false">
<tag name="twig.extension"/>
<argument type="service" id="sonata.admin.pool"/>
</service>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ file that was distributed with this source code.
#}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
{% set route_name = field_description.options.route.name %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ file that was distributed with this source code.
#}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
{% if value %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ file that was distributed with this source code.
#}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
{% set route_name = field_description.options.route.name %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ file that was distributed with this source code.
#}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
{% set route_name = field_description.options.route.name %}
Expand Down
9 changes: 6 additions & 3 deletions src/Resources/views/CRUD/action.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ file that was distributed with this source code.
{% include '@SonataAdmin/CRUD/action_buttons.html.twig' %}
{%- endblock -%}

{% block tab_menu %}
{%- block tab_menu -%}
{% if action is defined %}
{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': sonata_admin.adminPool.getTemplate('tab_menu_template')}, 'twig') }}
{{ knp_menu_render(admin.sidemenu(action), {
'currentClass': 'active',
'template': get_admin_pool_template('tab_menu_template')
}, 'twig') }}
{% endif %}
{% endblock %}
{%- endblock -%}

{% block content %}

Expand Down
7 changes: 6 additions & 1 deletion src/Resources/views/CRUD/base_edit.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ file that was distributed with this source code.
{% include '@SonataAdmin/CRUD/action_buttons.html.twig' %}
{%- endblock -%}

{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': sonata_admin.adminPool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
{%- block tab_menu -%}
{{ knp_menu_render(admin.sidemenu(action), {
'currentClass': 'active',
'template': get_admin_pool_template('tab_menu_template')
}, 'twig') }}
{%- endblock -%}

{% use '@SonataAdmin/CRUD/base_edit_form.html.twig' with form as parentForm %}

Expand Down
2 changes: 1 addition & 1 deletion src/Resources/views/CRUD/base_history.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ file that was distributed with this source code.
{% for revision in revisions %}
<tr class="{% if (currentRevision != false and revision.rev == currentRevision.rev) %}current-revision{% endif %}">
<td>{{ revision.rev }}</td>
<td>{% include admin.getTemplate('history_revision_timestamp') %}</td>
<td>{% include get_admin_template('history_revision_timestamp', admin.code) %}</td>
<td>{{ revision.username|default('label_unknown_user'|trans({}, 'SonataAdminBundle')) }}</td>
<td><a href="{{ admin.generateObjectUrl('history_view_revision', object, {'revision': revision.rev }) }}" class="revision-link" rel="{{ revision.rev }}">{{ "label_view_revision"|trans({}, 'SonataAdminBundle') }}</a></td>
<td>
Expand Down
15 changes: 10 additions & 5 deletions src/Resources/views/CRUD/base_list.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ file that was distributed with this source code.
{% include '@SonataAdmin/CRUD/action_buttons.html.twig' %}
{%- endblock -%}

{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': sonata_admin.adminPool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
{%- block tab_menu -%}
{{ knp_menu_render(admin.sidemenu(action), {
'currentClass': 'active',
'template': get_admin_pool_template('tab_menu_template')
}, 'twig') }}
{%- endblock -%}

{% block title %}
{#
Expand Down Expand Up @@ -91,7 +96,7 @@ file that was distributed with this source code.

{% block table_body %}
<tbody>
{% include admin.getTemplate('outer_list_rows_' ~ admin.getListMode()) %}
{% include get_admin_template('outer_list_rows_' ~ admin.getListMode(), admin.code) %}
</tbody>
{% endblock %}

Expand Down Expand Up @@ -206,7 +211,7 @@ file that was distributed with this source code.
{% endif %}

{% block pager_results %}
{% include admin.getTemplate('pager_results') %}
{% include get_admin_template('pager_results', admin.code) %}
{% endblock %}
</div>
{% endif %}
Expand All @@ -215,7 +220,7 @@ file that was distributed with this source code.
{% block pager_links %}
{% if admin.datagrid.pager.haveToPaginate() %}
<hr/>
{% include admin.getTemplate('pager_links') %}
{% include get_admin_template('pager_links', admin.code) %}
{% endif %}
{% endblock %}
</div>
Expand Down Expand Up @@ -257,7 +262,7 @@ file that was distributed with this source code.

{% block list_filters %}
{% if admin.datagrid.filters %}
{% form_theme form admin.getTemplate('filter') %}
{% form_theme form get_admin_template('filter', admin.code) %}

<div class="col-xs-12 col-md-12 sonata-filters-box" style="display: {{ admin.datagrid.hasDisplayableFilters ? 'block' : 'none' }}" id="filter-container-{{ admin.uniqid() }}">
<div class="box box-primary" >
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/views/CRUD/base_show.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ file that was distributed with this source code.
{% block tab_menu %}
{{ knp_menu_render(admin.sidemenu(action), {
'currentClass' : 'active',
'template': sonata_admin.adminPool.getTemplate('tab_menu_template')
'template': get_admin_pool_template('tab_menu_template')
}, 'twig') }}
{% endblock %}

Expand Down
7 changes: 6 additions & 1 deletion src/Resources/views/CRUD/batch_confirmation.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ file that was distributed with this source code.
{% include '@SonataAdmin/CRUD/action_buttons.html.twig' %}
{%- endblock -%}

{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': sonata_admin.adminPool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
{%- block tab_menu -%}
{{ knp_menu_render(admin.sidemenu(action), {
'currentClass': 'active',
'template': get_admin_pool_template('tab_menu_template')
}, 'twig') }}
{%- endblock -%}

{% block content %}
<div class="sonata-ba-delete">
Expand Down
7 changes: 6 additions & 1 deletion src/Resources/views/CRUD/delete.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ file that was distributed with this source code.
{% include '@SonataAdmin/CRUD/action_buttons.html.twig' %}
{%- endblock -%}

{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': sonata_admin.adminPool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
{%- block tab_menu -%}
{{ knp_menu_render(admin.sidemenu(action), {
'currentClass': 'active',
'template': get_admin_pool_template('tab_menu_template')
}, 'twig') }}
{%- endblock -%}

{% block content %}
<div class="sonata-ba-delete">
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/views/CRUD/list__action.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ file that was distributed with this source code.
#}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
<div class="btn-group">
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/views/CRUD/list__batch.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ file that was distributed with this source code.
#}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
<input type="checkbox" name="idx[]" value="{{ admin.id(object) }}">
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/views/CRUD/list__select.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ file that was distributed with this source code.
#}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
<a class="btn btn-primary" href="{{ admin.generateUrl('list') }}">
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/views/CRUD/list_array.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ file that was distributed with this source code.
#}
{% import '@SonataAdmin/CRUD/base_array_macro.html.twig' as list %}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
{{ list.render_array(value, field_description.options.inline is not defined or field_description.options.inline) }}
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/views/CRUD/list_boolean.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ file that was distributed with this source code.
#}

{% extends admin.getTemplate('base_list_field') %}
{% extends get_admin_template('base_list_field', admin.code) %}

{% set isEditable = field_description.options.editable is defined and field_description.options.editable and admin.hasAccess('edit', object) %}
{% set xEditableType = field_description.type|sonata_xeditable_type %}
Expand Down

0 comments on commit 020bffc

Please sign in to comment.