 Today we are talking about views for developers, so I'm assuming that you use views and you're familiar with building views and is it quiet, I'll try and get a bit closer, is that better? So today we're talking about views for developers, I'm assuming that you are pretty familiar with views and how to use it and how to build interesting things with it. I'm also assuming that if you're not a programmer you're that way inclined and becoming a programmer. We will be talking about object-oriented programming concepts in the latter half of the presentation, so being familiar with those concepts is pretty useful, almost necessary, although there's a lot of other content in the session that is useful even if you're not familiar with that, but we'll talk a bit more about that later. With regards to questions, there's a microphone here in the middle, for the most part I would like to keep questions to the end if there's something that you think is really important or that you want to interject, that's okay, but there's a fair bit of content to get through, but I expect to have time at the end for questions. So for the most part we'll keep questions to the end, please. So there's kind of two parts to the presentation today. First we're going to look at existing features in views and in the second part we're going to look at how to extend views and add additional features to it. Now the first part I think is really quite important because views are a really powerful tool and it actually has a lot of features that people aren't aware of, I haven't discovered despite having used views for a long time. I've been using views for six years or so and I'm still finding little features here and there that I didn't know about. So site building can be really quite difficult, it's engineering really. In any medium or large website there's going to be several content types, they're probably all related to each other and vocabularies and other entity types. And there's a lot of moving parts to keep track of and to keep an eye on and to get your head around and it can get really complicated, but as software engineers we're always looking for the simplest solutions to those complex problems and someone once said and I couldn't find who this quote came from, something along the lines of, don't tell me how complicated the problem is, instead tell me just how simple your solution is. And I think that's a good guideline as software engineers to help keep problem solving and solution implementations on track and avoid things getting out of control and over bloated and over abstracted. So views are a great tool for keeping things simple because you can build an awfully wide range of quite complex views and displays with it and you can just build some fantastic things with it. I'm just going to flip through a few screenshots of some sites that have some interesting views on them very quickly. So this is the landing page of a website called Gelosophy, it's got two carousels on the home page, I think this uses the views carousel module, the views slideshow module, I forget which one. This website lists news items, the interesting thing I want to pull out here is the bit of text here displaying one to 12 of 296 stories, which is this whole page is done with views including that bit. Views is excellent at showing tabular data, like in this table, so this is part of a kind of data crunching application and the only bit of custom code here is a bit of CSS to align the numbers to the right and add some color and theme into it. This is a grid which is distinct from a views table because each data row is a table cell in contrast with the previous table, each data row is a table row. Grids are of course very popular for a lot of websites these days. The screen shots from the same website we looked at earlier but instead of showing the news articles it's showing collections of news articles. So each collection is topical and it has a number of stories in it. The interesting thing about this view is that it is sorted by the number of stories in each collection. So the first collection has the most stories in it and the last collection has the least number of stories in it. This is a user profile page, that's not me, I know, this is in development. So the URL here, you probably can't see it on there but it's user three, oops, there we go, user slash three. So this is the user profile page but the interesting thing here is that the content region doesn't have the content you would expect to find in the user page. It's been overridden with views and it shows instead blog posts by the user and a views block has been configured to render the user profile in a block in the sidebar. This is also interesting because this view on the left is still a list of things but there's only one item in this list and of course you can have zero, one or more items and views and a view that has only one item can be quite useful for a number of use cases. This page is quite a bit more complicated. This is an admin user interface to configure verifiers of areas of expertise. This organization has an internal application that tracks experts in their industry and in which particular niche areas of expertise in that industry they have expertise and the level of that expertise so we can see here in the main column we've got names and the organization, the level of expertise and their verified status whether someone has verified their expertise or not. And on the left here we can see the areas of expertise and this is actually a hierarchical vocabulary so we have regulations, policy, industry, commercial and finance, et cetera and then under each of those there's a number of sub areas of expertise. These are taxonomy terms and the implementation and there's actually three views that have gone into building this administrative interface. There's the main view in the center here, the table view. There's a header area view which has just a little bit of more context and information for the administrator that's using this interface and on the left there's an attached view which renders the taxonomy terms for the areas of expertise. Now the attached view is quite interesting because we're showing the count of the number of experts in each area of expertise. So that uses a SQL count query and it's actually the same because it's an attached view, it's the same view that renders this table here on the left but it's using an aggregation query to instead of rendering the expert to render the area of expertise with the count of the number of experts in it. So in addition to the SQL count clause and the group by part of that SQL clause there's another level of grouping going on here which I've highlighted in blue which groups each area of expertise by its parent taxonomy term. Now that grouping happens at the view's render layer, not at the SQL layer and that's what allows it to be rendered in that way. And the last part of this view is a little bit of custom code that implements jQuery accordion so that each parent area of expertise can be opened and closed and expanded and navigated because it's a fairly large vocabulary and it wouldn't fit comfortably on the page. The main view is fairly straightforward, it's a tabular view with fields but the interesting thing here is these check boxes in the right column that was implemented using views bulk operations. If you have not used or tried to use bulk operations, I highly recommend you spend an hour or two just trying it out, toying with it and playing with it. It's very, very powerful and very useful for building administrative interfaces like this. So most of the views we looked at just now had a little bit of custom code, a lot of it was just in the theme layer. But one of the advantages of Drupal is that you can get an awful long way in building out a site without custom code which is fantastic and makes site building cheap because custom code is expensive, it takes time to implement, it's usually baggy the first time you do it because you forgot about some edge case, so it needs fixing, when you upgrade the Drupal website across a major Drupal version, for example, six to seven or seven to eight, it has to be upgraded manually which takes more time. And if you want to add other features related to it, that's going to take more time again and you're probably going to start the process of debugging it and fixing it all over again. And for most organizations, the more time you spend on it, the more expensive it gets. Obviously for professional services companies, like most of the sponsors of Drupal gone, time is literally money because you charge out for each hour by the dollar. But even for organizations that have staff and work on internal projects, time is still critical because the more time spent on one project is less time spent on the next project and it gets delayed. So before you start writing custom code and that's why I wanted to spend time on this in the first section of this presentation. Before you extend Drupal of use of custom code or add things to it, it's really useful to find a way or to look for ways that you can get closer to what you need or perhaps exactly what you need using existing code, using contributed modules and existing features. And the closer you get, of course, the less custom code you need to write and the less risk and expense and time you spend on that. So essentially the more config you know in views, the less custom code you're gonna need to write in views. So let's jump into some of the more advanced config features which you may or may not be aware of in views. But just before we do that, I wanna review the anatomy of a view to make sure that we're all on the same pages to what part of the view is what and what's it called and how it relates to everything. So at the top level there's two parts to a view, the title and the display. The display obviously has everything interesting and in fact views doesn't usually render the title itself, it just hands it off to Drupal to render it as the page title if it's a page view or the block title if it's a block view, et cetera. In the display itself, there's the header area which can have zero or more area plugins in it. An area plugin is often just some custom text, it can also be another view, you can embed a view as an area plugin. Can also be a result summary and a few other things if you extend views with additional modules. At the top of the display of the view we also have exposed filters which we saw on one of the screenshots earlier which will often be a form that allows the site visitor to further filter and reduce the results in the view. Then there are views attachments. Then into the body of the view there are obviously the rows and each row might be an entity such as a node teaser or a full node or a comment or it could be one or more fields. And in the case that there's zero rows then views renders the empty area or the no results behavior area as it's called in the user interface. And the empty area can have area plugins just like the header area, for example, some custom text or another embedded view. And in the footer there is, first of all, the pager. Any views that are attached, sorry, any attachment views that are attached to the view. Then the footer area which again has area plugins just like the empty area and the header area and feed icons. Okay, so here's a feature that you've probably seen in views but I find is often under use so I wanna spend a little bit of time on this. Views three and in views two if you install and enable the semantic views module you can configure, you can customize the element that the HTML element that wraps each field. And there's actually three levels to this. You can configure the element that wraps the field itself, the value, sorry, the label for that field. And then there's another wrapper for both the label and the field itself. So in this screenshot a field, probably a node title or something like that has been configured to render as an H2 with a class of title. So it's gonna look a little bit like a teaser title. And then there's no wrapper for the field and label. The label HTML is not customized in this case probably because there is no label for it. Now if you use this feature of views a lot you'll probably find yourself configuring all of the fields to have no wrappers and then just adding a single wrapping element for the fields that you need it. But views has a little feature in the row style options which lets you do that by default for the whole view. Which quickly gets rid of all of views for both wrapping elements around fields, labels and fields and labels together. Which is essentially the same as selecting none for all three of these for all of the fields. And then you can just go and add the ones, add the markup elements that you want. So that can speed things up and make that feature more useful and quicker to configure. However, if you have multiple views that need the same configuration for that markup you're quickly gonna run into duplicate configuration across your views which makes the website more difficult to maintain. So at that point you wanna think about something outside of views to manage that. Such as view modes like teaser and teaser for nodes and the full view mode for nodes. And if you need more view modes there's a module called display suite which is essentially extends the view modes concept in Drupal and allows you to create custom view modes. So that's a powerful way of doing that. It takes more time to build out that configuration with display suite than in views. But if you need to reuse it a lot it's gonna make your site more maintainable and it might work out to be quicker anyway. Another option that I haven't tried myself yet I've only recently learned about it this week is the fences module. And fences allows you to configure that wrapping element in the field configuration via the field API configuration form. As I said I haven't used it so I can't speak about it much more than that but it's probably worth checking out. I'll definitely be checking it out next week. So another feature of views that is easily missed is the ability to concatenate fields together or to wrap some custom text around a field. So here we've got a title field and a field API field called country and they can concatenate it together and field country is wrapped in round parentheses. These tokens come from the replacement patterns which are exposed in the user interface. I don't think they're actually token module tokens I think views has its own token system that manages that but it works in the same way as far as user interface is concerned. Another fantastic feature in views is the ability to link a field to the content item. For example, you might want to link an arbitrary field to the full node page. However, views also has the ability to customize the target that a field links to in the rewrite results section again. You can put in a custom system path and you can even put in those same replacement patterns into that path. So this is useful for example, if you want a row or a field in your configuration to link to another view that takes the node ID as an argument rather than linking to the node page itself. Of course, if you configure the field to be output as a link, you're gonna want to disable this otherwise you're gonna end up with two A elements wrapping the field. Last time I tried that, views wasn't smart enough to automatically disable the other one. Yeah. So no results behavior. Obviously views has the ability to render some custom text or an area plugin in the case that there are no results. There are no rows in the whole result set for the whole view. But as well as that, views has a feature that allows you to configure what should be rendered for a field in the case that the value for that field is null or zero or missing. And yeah, so I just wanted to highlight this as it's hidden away in the field configuration settings. Summary views, you've probably come across so I won't spend much time on this, but a summary view can list the summary view is configured in the settings for a contextual filter and a summary view will render if that contextual filter is configured in this way. In the case that the argument for that contextual filter is missing and it will render a list of potential arguments that you can use with that view so that you can drill down further into the content. So you could actually build a summary view using the feature we looked at earlier where you implement another view and some custom links. And if you did it this way, you would have a lot more control over that because you would have access to other fields and relationships and configuration for that. However, summary views are a quick way to create that list that links deeper into that view and or filters, sorry, and or in the filters. So I think this feature is new in views three and isn't immediately obvious in the user interface. Obviously here we have got a couple of groups for our filters. The first group is and those filters together. The second group's or's those filters together and then the two groups are anded together. And this is highly configurable through the user interface. You can quite make quite a mess of your view and have unintended results if you're not careful. But it is a very powerful feature. And you've probably seen that before, but what very few people are aware of is that you can actually configure contextual filters in here as well. They don't appear in the interface, but because they all get rendered into the where clause of SQL, they are still kind of taken into account when a views builds the where clause. And contextual filters will always be included in the first and or group. So what that means is that, whoopsie, you're getting a preview, there we go. What that means is that contextual filters, despite not appearing in the user interface, you should assume that they're in this first group here as if they are in the user interface. So what that means is that you could actually or together your contextual filters and that would kind of override, if those contextual filters are required, then it would mean that only one of them needs to be required if you've awed the contextual filters together. Yeah. So that's not obvious from the user interface, but it is a great way to take advantage of some interesting things in views and make a big mess of it if you don't understand what's going on there as well. Result summaries. We looked at a screenshot of this at the beginning. I only just discovered this feature in views so that's why I wanted to include this. Maybe everyone else knew about it already. But it allows you to add a little bit of text along the lines of this here, displaying one to seven of seven. It's distinct from a summary view, despite having a similar name and have highlighted the difference here between a result summary and a summary view. Oh, result summaries are area plugins. You can add them to the header, footer, or even the empty area. Although it probably wouldn't make sense to add a result summary to the empty area because it would probably say something like displaying zero to zero of zero, which wouldn't be very useful. This is the configuration for the result summaries, and you can see here that you can configure the text and change that and include various different numbers in that text. So aggregate count queries. This feature is intentionally quite difficult to activate and find in views because it clutters the user interface, despite views three having an amazing interface and far better than views one or two interface. It doesn't scale to quite the level that this feature needs it to. And as well as that, it is a complex concept to get your head around. If you don't understand what's happening at the SQL level here, if you're not familiar with the SQL to read and debug that SQL while you're configuring the count query, you might not wanna try this feature because it is really complicated. But if you do understand it, it's very powerful and the way you configure it is in the advanced settings of the view, you turn use aggregation on, and that adds this aggregation settings, configuration option to all of your filters, sorts, fields, and I think relationships and contextual filters as well. In most cases, you're only gonna want to configure the aggregation settings for one or two of your sorts or filters or fields. And yeah, that's fairly straightforward. Once you get to this point, you click on aggregation settings and you can choose to run that field or filter or sort through account function as a popular one or sum or average. And there's a few other options there as well. Alternative pages. So sometimes it's useful to have a pager that groups your content by date, such as month, week, or year, or an alphabetic pager that works a bit like an address book. So you have A, B, C, D along the bottom and can find perhaps people by the first letter of their surname. In most cases, alternative pages are actually contextual filters, but the date pager is configured via the pager settings, as we see in the screenshot here. An alphabetic pager is configured by enabling the glossary mode of a contextual filter. And you can set a character limit to decide how many letters should go into that pager. You can also build alternative pages like this using views attachments. And in most cases, you'll get some more flexibility in that way, but you'll get some more flexibility in regards to the rendering of each pager item, but it might be a bit harder to get it to render like a pager. And finally, this is actually a Contrib module for views, which is very, very useful and just does one simple little thing. It exposes an area plugin that you can add to header, footer, and empty areas to add a link. Of course, you can do this with the custom text area plugin, but you have to type in the a tag and you end up assuming that the base path, you end up having to assume the base path for the website. So if you then move the website to a sub director of a domain or disable clean URLs, the link might not work anymore. And it also won't go through aliases. This module runs the link path through the L function, so it will alias any system paths and it also handles query strings and a few other little things relating to links. Okay, so that's the first section. We've looked at why you shouldn't write custom code if you can avoid it and why you should think simple solutions for your complex problems. We reviewed the anatomy of a view and we looked at several advanced configuration options and views. How to, for example, how to wrap fields with custom markup elements without having to get your hands dirty in the theme layer just through configuration. How to concatenate fields together. How to render fields as links to custom paths and the no results behavior for fields as opposed to the no results behavior for the view results set. Summary views, the configuration of that and or groups of filters and also the configuration of the and or groups with regards to contextual filters. Result summaries, for example, showing one to seven of 17 items. We also looked at how to enable aggregate count queries and views and we looked at some alternative pages and the views link area module. So that brings us to the second section, but before we dive into this, does anyone have any burning questions at this point that they don't wanna keep to the end? The question was, do you know about adding access controls to area plugins? Oh, yeah, actually I wrote a patch for that the other week. So currently views link area doesn't check that the user currently viewing the view has permission to access that system path. I thought that it did and then I configured a view with that assumption and it didn't work. Well, it did work, but it worked for anonymous users as well as administrators, which I didn't expect. So there's a patch in the issue queue for that. I don't think it's been reviewed though. So if you have a look and review it, it might get committed quicker. Yeah. Um, could you go into a little more detail regarding the count function that you mentioned? The what function? The count sort that you mentioned before. So what sort of detail? How would you configure that? Yeah, I can do that really quick, but I'll be really quick so that we can move on. Thank you. So I have a view here, which I used to make some of these screenshots and it's probably not gonna work because I haven't really thought about what I'm gonna add here, but basically you tick that. Now use aggregation is set to yes and we've got all these additional aggregation settings here. Now it's not gonna make sense for this view to aggregate it, but for example, I could set account function here or count distinct sum, average, min, max. And those will relate to the SQL functions of the same names. Okay, so let's move on to the second part, which is about writing that nasty custom code, which is gonna cost us so much time and money. Before we dive into this, there's no way I could possibly tell you everything you need to know in this session and if I did you would forget 99% of it anyway. So you need to know where to get the detailed documentation. Views three documentation is now, as of just a couple of weeks ago, available on api.drup.org, which is absolutely fantastic because you can use the search feature there and in the same way that you do with Drupal core functions. There is also topical documentation on api.drup.org, although I haven't worked out how to navigate to it yet because this is a new feature on api.drup.org. So this is a useful URL to find or to write down. And that topical documentation is actually very well presented on api.drup.org and very, very useful. It's a great way to dive into some of the concepts of views and get your head around them at a more general level. As well as that, there is the DoxyGen documentation, which has been available on logris.com for many years, but that documentation is still for views two. It hasn't been updated for views three. So I recently went and updated the DoxyGen configuration and generated views three documentation and I've put that on drupal.geek.nz slash views if you prefer that. I prefer the DoxyGen documentation sometimes for depending on what I'm looking for in the documentation. One thing I like about it is its presentation of the classes and the relationships between those classes, the class hierarchy in particular. It has this fantastic navigatable tree so you can see exactly which classes inheriting from which other class. And this is a great place to start to work out how to add a particular feature to views because most of the time you're going to need to create a class that inherits from one of these handlers or from one of these plugins. Yeah, so let's look at an example. I'm actually gonna look at the views link area module because it's a nice simple implementation which serves as a great example for how to extend views. So the first thing you need to do to tell views that your module integrates with views is implement hook views API and you tell it which version of views your module supports. In this case, everything from three dot zero, alpha one and up. And you can also tell it where in your module your views include files are. You can omit this if they're in your, if they're in the home do it, I believe. But check the documentation for more details and the other options there. Once you've got that, the next thing is to actually create that subclass. So views handler area link implemented by the views link area module extends views handler area. In views handler area, we can find out about the documentation for that in the Doxygen documentation which I have open here. Views handler area and you can see already that there is some default implementations of this in views itself. Views area view, which is the area plugin that allows you to embed a view into a views area. Text, which is just the generic custom text one. Result, which is result summaries. For example, the text displaying seven to 17, sorry, one to 10 of 17 results. And broken which handles the case where a module has been disabled and the area handler no longer is available. So views link area extends views handler area and if we wanted to get more documentation about that we can see it all here. I'm not gonna look into the methods that have been implemented here because that's kind of low level detail and it'll be vastly different for every use case. The next thing, lost my slides, here we go. The next thing you need to implement is, or the next thing you need to do is tell Drupal about your classes so it can store that information in the registry and automatically load the relevant include files when it instantiates that class. So in Drupal seven, that means putting these lines here and we can see here that views link area module has put that class in a file called views handler area link dot ink, which is consistent with the convention of Drupal of defining classes in a file of the same name and include file of the same name. View sync area module has also put its implementations of views hooks in a file called views link area dot views dot ink, which is the Drupal convention for putting implementations of another module's hooks. And it's exposed that file here as well to Drupal so it can keep track of it. In Drupal six, that's a bit different and it's a little bit more complicated, but hopefully you're not doing too much Drupal six anymore. Finally, in most cases you will need to tell views how your new class integrates with the data schema. And in the case of views link area, it doesn't actually integrate with the schema so it's kind of using a pseudo column of the views table to expose the area plugin. But most of the other classes will somehow integrate with the schema and they might, for example, if they implement a relationship, they will refer to the table that they're building that relationship from and the column. Again, the detail for that documentation you can find on api.drupal.org. Okay, so we're going good for time. The last thing I wanna do to show you is which classes that we looked at in the class hierarchy here, how these relate to features in the user interface. I think this is important because as developers we usually build our mental model of how a system like views works based on its user interface. And often the way that you work out what's missing in order, like the piece that's missing to complete your requirements or get that feature you need is through user interface, like I need to add another one of these things that does something differently. So I'm not gonna go through all of them because some of them don't appear in user interface and some of them aren't used very often but we'll go through the most important ones. Views handler field is a parent class for subclasses that expose fields. That's fairly straightforward. Views handler filter, no surprises there. Views handler argument is for contextual filters. If you use views two, views version two in the past you'll know that contextual filters used to be called arguments. Views handler relationship is a parent class to the classes which add different types of relationships which you can add through the user interface here. Views handler sort, views handler area. Now this appears in several places in user interfaces because area plugins can appear in the header area in the footer area and the no results behavior area or the empty area. Views plugin display. Now this appears a bit differently in the user interface of course and I'm just gonna jump over to the view I have here. So we can see that the existing implementations for different types of displays you can add our attachment block date browser feed, page references and if we look at documentation views plugin display, we can see that the subclasses for that pretty much map to those options. And of course as we can see here that views plugin display feed is a subclass of views plugin display page. So you don't have to inherit directly from views plugin display. If you just want to tweak something and for example the block display you can inherit from that instead and just override the bits of that you need. You don't have to copy the whole thing. Views plugin style, this adds four meter options. We'll look at this in the user interface too. So the options for four meters by default, grid, HTML list, jump menu, table, and formatted list. And in the class hierarchy we can see grids, jump menu, HTML list here it's just called list, RSS, table down here, jump menu. Default is unformatted list and we've got a few others here that have the namespace summary. These don't appear in the user interface because they relate to summary views rather than the main view formatted. Views plugin row, this is very much dependent on the formatted. Some formatters require you have the row style that they use for example a table view must have a fields formatted at the row level. But a HTML list can have fields or entities. Views plugin pager, views plugin access. Usually you only use permissions for this but you could actually extend this with a custom system that works out permissions in some other arbitrary way. Views plugin cache, again you can implement your own caching layer for views there. So outside of the main user interface, looking at the interface for contextual filters, we come across a couple more. Views plugin argument default. So this takes effect when a contextual filter is configured to find the value of its argument from somewhere other than the URL because the URL has not been explicitly passed. And again let's just jump back to documentation. We can see how that maps to the options in the user interface. Current user, fixed node, PHP, raw, et cetera. And they map fairly straightforward to these here. And another one for contextual filters is views plugin argument validate. And again in the doxigen documentation, we can see that these subclasses, user, taxonomy term, PHP, numeric node, map pretty much directly to the options here, node, fixed, PHP, taxonomy term, user. Okay, so that brings us to the end of the second section. We've looked at where you can find documentation to get implementation detail for developers about the functions and methods of views on api.truple.org and truple.geek.nz slash views for the doxigen documentation. We've looked at the classes and subclasses and the hierarchy of those and how to navigate that and doxigen. And we looked at how you can extend views to add another one of these subclasses with your own particular feature set. And that there are four steps to that. You've got to implement hook views API. You do that once in your whole module of course, not for each class that you've created a subclass for. Then you create the subclass of the appropriate views class that adds the type of feature you need. You have to expose that class in your modules info file. And finally, you also need to expose that class to views using hook views data so that views knows how that relates to the schema and the other entities and the data model that your website uses. And finally, we looked at how the classes map to various configuration features in the user interface. So that brings us to the end of the content. We've got a fair bit of time for questions still, which is great. I hope you've learned something and that you can go build awesome things with views now. Just before we get into questions, please, please, please take the time to take the survey on the Drupalcon Denver website. I really appreciate feedback. It helps me learn what information is useful and not useful and how I can better present that information so I can do it better next time. And as well as that, it helps the Drupalcon organizers put together better programs and schedules for future Drupalcons. You can do that by going to the website, to the program, finding the session and filling out the information there. And you should do that for all the sessions if you can. It would be fantastic. Yes, please. Hi, Bevan. Could you help me out with a recipe? How would I create a view that would display the output of a web service, like a third-party web service? You would need to build an alternative backend for views, which is something that I would have loved to have demoed in this session, but it would take quite a bit of time to do that. The class that you want to extend in order to create an alternative backend is, I think, views plugin query, yeah. So this, by default, in views is SQL. It's a SQL database. But you can expose a REST API, a file system if you wanted, or any other type of data store to views and list all sorts of different things. Now, if it's a common API that you're integrating with, like Flickr, chances are that someone's done it already. So you should look for an appropriate module that you can use and perhaps complete if it's not done. But you wouldn't go the entity route? If you want to duplicate all that data in Drupal, you could, but I would probably be inclined to do that at a cache layer rather than an entity there because all you're doing is caching a data that's primarily stored somewhere else. In your hook views API implementation, you had a very specific... Sorry, it's very quiet. Can you get close to the mic? Yes. In your hook views API implementation, you had a very specific view number, three dash alpha of one. What happens if views gets updated and your custom module is implementing like a beta version of views or something? That's a great question. I don't know the answer. I would look at the documentation for hook views API. In this case, Larry Garfields implemented this module and I suspect at the time he implemented it, views didn't have a stable release yet, which is why he went with three dot zero dash alpha one. I expect the way it works is probably something like it will work with all API versions that are in the three series, but it won't work with the API two series or four series. And of course the four series doesn't exist yet. Could you elaborate slightly on the difference between a handler and a plugin and when you would use one versus the other? That's an excellent question as well and I used to know exactly the answer for that. I'll have to have a quick look to remind myself. So I think basically the difference is that views, every view has to have exactly one of each plugin, but on the other hand it can have zero or more of each of the handlers. So it's, as far as you're concerned when it comes to extending views, it doesn't really matter. You just got to get the right one, like views has already decided for you which ones are handlers and plugins. And it's, I imagine there's something going on further up in this class hierarchy that's relevant for views to distinguish between them. Would it be fair to say that a handler is for getting data and a plugin is for displaying it or that'd be inaccurate? Handlers for getting data, plugins for displaying it. Yeah, that looks around about right for the most part, yeah. Hi, there are many differences between a triple six view and triple seven views. We have a bunch of triple six views. Is there any good way to migrate to triple seven views? That's a very interesting question. On triple six, are you using views two or views three? Six, view two. Okay, so one probably you're gonna have is, as well as migrating the data across and the fact that the data model has changed is that on triple seven, there is only views three, not views two. I'd probably suggest, well, that's a tricky one. It's probably gonna take a lot of time to work it out and you're probably gonna have to rebuild most of your views anyway because the data model has changed. So it might be easier in many cases to throw out the views two, sorry, the views two view that was configured and just rebuild it and views three and triple seven once you've got the data migrated. Thank you, no problem. So I have two, what I hope are really quick questions. One is, I had a recent use case where I was using and abusing rewrites as I often do, but I have certain rewrites like in a views results area you wanna be able to say X number of views within and then include maybe one of the contextual filters like a zip code or something like that for a location search. And those aren't exposed in the views token system so I basically had to hook in using one of the pre-render hooks to look at the views object and pull out the argument from that. Is that the most elegant way to do it or is there a better way to expose those? So I just wanna check I understood what the problem you had was. You wanted to include data from the argument for a contextual filter in the field. Yeah, to use that as a token basically like another field. So views isn't very good at that because the field is a separate entity the contextual filter, the contextual filter applies to all of the rows, not just one particular row. So that value is gonna be the same for all of your fields. So I suspect if you tried to step back and look at things from a bigger picture in a different angle, you might find a better way to do that. I have come across a similar problem before where I had a view that was a list of length one and I wanted to include information about the contextual filter in that and actually it was one of the ones in the screenshots. I'll pull it up real quick. This one here, so this views header area does exactly that and it's another view which inherits the contextual argument but it's listing taxonomy terms instead of nodes. So I haven't got it at the field level but I am able to provide a lot of information about the argument that was passed into this contextual filter on this display but it's a separate view that's embedded via the views header area. Well that wasn't very quick but I don't know if you can riff at some point on performance tweaking because views can be awesome but very slow. Yeah, wasn't really time to get to that in this session but basically configure your cases carefully and do as much case as you can on the front end using Varnish or whatever and if that's not enough you need to look at how you can cache the data queries themselves and again you can extend views with it by implementing your own cache layer if you like and that will give you a lot more control over that in options. What's your thoughts on views PHP being used apart from it being a security vulnerability? What are my thoughts on views? Views PHP modules so you can use PHP and directly interviews UI. All right. So you can only do that in Drupal 7 if you're logged in as root user even if you have an administrator role you can't do that, you have to log in as user ID one which I think solves a lot of the potential security issues because otherwise it could be easy to configure a kind of lower level site builder to have PHP access when they configure their view. In terms of whether you should do it or not that's tricky and general knows the correct answer you should look at how to do it by extending a class instead but sometimes it's really simple and quick and convenient and if you're building out the prototype or a very early phase of the website I've done it before. Cheers. I have a view that it uses a contextual filter to list taxonomy terms and then it has another contextual filter as an attachment view in glossary mode to list the first letter of surnames. The problem is my users can only select either taxonomy term to filter by or the last last name filter by how would I allow them to do both? So you have two contextual filters and you want a summary view for each? Yes. And you want both summary views to appear at once? Yes. Yeah, I don't think views does that. You could probably do it if you added them as attachment views. I've never tried that though. Yeah, one is an attachment view. Would I have to make the other one attachment view and then could I use that and or group? Yeah, we're getting too deep. Too deep. And for a conversation like this if you like we could have a look after. All right, yeah. Thank you. Good morning. My question is about configuring a search term or a search filter and let's just assume I have a title field that I'm wanting to search by or filter by in a description filter. When I display those filters to the user I'm interested in having one search box instead of two search boxes. Is there a way in views to aggregate that search box where it all just searches both of those terms? So you want one search box as an exposed filter that searches across two fields? Yes. Does it matter if it searches the whole node or the whole entity? It does not matter. Okay, so there is a exposed filter for that that works at least for nodes and I think for users and comments. And I'm probably not gonna be able to find it on the fly. Oh, I've got search module disabled so it's not gonna be here. But I'm pretty sure that if you enable the core search module you can add something like, oh full text, yeah. I think it's called the full text filter and you can configure it to be exposed and it will work kind of like a search box but only on the nodes that come through the result set for that view. Great, thank you. As well as that, there is a search API which is another big can of worms I don't wanna start talking about but is very powerful for that sort of thing and gives you a whole lot more options as well in terms of searching and exposed filters. Thank you. Yeah, I have a quick question about performance I guess. On some of my sites I have definitely, in the contextual filters, a bunch of PHP that kind of decides what to do. So can you get a bit closer to the mic? What's it? Sorry, yeah, sorry. On some of my sites I have a lot of contextual filters which have a lot of PHP that provides a default argument kind of in that little block there. Is it something that we should be writing my own contextual filter class for or something for better performance? Yes. Okay. Or would caching fix some of that too? For performance I don't know if it matters but in terms of site maintainability. For example, what happens if you disable a module or rename a function that that PHP snippet depends on? Your site's gonna die. If you put that in a class you're gonna discover that more easily and be able to handle that more efficiently with your version control system. If I have a content type which stores the XML and if I want to expose the XML tags as it feels to view on the fly, is it possible? Can you repeat that? Like I have a content type which stores the XML data and there are different tags in that XML. I want to expose those tags as the fills to the views so that views can display certain tags. Sorry. Yeah, I think that's a bit complicated answer here. Perhaps you can ask me afterwards and I'll point you in the wrong direction. Hi, I was wondering can views read data from minus QL that's not exposed to Drupal? Yeah, and that's exactly what hook views data is for. I'm gonna use api.drupal.org. You need to be very familiar with the schema that you, with the data that you wanna add in the schema for that data and you need to understand how hook views data works. Well, the documentation for it's great so read that and learn it. But that's the way to go about doing that. Thank you. If you do do that, and assuming it is data that is in an existing contrib or core table, please do it as a patch and contribute it on drupal.org rather than just in your custom module. That way someone else can reuse that feature. We'll do two more. Okay, I have a view that has an exposed filter that's based on a tagging taxonomy. And what I would really like it to do rather than require them to enter something and the drop down happens and if they don't enter the right exact tag, they don't get anything back. What am I missing on that? I would need to have a closer look. Chase me after and we can have a look if you like. Okay. Yeah, the attachment display you have with the taxonomy is that you're accordion. Sorry, can you hear me okay? Yep. The attachment display you have with the accordion right here. Is that just a summary or is that a count query attachment display? Just kind of curious how deep that nesting goes and how you sorted it. Oh, so this hierarchy only had two levels. I forgot to mention that. So it's just grouped by the parent and that's it. Yeah, gotcha. If the hierarchy had more than two levels, then this would have been a lot more complicated to build, implement and use. But the way that it works is as far as the rendering goes of that hierarchy is it's using the group buy option and I think the row style settings or something like that. I don't have access to that view here to show you the configuration of that exact view but I think it's using this grouping feature. And so that's not a sequel group buy cause. That's just, that happens in the rendering layer of views. Right, it's just happening, I think. Do you know anything that can... Oh, and the way I, so in the view that displays that, I configured a relationship for the parent term for each of the terms and I also added a filter where parent term is not null. So the view was only listing child terms but it had the parent term as a field. Or as a related entity. And then I added the parent terms name as a field but excluded it from the display. So it was still available at the rendering layer but it wasn't being rendered with each row. And then finally here I select the parent title as the group buy field. And so, and then views uses that to group each row by that field. Awesome, thanks. Do you, one quick question, final question. Do you have any recommendations on how to actually get that tree to render? Right, so it could be infinitely deep or? Exactly what I just said, it'll render it in a, well in a semantic tree at least. Yeah, so I... But then to make it look like a tree you can do that with CSS. Maybe I misunderstood the question. Yeah, kind of, I'll catch you later. Okay, thanks. Thank you very much. Just let me put this, there we go. Sorry? Right, it's a good way to expose what's going on. It's a great home day.