drupal视图创建
In this article you are going to learn how to expose the table created by your Drupal module to Views. Why would you like to do this? Views is a powerful module for querying and displaying information and can save you a lot of hassle when dealing with the custom data your module produces.
在本文中,您将学习如何将Drupal模块创建的表暴露给View。 您为什么要这样做? Views是用于查询和显示信息的功能强大的模块,在处理模块生成的自定义数据时可以节省很多麻烦。
The focus of this tutorial will be on data that is not abstracted as Drupal entities, but simply stored in a table. Exposing custom entities to Views is a topic I covered in another Sitepoint.com series so I recommend reading up on that if this is the case for you – here is a list of my articles.
本教程的重点将放在不是抽象为Drupal实体而是仅存储在表中的数据上。 将自定义实体暴露给View是我在另一个Sitepoint.com系列文章中讨论的主题,因此,如果您是这种情况,我建议您仔细阅读- 这是我的文章列表。
I set up a module called expose in this repository that you can clone, follow along and even build on if you want to learn more. The master branch contains a clean module that simply creates the table I will use in this article to illustrate the process. The exposed-table branch contains, commit by commit, the steps I go through below.
我在此存储库中设置了一个名为expose的模块,如果您想了解更多信息 ,可以克隆,遵循它,甚至在此基础上构建。 master分支包含一个干净的模块,该模块仅创建将在本文中用于说明此过程的表。 exposed-table分支包含我在下面逐个提交的步骤。
Since the schema definition is in the module, I will not repeat it here. I will however give you a short MySQL command to generate a couple of dummy records to have something to play with. Hopefully this command is informative enough to describe the table structure as well:
由于模式定义位于模块中,因此在此不再赘述。 但是,我将给您一个简短MySQL命令,以生成几个虚拟记录以供您使用。 希望该命令也能提供足够的信息来描述表结构:
INSERT INTO `exposed` (`id`, `name`, `deadline`, `node_id`) VALUES (1, 'Danny', 1399477939, 1), (2, 'Peter', 1399477957, 2);There are two main steps we need to take to expose our exposed table to Views: make Views aware of our module and its Views related files and tell it about the structure of our table. The second step is the complex one where you can have various degrees of customization.
我们需要采取两个主要步骤将exposed表exposed给View:使View知道我们的模块及其与Views相关的文件,并告知其表的结构。 第二步是复杂的步骤,您可以在其中进行各种程度的自定义。
But first things first, the implementation of hook_views_api():
但是首先要注意的是hook_views_api()的实现:
/** * Implements hook_views_api(). */ function expose_views_api() { return array( 'api' => 3, 'path' => drupal_get_path('module', 'expose') . '/includes/views', ); }This is a very simple implementation in which we tell which Views API our module uses and the location of where the Views related include files will be placed. The hook_views_api() implementation goes in the .module file.
这是一个非常简单的实现,其中我们告诉我们模块使用哪个Views API以及将放置Views相关包含文件的位置。 hook_views_api()实现位于.module文件中。
Next, it’s time to implement hook_views_data(), this time in a file called expose.views.inc located in the folder we specified above (/includes/views/):
接下来,是时候实现hook_views_data()了 ,这次是在我们上面指定的文件夹( /includes/views/ )中的一个名为expose.views.inc的文件中:
/** * Implements hook_views_data(). */ function expose_views_data() { $data = array(); $data['exposed']['table']['group'] = t('Exposed'); $data['exposed']['table']['base'] = array( 'title' => t('Exposed'), 'help' => t('Contains records we want exposed to Views.'), ); return $data; }With this implementation we tell Views all about our table in a big array that we return at the end. First, we need to specify the group our table will be part of. This will be used to identify where the table fields come from in the UI. Next, we tell Views that the exposed table is a base table (hence the base index). This means we can create a View that uses this table to start from – as the main query. And as you can see, for both pieces of information, the exposed key is actually the name of the table in the database.
通过此实现,我们以大数组的形式告诉Views所有有关表的内容,最后将其返回。 首先,我们需要指定表将属于的组。 这将用于标识表字段在UI中的位置。 接下来,我们告诉Views exposed表是基表(因此有base引)。 这意味着我们可以创建一个使用此表作为起点的视图–作为主要查询。 如您所见,对于这两条信息, exposed键实际上是数据库中表的名称。
These are the first two steps that will already allow us to see some changes in the UI. Clear the cache and add a new View. You’ll notice that next to Content, User, etc, you now have Exposed as well as a type of data. This is from when we defined the table as being a base one. However, if you continue and edit the View now, you’ll see a broken handler in the Fields section and none of the table columns can be found as fields. It follows to declare them to Views as well.
这是前两个步骤,已经使我们能够看到UI中的某些更改。 清除缓存并添加一个新的视图。 您会注意到,在Content , User等旁边,您现在已经拥有Exposed以及一种数据。 这是从我们将表定义为基础表开始的。 但是,如果继续并立即编辑“视图”,则在“ Fields部分中将看到一个损坏的处理程序,并且找不到任何表列作为字段。 接下来也将它们声明为Views。
Now that Views knows about our table, let’s tell it also how to handle the table columns for displaying, filtering and sorting. The way to do this is by specifying some metadata about each column (like title and description) and which Views handler to use for this field for a given task. Let’s see how to do this for the first three columns on our table: id, name, deadline. Inside the hook_views_data() implementation, paste the following right before $data gets returned:
现在,Views知道了我们的表,让我们也告诉它如何处理表列以进行显示,过滤和排序。 完成此操作的方法是通过指定有关每列的一些元数据(例如标题和描述),以及为给定任务将此字段使用哪个Views处理程序。 让我们看看如何在表格的前三列中执行此操作: id , name , deadline 。 在hook_views_data()实现内部,在返回$data之前粘贴以下内容:
// The ID field $data['exposed']['id'] = array( 'title' => t('ID'), 'help' => t('The record ID.'), 'field' => array( 'handler' => 'views_handler_field_numeric', ), 'sort' => array( 'handler' => 'views_handler_sort', ), 'filter' => array( 'handler' => 'views_handler_filter_numeric', ), ); // The Name field $data['exposed']['name'] = array( 'title' => t('Name'), 'help' => t('The record name.'), 'field' => array( 'handler' => 'views_handler_field', ), 'sort' => array( 'handler' => 'views_handler_sort', ), 'filter' => array( 'handler' => 'views_handler_filter_string', ), ); // The Deadline field $data['exposed']['deadline'] = array( 'title' => t('Deadline'), 'help' => t('The record deadline.'), 'field' => array( 'handler' => 'views_handler_field_date', ), 'sort' => array( 'handler' => 'views_handler_sort_date', ), 'filter' => array( 'handler' => 'views_handler_filter_date', ), );It seems like a lot but it’s not. For each field, we create a new array inside the exposed array (that is our new table), the key of which is being named after the table column. Then after some basic information (title and help), we tell Views which handler to use for each of these three operations: field, sort and filter. The first one is for displaying the field whereas the latter two are self explanatory.
看起来很多,但事实并非如此。 对于每个字段,我们在exposed数组(即我们的新表)内创建一个新数组,其键以表列命名。 然后,在获得一些基本信息( title和help )之后,我们告诉Views这三个操作中的每个操作使用哪个处理程序: field , sort和filter 。 第一个用于显示字段,而后两个用于说明。
But what is a handler? A handler is a Views class located in the handlers folder of the Views module that handles these operations. And here we basically need to specify which one of those classes should be used. For instance, for a regular integer field we would use the integer oriented handler for display, the regular one for sorting and again the integer one for filtering. For the deadline, we have date handlers. And if the default that Views offers is not enough (which can be the case), you can extend these classes, change some logic, and use the new custom handlers instead.
但是什么是处理程序? 处理程序是位于Views模块的handlers文件夹中的Views类,用于处理这些操作。 在这里,我们基本上需要指定应使用这些类之一。 例如,对于一个常规整数字段,我们将使用面向整数的处理程序进行显示,使用常规处理程序进行排序,然后使用整数进行过滤。 对于截止日期,我们有日期处理程序。 而且,如果Views提供的默认值还不够(可能是这种情况),则可以扩展这些类,更改某些逻辑并改用新的自定义处理程序。
Now you can save, clear the cache and refresh your View. You should be able to add fields, filters and sort them. Views, meanwhile, knows how to handle each field depending on the data type they contain.
现在,您可以保存,清除缓存并刷新视图。 您应该能够添加字段,过滤器并对它们进行排序。 同时,视图知道如何根据它们包含的数据类型来处理每个字段。
As you probably noticed, we have one more column in the table we did not yet cover: the node_id. This is an integer in the database and I suppose we can describe it as such. But it wouldn’t be very useful to create listings that show node IDs. Rather, these IDs should be used in a relationship (table join), and retrieve data from the respective nodes. To do this, we need 2 things: tell Views what other tables our table can join with and set the proper handlers for the node_id column.
您可能已经注意到,表中还有一列我们尚未介绍的列: node_id 。 这是数据库中的整数,我想我们可以这样描述它。 但是创建显示节点ID的列表并不是很有用。 而是应在关系(表联接)中使用这些ID,并从各个节点检索数据。 为此,我们需要做两件事:告诉Views我们的表可以与哪些其他表一起加入并为node_id列设置适当的处理程序。
First, let’s make sure Views knows that the exposed table can join with the node table. Inside the hook_views_date() implementation, before describing the fields, paste the following:
首先,让我们确保Views知道exposed表可以与node表联接。 在hook_views_date()实现内部,在描述字段之前,粘贴以下内容:
$data['exposed']['table']['join'] = array( 'node' => array( 'left_field' => 'nid', 'field' => 'node_id', ), );So we basically add a new index join in which the array keys beneath represent the tables it will join with. The left_field is the field on the target table (node) while the field is the one on the current (exposed) table. This can be confusing since usually the column names are the same.
因此,我们基本上添加了一个新的索引join ,其中下面的数组键表示将与之联接的表。 left_field是目标表( node )上的field而该field是当前( exposed )表上的字段。 因为通常列名是相同的,所以这可能会造成混淆。
Next, we need to define the node_id field just like we did the rest, but with one extra bit of information, the relationship (and argument as well):
接下来,我们需要像其余部分一样定义node_id字段,但要多加一点信息,即关系(以及参数):
// The Node ID field $data['exposed']['node_id'] = array( 'title' => t('Node ID'), 'help' => t('The record node ID.'), 'field' => array( 'handler' => 'views_handler_field_node', ), 'sort' => array( 'handler' => 'views_handler_sort', ), 'filter' => array( 'handler' => 'views_handler_filter_numeric', ), 'relationship' => array( 'base' => 'node', 'field' => 'node_id', 'handler' => 'views_handler_relationship', 'label' => t('Node'), ), 'argument' => array( 'handler' => 'views_handler_argument_node_nid', 'numeric' => TRUE, 'validate type' => 'nid', ), );The display handler for this field is taken from the Views module implementation on behalf of the core Node module (found in the modules/node folder). This is the handler that is also used by Views when displaying the node ID on a View based on the node table.
该字段的显示处理程序代表核心Node模块(位于modules/node文件夹中)从Views模块实现中获取。 当基于node表在View上显示节点ID时,这也是Views所使用的处理程序。
The handlers for the filter and sort are the same as before since we are dealing with a regular integer. We can filter and sort on this as well. However, we also have a relationship key there, array through which we specify the join table, field and handler. views_handler_relationship is a class that will take care of the relationship for not only displaying fields from joined tables, but also the ability to filter and sort on them.
过滤器和排序的处理程序与之前相同,因为我们正在处理常规整数。 我们也可以对此进行过滤和排序。 但是,我们那里也有一个relationship键,即数组,通过该键可以指定联接表,字段和处理程序。 views_handler_relationship是一个将处理关系的类,它不仅用于显示联接表中的字段,而且还可以对它们进行过滤和排序。
And finally, for good measure, I’ve also included the argument key through which we take care of handling arguments (contextual filters) based on the node ID. The handler used for this is again specific to the node ID, exactly as the Views module implements it. For other fields, you have a number of general argument handlers you can use as well.
最后,作为一种很好的措施,我还加入了argument键,通过该键我们可以根据节点ID处理参数(上下文过滤器)。 再次使用该处理程序是特定于节点ID的,就像Views模块实现它一样。 对于其他字段,您也可以使用许多常规参数处理程序。
So clear your cache and refresh the View. You should now be able to add a relationship based on the Node ID. Then, you will get a host of new node related fields that you can add, filter and sort on. Additionally, you can now add a contextual filter for this field and filter the View dynamically based on the ID passed in context.
因此,请清除缓存并刷新视图。 现在,您应该能够基于节点ID添加关系。 然后,您将获得大量与节点相关的新字段,可以对其进行添加,过滤和排序。 此外,您现在可以为此字段添加上下文过滤器,并根据上下文中传递的ID动态过滤视图。
As you can see, working with Views is easy both as a site builder and developer. Through a few simple steps, we managed to expose the data in our own custom table to Views. Now we can use it to display, filter, and sort our data, as well as access related Drupal entities. It’s a very pluggable system indeed, and if you are not happy with what the existing handlers can do for you, feel free to extend the ones that come close and adjust them for your data, then reference the new classes in the appropriate field definition. Good luck!
如您所见,无论是作为网站构建者还是开发者,使用Views都很容易。 通过几个简单的步骤,我们设法将自定义表中的数据公开给View。 现在,我们可以使用它来显示,过滤和排序数据,以及访问相关的Drupal实体。 确实,这是一个非常可插拔的系统,如果您对现有处理程序可以为您做的事情不满意,请随意扩展接近的处理程序并为您的数据进行调整,然后在适当的字段定义中引用新的类。 祝好运!
翻译自: https://www.sitepoint.com/exposing-tables-views-drupal-7/
drupal视图创建