Commit 07298d66 authored by Dries's avatar Dries

Issue #1911492 by jibran, Manuel Garcia, derhasi, pcambra, dawehner,...

Issue #1911492 by jibran, Manuel Garcia, derhasi, pcambra, dawehner, damiankloip: Fixed Views try to find Custom StylePlugin template in core/modules/views/templates.
parent 6633dfd9
......@@ -24,6 +24,7 @@
* title = @Translation("Block"),
* help = @Translation("Display the view as a block."),
* theme = "views_view",
* register_theme = FALSE,
* uses_hook_block = TRUE,
* contextual_links_locations = {"block"},
* admin = @Translation("Block")
......
......@@ -20,6 +20,7 @@
* title = @Translation("Comment"),
* help = @Translation("Display the comment as RSS."),
* theme = "views_view_row_rss",
* register_theme = FALSE,
* base = {"comment"},
* display_types = {"feed"}
* )
......
......@@ -26,6 +26,7 @@
* admin = @Translation("Entity Reference Source"),
* help = @Translation("Selects referenceable entities for an entity reference field."),
* theme = "views_view",
* register_theme = FALSE,
* uses_hook_menu = FALSE,
* entity_reference_display = TRUE
* )
......
......@@ -21,6 +21,7 @@
* title = @Translation("Entity Reference inline fields"),
* help = @Translation("Displays the fields with an optional template."),
* theme = "views_view_fields",
* register_theme = FALSE,
* display_types = {"entity_reference"}
* )
*/
......
......@@ -21,6 +21,7 @@
* title = @Translation("Entity Reference list"),
* help = @Translation("Returns results as a PHP array of labels and rendered rows."),
* theme = "views_view_unformatted",
* register_theme = FALSE,
* display_types = {"entity_reference"}
* )
*/
......
......@@ -20,6 +20,7 @@
* title = @Translation("Content"),
* help = @Translation("Display the content with standard node view."),
* theme = "views_view_row_rss",
* register_theme = FALSE,
* base = {"node"},
* display_types = {"feed"},
* module = "node"
......
......@@ -13,6 +13,29 @@
use Drupal\views\ViewExecutable;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Base class for any views plugin types.
*
* Via the @Plugin definition the plugin may specify a theme function or
* template to be used for the plugin. It also can auto-register the theme
* implementation for that file or function.
* - theme: the theme implementation to use in the plugin. This may be the name
* of the function (without theme_ prefix) or the template file (without
* template engine extension).
* If a template file should be used, the file has to be placed in the
* module's templates folder.
* Example: theme = "mymodule_row" of module "mymodule" will implement either
* theme_mymodule_row() or mymodule-row.tpl.php in the
* [..]/modules/mymodule/templates folder.
* - register_theme: (optional) When set to TRUE (default) the theme is
* registered automatically. When set to FALSE the plugin reuses an existing
* theme implementation, defined by another module or views plugin.
* - theme_file: (optional) the location of an include file that may hold the
* theme or preprocess function. The location has to be relative to module's
* root directory.
* - module: machine name of the module. It must be present for any plugin that
* wants to register a theme.
*/
abstract class PluginBase extends ComponentPluginBase implements ContainerFactoryPluginInterface {
/**
......
......@@ -247,7 +247,7 @@ public function testViewsFetchPluginNames() {
// Test using the 'test' style plugin type only returns the test_style and
// mapping_test plugins.
$plugins = views_fetch_plugin_names('style', 'test');
$this->assertIdentical(array_keys($plugins), array('mapping_test', 'test_style'));
$this->assertIdentical(array_keys($plugins), array('mapping_test', 'test_style', 'test_template_style'));
// Test a non existent style plugin type returns no plugins.
$plugins = views_fetch_plugin_names('style', $this->randomString());
......
<?php
/**
* @file
* Contains \Drupal\views\Tests\ViewsTemplateTest.
*/
namespace Drupal\views\Tests;
use Drupal\views\Tests\ViewTestBase;
use Drupal\views\Views;
/**
* Tests the views custom templates.
*
* @see Drupal\views_test_data\Plugin\views\style\StyleTemplateTest
*/
class ViewsTemplateTest extends ViewTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_view_display_template');
public static function getInfo() {
return array(
'name' => 'View template tests',
'description' => 'Tests the template retrieval of views.',
'group' => 'Views'
);
}
protected function setUp() {
parent::setUp();
$this->enableViewsTestModule();
}
/**
* Tests render functionality.
*/
public function testTemplate() {
// Make sure that the rendering just calls the preprocess function once.
$view = Views::getView('test_view_display_template');
$output = $view->preview();
// Check if we got the rendered output of our template file.
$this->assertTrue(strpos(drupal_render($output), 'This module defines its own display template.') !== FALSE, 'Display plugin DisplayTemplateTest defines its own template.');
}
}
base_field: id
base_table: views_test_data
core: 8.x
description: ''
status: '1'
display:
default:
display_plugin: default
id: default
display_title: Master
position: '1'
display_options:
access: { }
cache: { }
query: { }
pager: { }
style:
type: test_template_style
row:
type: fields
options: { }
fields:
id:
id: id
table: views_test_data
field: id
relationship: none
group_type: group
admin_label: ''
label: ''
exclude: '0'
alter: { }
provider: views_test_config
filters: { }
sorts: { }
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
label: test_view_display_template
module: views
id: test_view_display_template
tag: ''
uuid: a8e37ebf-573e-4cb9-83f5-a259f12bdc7a
langcode: en
......@@ -17,6 +17,7 @@
* id = "display_no_area_test",
* title = @Translation("Display test no area"),
* theme = "views_view",
* register_theme = FALSE,
* contextual_links_locations = {"view"}
* )
*/
......
......@@ -18,6 +18,7 @@
* id = "display_test",
* title = @Translation("Display test"),
* theme = "views_view",
* register_theme = FALSE,
* contextual_links_locations = {"view"}
* )
*/
......
......@@ -21,6 +21,7 @@
* title = @Translation("Test row plugin"),
* help = @Translation("Provides a generic row test plugin."),
* theme = "views_view_row_test",
* module = "views_test_data",
* display_types = {"normal", "test"}
* )
*/
......
......@@ -22,6 +22,7 @@
* title = @Translation("Field mapping"),
* help = @Translation("Maps specific fields to specific purposes."),
* theme = "views_view_mapping_test",
* module = "views_test_data",
* display_types = {"normal", "test"}
* )
*/
......
<?php
/**
* @file
* Definition of Drupal\views_test_data\Plugin\views\style\StyleTemplateTest.
*/
namespace Drupal\views_test_data\Plugin\views\style;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\views\Plugin\views\style\StylePluginBase;
/**
* Provides a general test style template plugin.
*
* @ingroup views_style_plugins
*
* @Plugin(
* id = "test_template_style",
* module = "views_test_data",
* title = @Translation("Test style template plugin"),
* help = @Translation("Provides a generic style template test plugin."),
* theme = "views_view_style_template_test",
* display_types = {"normal", "test"}
* )
*/
class StyleTemplateTest extends StylePluginBase {
/**
* Can the style plugin use row plugins.
*
* @var bool
*/
protected $usesRowPlugin = TRUE;
}
......@@ -21,6 +21,7 @@
* title = @Translation("Test style plugin"),
* help = @Translation("Provides a generic style test plugin."),
* theme = "views_view_style_test",
* register_theme = FALSE,
* display_types = {"normal", "test"}
* )
*/
......
{#
/**
* @file
* Default theme implementation to display a view of mapping_test rows.
*
* Available variables:
* - rows: A list of view rows.
* - options: Various view options, including the row style mapping.
* - view: The view object.
* - element: Render array of views rows.
*
* @see template_preprocess_views_view_mapping_test()
*
* @ingroup themeable
*/
#}
{{ element }}
{#
/**
* @file
* Views template test template to test the module defined templates.
*/
#}
This module defines its own display template.
......@@ -78,7 +78,10 @@ function views_pre_render_view_element($element) {
}
/**
* Implement hook_theme(). Register views theming functions.
* Implements hook_theme().
*
* Register views theming functions and those that are defined via views plugin
* definitions.
*/
function views_theme($existing, $type, $theme, $path) {
Drupal::moduleHandler()->loadInclude('views', 'inc', 'views.theme');
......@@ -118,7 +121,10 @@ function views_theme($existing, $type, $theme, $path) {
$plugins = views_get_plugin_definitions();
// Register theme functions for all style plugins
// Register theme functions for all style plugins. It provides a basic auto
// implementation of theme functions or template files by using the plugin
// definitions (theme, theme_file, module, register_theme). Template files are
// assumed to be located in the templates folder.
foreach ($plugins as $type => $info) {
foreach ($info as $def) {
// Not all plugins have theme functions, and they can also explicitly
......@@ -126,32 +132,47 @@ function views_theme($existing, $type, $theme, $path) {
if (!isset($def['theme']) || empty($def['register_theme'])) {
continue;
}
// For each theme registration we a base directory to look for the
// templates folder. This will be in any case the root of the given module
// so we always need a module definition.
// @todo: watchdog or exception?
if (!isset($def['provider'])) {
continue;
}
$hooks[$def['theme']] = array(
'variables' => $variables[$type],
);
if ($def['module'] == 'views') {
// For the views module we ensure views.theme.inc is included.
if ($def['provider'] == 'views') {
$def['theme_file'] = 'views.theme.inc';
}
elseif (isset($def['theme_file'])) {
$def['theme_path'] = drupal_get_path('module', $def['module']);
}
// We always use the module directory as base dir.
$module_dir = drupal_get_path('module', $def['provider']);
if (isset($def['theme_path'])) {
$hooks[$def['theme']]['path'] = $def['theme_path'];
}
// The theme_file definition is always relative to the modules directory.
if (isset($def['theme_file'])) {
$hooks[$def['theme']]['path'] = $module_dir;
$hooks[$def['theme']]['file'] = $def['theme_file'];
}
if (isset($def['theme_path']) && isset($def['theme_file'])) {
$include = DRUPAL_ROOT . '/' . $def['theme_path'] . '/' . $def['theme_file'];
// Whenever we got a theme file, we include it directly so we can
// auto-detect the theme function.
if (isset($def['theme_file'])) {
$include = DRUPAL_ROOT . '/' . $module_dir. '/' . $def['theme_file'];
if (is_file($include)) {
require_once $include;
}
}
// If there is no theme function for the given theme definition, we assume
// a template file shall be used. By default this file is located in the
// /templates directory of the module's folder.
// If a module wants to define its own location it has to set
// register_theme of the plugin to FALSE and implement hook_theme() by
// itself.
if (!function_exists('theme_' . $def['theme'])) {
$hooks[$def['theme']]['template'] = drupal_clean_css_identifier($def['theme']);
$hooks[$def['theme']]['path'] = $module_dir;
$hooks[$def['theme']]['template'] = 'templates/' . drupal_clean_css_identifier($def['theme']);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment