drupal视图创建

tech2022-09-06  95

drupal视图创建

Views is in Drupal 8 core. We all know that by now. Twig is the new templating engine in Drupal 8. This we also know. But do we know how to interact programmatically with the first in order to theme a View using the second? Aside from overriding View templates like with any other subsystem, we have available a more powerful alternative in the form of Views plugins (Display, Style, Row and Field).

视图位于Drupal 8核心中。 现在我们都知道。 Twig是Drupal 8中的新模板引擎。我们也知道这一点。 但是,我们是否知道如何通过编程方式与第一个交互以便使用第二个为主题设置View? 除了像其他子系统一样覆盖View模板之外,我们还提供了Views插件(Display,Style,Row和Field )形式更强大的替代方案。

In this article, we are going to look at how we can create a custom Style plugin for Views in Drupal 8. We will use the Bootstrap tab markup as a goal and implement a tabbed output for our View results. In the View configuration, the Style settings will allow us to specify which field will be used as the tab navigation copy, leaving the rest of the fields shown in the respective tab panes. Basically, each View result will represent a tab – so this example is not suited for Views which have more than a few results. The main goal is to illustrate how we can create our own Views Style plugins in Drupal 8.

在本文中,我们将研究如何在Drupal 8中为Views创建自定义样式插件。我们将使用Bootstrap选项卡标记作为目标,并为View结果实现选项卡式输出。 在“视图”配置中,“样式”设置将允许我们指定哪个字段将用作选项卡导航副本,其余字段显示在相应的选项卡窗格中。 基本上,每个视图结果都将代表一个选项卡–因此,该示例不适用于具有多个结果的视图。 主要目的是说明如何在Drupal 8中创建自己的Views Style插件。

We will not cover the details on how you can use Bootstrap in your project. However, you can check out the documentation page on assets or even this article on how to make sure anonymous users can benefit from jQuery being loaded on the page. And if you want to see the code we write ahead of time, you can find it in this repository within the Demo module.

我们将不介绍有关如何在项目中使用Bootstrap的详细信息。 但是,你可以检查出资产文档页面 ,甚至这篇文章就如何确保匿名用户可以从jQuery的加载页面上受益。 而且,如果您想查看我们提前编写的代码,可以在此存储库中的Demo模块中找到它。

什么是样式插件? (What Is the Style Plugin?)

The Views Style plugin is the one responsible for rendering the listing. Notable examples of core Style plugins are Unformatted List, HTML List, Table or Grid. They are used by the Display plugin and they in turn use Row plugins that represent one item in the listing.

Views Style插件是负责呈现列表的插件。 核心样式插件的显着示例是Unformatted List , HTML List , Table或Grid 。 它们由Display插件使用,而它们又使用代表清单中一项的Row插件。

In Drupal 8, all Views plugin types are built using the new Plugin system and share some common functionality (they always extend from the same Views PluginBase).

在Drupal 8中,所有Views插件类型都是使用新的Plugin系统构建的,并具有一些共同的功能(它们总是从同一个Views PluginBase )。

Let’s now create our own such Style plugin that can be used by most Display types (Page, Block, etc) and which uses the Field row plugin.

现在,让我们创建自己的样式插件,该插件可用于大多数显示类型(页面,块等),并使用字段行插件。

Bootstrap Tabs样式插件 (The Bootstrap Tabs Style Plugin)

The first step is to create our plugin class located in the Plugin/views/style folder of our module:

第一步是在模块的Plugin/views/style文件夹中创建我们的插件类:

