In this example you will create a context-sensitive block that shows the titles of recent blog entries by an author when viewing one of their posts. This will demonstrate using Views arguments to dynamically filter a view's contents at display time.

Before working through this example, enable the Blog module and populate some entries from a few different users.

Creating the View

The first step is creating a view for our recent blog entries block. Because the block will show the titles of blog entries, this view is considered a "Node" type. Go to add new view, enter the following properties, and click Next:

View name
View description
List of recent blog entries for a given author.
View tag
View type

Generating a list of blog entries

It will be much easier to see the view progress if we can see it doing something. In this section, we will create a basic view displaying blog entry titles.

  1. In the third column, locate the Fields area. Generally speaking, fields are the pieces of information that you want to display in the view (in this case, node title). Click the + icon to add a field.
  2. Scroll down to Defaults: Add fields, below the settings table. A large selection of fields will be available.
  3. In the Groups drop-down menu, select Node. This will limit the list to only the default fields exposed by Node module.
  4. Scroll down the list, select the Node: Title field, and click Add.
  5. You will now be presented with settings for the Node: Title field. Delete the label from the Label field, so that each individual node title is not prefixed with the word "Title." Additionally, check the Link this field to its node box so that visitors who see an interesting title can click directly on it to read the blog entry to which it belongs.
  6. When finished, click Update. If you scroll down to the Live Preview section, you should now see a list of several node titles; however both blog entries and other node types will be in the list. Let's fix that.
  7. In the fourth column, locate the Filters area. Filters limit the results displayed in the view, and we can use this to our advantage here by showing node titles only from blog entries and not every type of node. Click the + icon to add a filter.
  8. As before, scroll down to the Defaults: Add filters section, select Node from the Groups select box to limit the list of options to only those exposed by Node module.
  9. Scroll down and select the Node: Type field and click Add. In the settings page that appears, leave Operator as Is one of and select Blog entry under Node type. Click Update when finished.
  10. Now, by scrolling down to Live preview, you'll see that the list only shows blog entries.

Adding context with arguments

While filters are very useful for limiting the results of a view when the condition is always consistent (for example, a view of blog entry nodes should always be filtered by the blog entry type), something filters can't do is smart decision-making based on the page context. In our case, we want the view to display a different list of blog entries when looking at a post by user 'admin' than we do when looking at a post by user 'member', and filters won't be able to help.

Luckily, there's another way to filter a view's content: arguments. Through arguments, Views are able to obtain additional context (typically via dynamic URLs with IDs in them) and can take this context into consideration when displaying the view.

Let's walk through adding and configuring an argument to our view so that we can change its contents based on post author.

  1. In the third column, locate the Arguments area. Click the + icon to add an argument.
  2. Because we are basing the view around content authors, this time under Groups select User. Check User: Uid and click Add.
  3. The Defaults: Configure Argument User: Uid settings page has a lot going on, but only a few things that need our attention.
  4. The Title field here, unlike the Title field under Basic Settings, can be based upon the context that the view is being displayed in. Change the title to 'Recent entries by %1.' %1 will later be expanded to the user's name (based on the User: Uid argument) when the view is displayed.
  5. Under Action to take if argument is not present, there are a variety of options, ranging from displaying a 404 or a 403 page to simply displaying all values in the view. In our case, if an argument isn't specified (which it won't be, since this view will be displayed in a sidebar block, not as a page with its own URL), we want to give it a default one to act on. Select Provide default argument.
  6. Assuming JavaScript is enabled in your browser, you should now get another selection for Default argument type. Select User ID from URL, which will then provide a new option, Also look for a node and use the node author. Select it. This will cause Views to first see if it can figure out a user ID from the current URL (for example, user/1). If it can't, it will instead check to see if the current page is a node page (such as node/42) and, if so, take the user ID from the node's author field instead.
  7. Validator options provide a useful way to control what kind of arguments your view will accept. Select User as the Validator. By default, changing this setting will check the incoming argument and ensure it's a valid user ID; if not, the view will be hidden from the page.
  8. Once you have changed the argument's title, default argument, and validator options, click Update to save your changes.
  9. You'll notice that now the Live preview no longer shows anything. Did we just break the view? Fortunately, no. It's merely abiding by our wishes to hide itself if there is no valid user ID given to it. Try entering a '1' in the Arguments box and clicking Preview. You should now see a list of only user 1's blog entries.

Creating the block

So the live preview is now showing basically what we want. There's just one problem: we have no way to stick what we've done so far into a sidebar block! Let's fix that by adding a new Display.

  1. In the first column, under Defaults, there is a select box containing entries such as Page, Feed, and, yes, Block! Select Block and click Add display.
  2. There's not much else to do here as far as Views is concerned. Under Block settings, click the None link next to Admin and fill in a description for the block in the administrative interface, such as: 'Recent blog entries by author.' and click Update.
  3. Save your work by clicking the Save button at the bottom of the Views interface. You should receive a message that the view has been saved.
  4. Next, navigate to the blocks interface and drag the 'Recent blog entries by author' block to the right sidebar region (or similar) and click Save blocks.
  5. You'll notice this appeared to do nothing. No block shows in the sidebar. But remember, we are looking at an adminitrative page; we are not looking at a page that would provide a user ID context. Navigate to the main blog listing and click on an entry there. You should now see a sidebar block, titled something like "Recent entries by admin," with a list of blog entries beneath it.

Finishing touches

There are still a few remaining things to do before our view is complete. For example, we said that the block was to show recent blog entries, but instead it's showing them in the order they were entered, with oldest on top. Additionally, even unpublished entries are showing in the list currently.

  1. Return to the recent_blog_entries view edit page.
  2. Add an additional filter by clicking the + icon in the Filters section in the fourth column.
  3. Change Groups to Node and select Node: Published. Click Add.
  4. Under the Published selection, choose Yes and click Update.
  5. To handle sorting, locate the Sort criteria area, just above filters, and click the + icon there.
  6. Under Groups, again select Node. From the list of options, check Node: Post date and click Add.
  7. In the settings page, change Sort order to Descending. This will place the newer posts on top of the older ones. Click Update when finished.
  8. Finally, Save the view for your new settings to take effect.