I have couple hundreds of articles on a website. I use a view to show excerpts and links to them on one page and I also have a pager that show 10 articles at the time. I need to add a dropdown with years [...,2008,2009...,2013]. If you select a year in the dropdown, then view should only display articles that were posted in that year. Years in the dropdown should be updated automatically if a new article added in 2013 for example, and thus the first year is the year of the first publication.
Please suggest possible solutions.
I think, you need to set exposed filter to the view list. The configuration should be something like--
Filter criteria: Date (node);
Form element: Select;
Filter granularity: Year;
Date Fields: Post Date; Expose;
Filter type to expose: Single;
Operator: equal to;
Inform me if it works..
Here is a way to do it if you want to use Drupal's built in "Authored on" field for a node. You'll need to create a custom module. This was created in Drupal 7 / Views 3. My module files are in /sites/all/modules/custom/ViewsYearFilter/.
ViewsYearFilter.info
name = Views Year Filter
description = Allow a view to filter by post year.
package = tools
core = 7.x
files[] = ViewsYearFilter.inc
files[] = ViewsYearFilter.views.inc
ViewsYearFilter.module
<?php
/**
* Implements of hook_views_api().
*/
function ViewsYearFilter_views_api() {
return array('api' => 3);
}
ViewsYearFilter.views.inc
<?php
/**
* Implements of hook_views_data().
*/
function ViewsYearFilter_views_data() {
return array(
'node' => array(
'published_year' => array(
'group' => t('Content'),
'title' => t('Year'),
'help' => t('Filter by years.'),
'filter' => array('handler' => 'ViewsYearFilter'),
)
)
);
}
ViewsYearFilter.inc
<?php
/* Allows filtering of posts by year in a Drupal View. */
class ViewsYearFilter extends views_handler_filter_in_operator {
/**
* Override parent get_value_options() function. This function returns an array of all valid years from our post type.
* @return
* Return the stored values in $this->value_options if someone expects it.
*/
function get_value_options() {
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->propertyCondition('type', 'blog_post') //post type
->propertyCondition('status', '1'); //is published
$results = $query->execute();
$object_node_ids = array_keys($results['node']);
$objects = node_load_multiple($object_node_ids);
foreach ($objects as $blog_post) {
$values[date('Y', $blog_post->created)] = date('Y', $blog_post->created);
}
$this->value_options = $values;
return $values; //array of year values
}
function query() {
$this->ensure_my_table(); //not sure why/if this is necessary
$startDate = mktime(0, 0, 0, 1, 1, intval($this->value[0]));
$endDate = mktime(0, 0, 0, 1, 1, intval($this->value[0] + 1));
$this->query->add_where_expression($this->options['group'], "node.created >= " . $startDate . " AND node.created <= " . $endDate); //filtering query
}
}
Then, in your view config page you can create a new exposed filter:
Sorry, but I can't actually post this image as I don't have enough reputation. There will be a new exposed filter named "Content: Year" you can add to your view after creating and activating your new module.
PS: I based my code off of Shevchuk's answer on this question.