namespace Drupal\demo\Plugin\views\style; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\style\StylePluginBase; /** * A Views style that renders markup for Bootstrap tabs. * * @ingroup views_style_plugins * * @ViewsStyle( * id = "bootstrap_tabs", * title = @Translation("Bootstrap Tabs"), * help = @Translation("Uses the Bootstrap Tabs component."), * theme = "demo_bootstrap_tabs", * display_types = {"normal"} * ) */ class BootstrapTabs extends StylePluginBase { /** * Does this Style plugin allow Row plugins? * * @var bool */ protected $usesRowPlugin = TRUE; /** * Does the Style plugin support grouping of rows? * * @var bool */ protected $usesGrouping = FALSE; /** * {@inheritdoc} */ protected function defineOptions() { $options = parent::defineOptions(); $options['tab_nav_field'] = array('default' => ''); return $options; } /** * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $options = $this->displayHandler->getFieldLabels(TRUE); $form['tab_nav_field'] = array( '#title' => $this->t('The tab navigation field'), '#description' => $this->t('Select the field that will be used as the tab navigation. The rest of the fields will show up in the tab content.'), '#type' => 'select', '#default_value' => $this->options['tab_nav_field'], '#options' => $options, ); } }

The Drupal plugin type we are creating an instance of is ViewsStyle with some basic configuration passed in the annotation. Leaving aside the obvious ones, we have the theme and display_types keys that are worth mentioning. The first declares which theme function this Style plugin will use to render its data while the second declares which kinds of Display plugins this Style can be used by (in our case all Display types which don’t otherwise specify a custom type: normal). For more information on all the available annotation configuration for this plugin type, check out the Drupal\views\Annotation\ViewsStyle annotation class.

我们正在创建的Drupal插件类型是ViewsStyle ,并在批注中传递了一些基本配置。 除了显而易见的以外,我们还有值得一提的theme和display_types键。 第一个声明此Style插件将使用哪个主题函数来呈现其数据,而第二个声明该Style可以使用哪种Display插件(在本例中,所有其他未指定自定义类型的Display类型:normal)。 有关此插件类型的所有可用注释配置的更多信息,请查看Drupal\views\Annotation\ViewsStyle注释类。

Using the two class properties, we declare that our Style uses row plugins but does not allow grouping. Make sure you check out the parent classes to learn more about what other options can be specified like this. For example, the class we are extending already declares that Views fields can be used with the Style plugin.

使用这两个类属性,我们声明我们的Style使用行插件,但不允许分组。 确保您签出父类,以了解有关可以指定哪些其他选项的更多信息。 例如,我们正在扩展的类已经声明View字段可以与Style插件一起使用。

As mentioned before, using the two methods we create a plugin option and form element to be able to specify which field should act as the tab navigation. Using the current display handler ($this->displayHandler) we can load up all the available View fields the site builder has added to it. And this new form element will be available on the Style settings form:

如前所述,使用这两种方法,我们创建了一个插件选项和一个form元素,以便能够指定哪个字段应充当选项卡导航。 使用当前的显示处理程序( $this->displayHandler ),我们可以加载网站构建器已添加到其中的所有可用View字段。 并且此新表单元素将在“样式”设置表单上可用:

Since we are extending from the StylePluginBase class, there is nothing more we need to do. For the markup output we can rely on the demo_bootstrap_tabs theme which receives the relevant variables from the executed View. If we want, we can override any of the render methods and add more variables, change the theme, or whatever we need. We are good with the defaults, especially since we will implement a preprocessor to handle the variables that the template receives.

由于我们是从StylePluginBase类扩展而来的,因此我们无需执行其他任何操作。 对于标记输出,我们可以依靠demo_bootstrap_tabs主题,该主题从已执行的View接收相关变量。 如果需要,我们可以覆盖任何渲染方法并添加更多变量,更改主题或我们需要的任何内容。 我们对默认值很满意,特别是因为我们将实现一个预处理器来处理模板接收的变量。

主题 (The Theme)

It’s time to define the demo_bootstrap_tabs theme as we normally do (inside our .module file):

现在是时候像我们通常那样(在.module文件中)定义demo_bootstrap_tabs主题了:

/** * Implements hook_theme(). */ function demo_theme($existing, $type, $theme, $path) { return array( 'demo_bootstrap_tabs' => array( 'variables' => array('view' => NULL, 'rows' => NULL), 'path' => drupal_get_path('module', 'demo') . '/templates', ), ); }

The Style plugin passes the $view object and the resulting $rows by default to the template. It is up to the preprocessor to do a bit of handling of these variables (if needed) before they are sent to the template:

样式插件默认将$view对象和生成的$rows传递给模板。 在将这些变量发送到模板之前,要由预处理器进行一些处理(如果需要):

/** * Prepares variables for views demo_bootstrap_tabs template. * * Template: demo-bootstrap-tabs.html.twig. * * @param array $variables * An associative array containing: * - view: The view object. * - rows: An array of row items. Each row is an array of content. */ function template_preprocess_demo_bootstrap_tabs(&$variables) { $view = $variables['view']; $rows = $variables['rows']; $variables['nav'] = array(); // Prepare the tab navigation. $field = $view->style_plugin->options['tab_nav_field']; if (!$field || !isset($view->field[$field])) { template_preprocess_views_view_unformatted($variables); return; } $nav = array(); foreach ($rows as $id => $row) { $nav[$id] = array( '#theme' => 'views_view_field', '#view' => $view, '#field' => $view->field[$field], '#row' => $row['#row'], ); } template_preprocess_views_view_unformatted($variables); $variables['nav'] = $nav; }

So what’s happening here? First, we check the Style plugin options for the field name to be used (the one that was selected when configuring the View). If one is not there, we return, but not before doing a bit of default preprocessing that the template_preprocess_views_view_unformatted function already does well. So we delegate to it. Then, we loop through the Views results and build an array of content for our tab navigation. For this, we use the default Views views_view_field theme function to render the selected field. Finally, we pass this array to the template and also run the default preprocessor of the unformatted list style.

那么这是怎么回事? 首先,我们检查样式插件选项中要使用的字段名称(配置视图时选择的字段名称)。 如果不存在,我们将返回,但在进行一些默认的预处理之前,我们不会返回template_preprocess_views_view_unformatted函数已经很好地完成了。 因此,我们委托给它。 然后,我们遍历“视图”结果并为选项卡导航构建内容数组。 为此,我们使用默认的Views views_view_field主题函数来呈现所选字段。 最后,我们将此数组传递给模板,并运行未格式化列表样式的默认预处理器。

模板 (The Template)

In Drupal 8 there are no more theme functions, everything is now handled in Twig templates. So let’s see how the demo-bootstrap-tabs.html.twig file looks like in our module’s templates folder:

在Drupal 8中,不再有主题功能,现在所有内容都在Twig模板中处理。 因此,让我们看看demo-bootstrap-tabs.html.twig文件在我们模块的templates文件夹中的样子:

<div> <!-- Nav tabs --> <ul class="nav nav-tabs" role="tablist"> {% for tab in nav %} {% set active = '' %} {% if loop.index0 == 0 %} {% set active = 'active' %} {% endif %} <li role="presentation" class="{{ active }}"><a href="#tab-{{ loop.index0 }}" aria-controls="profile" role="tab" data-toggle="tab">{{ tab }}</a></li> {% endfor %} </ul> <!-- Tab panes --> <div class="tab-content"> {% for row in rows %} {% set active = '' %} {% if loop.index0 == 0 %} {% set active = 'active' %} {% endif %} <div role="tabpanel" class="tab-pane {{ active }}" id="tab-{{ loop.index0 }}">{{ row.content }}</div> {% endfor %} </div> </div>

As you can see, this is the necessary markup for the Bootstrap tabs. It won’t work, of course, without making sure the relevant Bootstrap styles and script are loaded in your theme first.

如您所见,这是Bootstrap选项卡的必要标记。 当然,如果没有确保首先将相关的Bootstrap样式和脚本加载到主题中,它将无法正常工作。

The first thing we render are the tab navigation items (from our nav variable). While looping through this array, we also make use of the loop index value in order to default the first item as active and be able to target the tab content panes below using unique IDs. For the actual value of the items, we just print the render array we created in our preprocessor and Drupal takes care of rendering that. That being said, it is probably a good idea to make sure that the field you use here is relatively short, without a link and plain markup. Titles would probably work just fine. But this is a matter of configuring the View accordingly.

我们呈现的第一件事是标签导航项(来自我们的nav变量)。 在遍历此数组时,我们还使用循环索引值,以便将第一项默认设置为活动状态,并能够使用唯一ID定位下面的选项卡内容窗格。 对于项的实际值,我们只打印在预处理器中创建的渲染数组,Drupal负责渲染。 话虽如此,确保您在此处使用的字段相对较短,没有链接和简单标记是一个好主意。 标题可能会很好。 但这是相应地配置视图的问题。

Below the navigation, we print the actual view rows, using the same loop index to default the first row as the active tab pane and identify them uniquely so the navigation above can control their visibility. As for the content, we print the entire row.content variable (which is prepared inside template_preprocess_views_view_unformatted) and which contains all the fields in our View. And if we want to not include the field we used for the navigation, we can just exclude that one from display in the View configuration. It will still appear in the navigation (because we explicitly print it there) but not in the main tab pane.

在导航下方,我们打印实际的视图行,使用相同的循环索引将第一行默认为活动的选项卡窗格,并对其进行唯一标识,以便上方的导航可以控制其可见性。 至于内容,我们将打印整个row.content变量(在template_preprocess_views_view_unformatted内部准备),并且包含View中的所有字段。 如果我们想不包括我们用于导航领域中,我们就可以排除在查看配置一个从显示器。 它仍然会出现在导航中(因为我们在此处明确地打印了它),但没有出现在主选项卡窗格中。

结论 (Conclusion)

And there we have it. A Views Style plugin to output the View results as Bootstrap tabs. All we need now is to make sure the Bootstrap assets are loaded and simply configure our View to use the new Style plugin. Do keep in mind that this is not meant for Views with lots of results and it only serves as an example to demonstrate how to create Style plugins.

我们终于得到它了。 一个Views Style插件,用于将View结果输出为Bootstrap选项卡。 现在,我们需要确保已加载Bootstrap资产,并只需将View配置为使用新的Style插件。 请记住,这并不适用于具有大量结果的视图,而只是作为示例说明如何创建样式插件。

If you have questions, comments, or suggestions, please leave them below!

如果您有任何问题,意见或建议,请留在下面!

翻译自: https://www.sitepoint.com/theming-views-in-drupal-8-custom-style-plugins/

drupal视图创建

相关资源:drupal_block_reactive:Drupal 8,ES2015(w Babel)和React.js-源码
最新回复(0)