danielebarchiesi@0: construct() danielebarchiesi@0: * - Create the initial handler; at this time it is not yet attached to a danielebarchiesi@0: * view. It is here that you can set basic defaults if needed, but there danielebarchiesi@0: * will be no knowledge of the environment yet. danielebarchiesi@0: * - handler->set_definition() danielebarchiesi@0: * - Set the data from hook_views_data() relevant to the handler. danielebarchiesi@0: * - handler->init() danielebarchiesi@0: * - Attach the handler to a view, and usually provides the options from the danielebarchiesi@0: * display. danielebarchiesi@0: * - handler->pre_query() danielebarchiesi@0: * - Run prior to the query() stage to do early processing. danielebarchiesi@0: * - handler->query() danielebarchiesi@0: * - Do the bulk of the work this handler needs to do to add itself to the danielebarchiesi@0: * query. danielebarchiesi@0: * danielebarchiesi@0: * Fields, being the only handlers concerned with output, also have an extended danielebarchiesi@0: * piece of the flow: danielebarchiesi@0: * danielebarchiesi@0: * - handler->pre_render(&$values) danielebarchiesi@0: * - Called prior to the actual rendering, this allows handlers to query for danielebarchiesi@0: * extra data; the entire resultset is available here, and this is where danielebarchiesi@0: * items that have "multiple values" per record can do their extra query for danielebarchiesi@0: * all of the records available. There are several examples of this at work danielebarchiesi@0: * in the code, see for example views_handler_field_user_roles. danielebarchiesi@0: * - handler->render() danielebarchiesi@0: * - This does the actual work of rendering the field. danielebarchiesi@0: * danielebarchiesi@0: * Most handlers are just extensions of existing classes with a few tweaks that danielebarchiesi@0: * are specific to the field in question. For example, danielebarchiesi@0: * views_handler_filter_in_operator provides a simple mechanism to set a danielebarchiesi@0: * multiple-value list for setting filter values. Below, danielebarchiesi@0: * views_handler_filter_node_type overrides the list options, but inherits danielebarchiesi@0: * everything else. danielebarchiesi@0: * danielebarchiesi@0: * @code danielebarchiesi@0: * class views_handler_filter_node_type extends views_handler_filter_in_operator { danielebarchiesi@0: * function get_value_options() { danielebarchiesi@0: * if (!isset($this->value_options)) { danielebarchiesi@0: * $this->value_title = t('Node type'); danielebarchiesi@0: * $types = node_get_types(); danielebarchiesi@0: * foreach ($types as $type => $info) { danielebarchiesi@0: * $options[$type] = $info->name; danielebarchiesi@0: * } danielebarchiesi@0: * $this->value_options = $options; danielebarchiesi@0: * } danielebarchiesi@0: * } danielebarchiesi@0: * } danielebarchiesi@0: * @endcode danielebarchiesi@0: * danielebarchiesi@0: * Handlers are stored in their own files and loaded on demand. Like all other danielebarchiesi@0: * module files, they must first be registered through the module's info file. danielebarchiesi@0: * For example: danielebarchiesi@0: * danielebarchiesi@0: * @code danielebarchiesi@0: * name = Example module danielebarchiesi@0: * description = "Gives an example of a module." danielebarchiesi@0: * core = 7.x danielebarchiesi@0: * files[] = example.module danielebarchiesi@0: * files[] = example.install danielebarchiesi@0: * danielebarchiesi@0: * ; Views handlers danielebarchiesi@0: * files[] = includes/views/handlers/example_handler_argument_string.inc danielebarchiesi@0: * @endcode danielebarchiesi@0: * danielebarchiesi@0: * The best place to learn more about handlers and how they work is to explore danielebarchiesi@0: * @link views_handlers Views' handlers @endlink and use existing handlers as a danielebarchiesi@0: * guide and a model. Understanding how views_handler and its child classes work danielebarchiesi@0: * is handy but you can do a lot just following these models. You can also danielebarchiesi@0: * explore the views module directory, particularly node.views.inc. danielebarchiesi@0: * danielebarchiesi@0: * Please note that while all handler names in views are prefixed with views_, danielebarchiesi@0: * you should use your own module's name to prefix your handler names in order danielebarchiesi@0: * to ensure namespace safety. Note that the basic pattern for handler naming danielebarchiesi@0: * goes like this: danielebarchiesi@0: * danielebarchiesi@0: * [module]_handler_[type]_[tablename]_[fieldname]. danielebarchiesi@0: * danielebarchiesi@0: * Sometimes table and fieldname are not appropriate, but something that danielebarchiesi@0: * resembles what the table/field would be can be used. danielebarchiesi@0: * danielebarchiesi@0: * See also: danielebarchiesi@0: * - @link views_field_handlers Views field handlers @endlink danielebarchiesi@0: * - @link views_sort_handlers Views sort handlers @endlink danielebarchiesi@0: * - @link views_filter_handlers Views filter handlers @endlink danielebarchiesi@0: * - @link views_argument_handlers Views argument handlers @endlink danielebarchiesi@0: * - @link views_relationship_handlers Views relationship handlers @endlink danielebarchiesi@0: * - @link views_area_handlers Views area handlers @endlink danielebarchiesi@0: * @} danielebarchiesi@0: */ danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * @defgroup views_plugins About Views plugins danielebarchiesi@0: * danielebarchiesi@0: * In Views, a plugin is a bit like a handler, but plugins are not directly danielebarchiesi@0: * responsible for building the query. Instead, they are objects that are used danielebarchiesi@0: * to display the view or make other modifications. danielebarchiesi@0: * danielebarchiesi@0: * There are 10 types of plugins in Views: danielebarchiesi@0: * - Display: Display plugins are responsible for controlling *where* a view danielebarchiesi@0: * lives; that is, how they are being exposed to other parts of Drupal. Page danielebarchiesi@0: * and block are the most common displays, as well as the ubiquitous 'master' danielebarchiesi@0: * (or 'default') display. danielebarchiesi@0: * - Style: Style plugins control how a view is displayed. For the most part danielebarchiesi@0: * they are object wrappers around theme templates. Styles could for example danielebarchiesi@0: * be HTML lists or tables. danielebarchiesi@0: * - Row style: Row styles handle each individual record from the main view danielebarchiesi@0: * table. The two included by default render the entire entity (nodes only), danielebarchiesi@0: * or selected fields. danielebarchiesi@0: * - Argument default: Argument default plugins allow pluggable ways of danielebarchiesi@0: * providing default values for contextual filters (previously 'arguments'). danielebarchiesi@0: * This is useful for blocks and other display types lacking a natural danielebarchiesi@0: * argument input. Examples are plugins to extract node and user IDs from the danielebarchiesi@0: * URL. danielebarchiesi@0: * - Argument validator: Validator plugins can ensure arguments are valid, and danielebarchiesi@0: * even do transformations on the arguments. They can also provide replacement danielebarchiesi@0: * patterns for the view title. For example, the 'content' validator danielebarchiesi@0: * verifies verifies that the argument value corresponds to a node, loads danielebarchiesi@0: * that node and provides the node title as a replacement pattern. danielebarchiesi@0: * - Access: Access plugins are responsible for controlling access to the view. danielebarchiesi@0: * Views includes plugins for checking user roles and individual permissions. danielebarchiesi@0: * - Query: Query plugins generate and execute a query, so they can be seen as danielebarchiesi@0: * a data backend. The default implementation is using SQL. There are danielebarchiesi@0: * contributed modules reading data from other sources, see for example the danielebarchiesi@0: * Views XML Backend module. danielebarchiesi@0: * - Cache: Cache plugins control the storage and loading of caches. Currently danielebarchiesi@0: * they can do both result and render caching, but maybe one day cache the danielebarchiesi@0: * generated query. danielebarchiesi@0: * - Pager plugins: Pager plugins take care of everything regarding pagers. danielebarchiesi@0: * From getting and setting the total amount of items to render the pager and danielebarchiesi@0: * setting the global pager arrays. danielebarchiesi@0: * - Exposed form plugins: Exposed form plugins are responsible for building, danielebarchiesi@0: * rendering and controlling exposed forms. They can expose new parts of the danielebarchiesi@0: * view to the user and more. danielebarchiesi@0: * - Localization plugins: Localization plugins take care how the view options danielebarchiesi@0: * are translated. There are example implementations for t(), 'no danielebarchiesi@0: * translation' and i18n. danielebarchiesi@0: * - Display extenders: Display extender plugins allow scaling of views options danielebarchiesi@0: * horizontally. This means that you can add options and do stuff on all danielebarchiesi@0: * views displays. One theoretical example is metatags for views. danielebarchiesi@0: * danielebarchiesi@0: * Plugins are registered by implementing hook_views_plugins() in your danielebarchiesi@0: * modulename.views.inc file and returning an array of data. danielebarchiesi@0: * For examples please look at views_views_plugins() in danielebarchiesi@0: * views/includes/plugins.inc as it has examples for all of them. danielebarchiesi@0: * danielebarchiesi@0: * Similar to handlers, make sure that you add your plugin files to the danielebarchiesi@0: * module.info file. danielebarchiesi@0: * danielebarchiesi@0: * The array defining plugins will look something like this: danielebarchiesi@0: * @code danielebarchiesi@0: * return array( danielebarchiesi@0: * 'display' => array( danielebarchiesi@0: * // ... list of display plugins, danielebarchiesi@0: * ), danielebarchiesi@0: * 'style' => array( danielebarchiesi@0: * // ... list of style plugins, danielebarchiesi@0: * ), danielebarchiesi@0: * 'row' => array( danielebarchiesi@0: * // ... list of row style plugins, danielebarchiesi@0: * ), danielebarchiesi@0: * 'argument default' => array( danielebarchiesi@0: * // ... list of argument default plugins, danielebarchiesi@0: * ), danielebarchiesi@0: * 'argument validator' => array( danielebarchiesi@0: * // ... list of argument validator plugins, danielebarchiesi@0: * ), danielebarchiesi@0: * 'access' => array( danielebarchiesi@0: * // ... list of access plugins, danielebarchiesi@0: * ), danielebarchiesi@0: * 'query' => array( danielebarchiesi@0: * // ... list of query plugins, danielebarchiesi@0: * ),, danielebarchiesi@0: * 'cache' => array( danielebarchiesi@0: * // ... list of cache plugins, danielebarchiesi@0: * ),, danielebarchiesi@0: * 'pager' => array( danielebarchiesi@0: * // ... list of pager plugins, danielebarchiesi@0: * ),, danielebarchiesi@0: * 'exposed_form' => array( danielebarchiesi@0: * // ... list of exposed_form plugins, danielebarchiesi@0: * ),, danielebarchiesi@0: * 'localization' => array( danielebarchiesi@0: * // ... list of localization plugins, danielebarchiesi@0: * ), danielebarchiesi@0: * 'display_extender' => array( danielebarchiesi@0: * // ... list of display extender plugins, danielebarchiesi@0: * ), danielebarchiesi@0: * ); danielebarchiesi@0: * @endcode danielebarchiesi@0: * danielebarchiesi@0: * Each plugin will be registered with an identifier for the plugin, plus a danielebarchiesi@0: * fairly lengthy list of items that can define how and where the plugin is danielebarchiesi@0: * used. Here is an example of a row style plugin from Views core: danielebarchiesi@0: * @code danielebarchiesi@0: * 'node' => array( danielebarchiesi@0: * 'title' => t('Node'), danielebarchiesi@0: * 'help' => t('Display the node with standard node view.'), danielebarchiesi@0: * 'handler' => 'views_plugin_row_node_view', danielebarchiesi@0: * 'path' => drupal_get_path('module', 'views') . '/modules/node', // not necessary for most modules danielebarchiesi@0: * 'theme' => 'views_view_row_node', danielebarchiesi@0: * 'base' => array('node'), // only works with 'node' as base. danielebarchiesi@0: * 'uses options' => TRUE, danielebarchiesi@0: * 'type' => 'normal', danielebarchiesi@0: * ), danielebarchiesi@0: * @endcode danielebarchiesi@0: * danielebarchiesi@0: * Of particular interest is the *path* directive, which works a little danielebarchiesi@0: * differently from handler registration; each plugin must define its own path, danielebarchiesi@0: * rather than relying on a global info for the paths. For example: danielebarchiesi@0: * @code danielebarchiesi@0: * 'feed' => array( danielebarchiesi@0: * 'title' => t('Feed'), danielebarchiesi@0: * 'help' => t('Display the view as a feed, such as an RSS feed.'), danielebarchiesi@0: * 'handler' => 'views_plugin_display_feed', danielebarchiesi@0: * 'uses hook menu' => TRUE, danielebarchiesi@0: * 'use ajax' => FALSE, danielebarchiesi@0: * 'use pager' => FALSE, danielebarchiesi@0: * 'accept attachments' => FALSE, danielebarchiesi@0: * 'admin' => t('Feed'), danielebarchiesi@0: * 'help topic' => 'display-feed', danielebarchiesi@0: * ), danielebarchiesi@0: * @endcode danielebarchiesi@0: * danielebarchiesi@0: * Please be sure to prefix your plugin identifiers with your module name to danielebarchiesi@0: * ensure namespace safety; after all, two different modules could try to danielebarchiesi@0: * implement the 'grid2' plugin, and that would cause one plugin to completely danielebarchiesi@0: * fail. danielebarchiesi@0: * danielebarchiesi@0: * @todo Finish this document. danielebarchiesi@0: * danielebarchiesi@0: * See also: danielebarchiesi@0: * - @link views_display_plugins Views display plugins @endlink danielebarchiesi@0: * - @link views_style_plugins Views style plugins @endlink danielebarchiesi@0: * - @link views_row_plugins Views row plugins @endlink danielebarchiesi@0: */ danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * @defgroup views_hooks Views hooks danielebarchiesi@0: * @{ danielebarchiesi@0: * Hooks that can be implemented by other modules in order to implement the danielebarchiesi@0: * Views API. danielebarchiesi@0: */ danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Describes data tables (or the equivalent) to Views. danielebarchiesi@0: * danielebarchiesi@0: * This hook should be placed in MODULENAME.views.inc and it will be danielebarchiesi@0: * auto-loaded. MODULENAME.views.inc must be in the directory specified by the danielebarchiesi@0: * 'path' key returned by MODULENAME_views_api(), or the same directory as the danielebarchiesi@0: * .module file, if 'path' is unspecified. danielebarchiesi@0: * danielebarchiesi@0: * @return danielebarchiesi@0: * An associative array describing the data structure. Primary key is the danielebarchiesi@0: * name used internally by Views for the table(s) – usually the actual table danielebarchiesi@0: * name. The values for the key entries are described in detail below. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_data() { danielebarchiesi@0: // This example describes how to write hook_views_data() for the following danielebarchiesi@0: // table: danielebarchiesi@0: // danielebarchiesi@0: // CREATE TABLE example_table ( danielebarchiesi@0: // nid INT(11) NOT NULL COMMENT 'Primary key; refers to {node}.nid.', danielebarchiesi@0: // plain_text_field VARCHAR(32) COMMENT 'Just a plain text field.', danielebarchiesi@0: // numeric_field INT(11) COMMENT 'Just a numeric field.', danielebarchiesi@0: // boolean_field INT(1) COMMENT 'Just an on/off field.', danielebarchiesi@0: // timestamp_field INT(8) COMMENT 'Just a timestamp field.', danielebarchiesi@0: // PRIMARY KEY(nid) danielebarchiesi@0: // ); danielebarchiesi@0: danielebarchiesi@0: // First, the entry $data['example_table']['table'] describes properties of danielebarchiesi@0: // the actual table – not its content. danielebarchiesi@0: danielebarchiesi@0: // The 'group' index will be used as a prefix in the UI for any of this danielebarchiesi@0: // table's fields, sort criteria, etc. so it's easy to tell where they came danielebarchiesi@0: // from. danielebarchiesi@0: $data['example_table']['table']['group'] = t('Example table'); danielebarchiesi@0: danielebarchiesi@0: // Define this as a base table – a table that can be described in itself by danielebarchiesi@0: // views (and not just being brought in as a relationship). In reality this danielebarchiesi@0: // is not very useful for this table, as it isn't really a distinct object of danielebarchiesi@0: // its own, but it makes a good example. danielebarchiesi@0: $data['example_table']['table']['base'] = array( danielebarchiesi@0: 'field' => 'nid', // This is the identifier field for the view. danielebarchiesi@0: 'title' => t('Example table'), danielebarchiesi@0: 'help' => t('Example table contains example content and can be related to nodes.'), danielebarchiesi@0: 'weight' => -10, danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // This table references the {node} table. The declaration below creates an danielebarchiesi@0: // 'implicit' relationship to the node table, so that when 'node' is the base danielebarchiesi@0: // table, the fields are automatically available. danielebarchiesi@0: $data['example_table']['table']['join'] = array( danielebarchiesi@0: // Index this array by the table name to which this table refers. danielebarchiesi@0: // 'left_field' is the primary key in the referenced table. danielebarchiesi@0: // 'field' is the foreign key in this table. danielebarchiesi@0: 'node' => array( danielebarchiesi@0: 'left_field' => 'nid', danielebarchiesi@0: 'field' => 'nid', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // Next, describe each of the individual fields in this table to Views. This danielebarchiesi@0: // is done by describing $data['example_table']['FIELD_NAME']. This part of danielebarchiesi@0: // the array may then have further entries: danielebarchiesi@0: // - title: The label for the table field, as presented in Views. danielebarchiesi@0: // - help: The description text for the table field. danielebarchiesi@0: // - relationship: A description of any relationship handler for the table danielebarchiesi@0: // field. danielebarchiesi@0: // - field: A description of any field handler for the table field. danielebarchiesi@0: // - sort: A description of any sort handler for the table field. danielebarchiesi@0: // - filter: A description of any filter handler for the table field. danielebarchiesi@0: // - argument: A description of any argument handler for the table field. danielebarchiesi@0: // - area: A description of any handler for adding content to header, danielebarchiesi@0: // footer or as no result behaviour. danielebarchiesi@0: // danielebarchiesi@0: // The handler descriptions are described with examples below. danielebarchiesi@0: danielebarchiesi@0: // Node ID table field. danielebarchiesi@0: $data['example_table']['nid'] = array( danielebarchiesi@0: 'title' => t('Example content'), danielebarchiesi@0: 'help' => t('Some example content that references a node.'), danielebarchiesi@0: // Define a relationship to the {node} table, so example_table views can danielebarchiesi@0: // add a relationship to nodes. If you want to define a relationship the danielebarchiesi@0: // other direction, use hook_views_data_alter(), or use the 'implicit' join danielebarchiesi@0: // method described above. danielebarchiesi@0: 'relationship' => array( danielebarchiesi@0: 'base' => 'node', // The name of the table to join with. danielebarchiesi@0: 'base field' => 'nid', // The name of the field on the joined table. danielebarchiesi@0: // 'field' => 'nid' -- see hook_views_data_alter(); not needed here. danielebarchiesi@0: 'handler' => 'views_handler_relationship', danielebarchiesi@0: 'label' => t('Default label for the relationship'), danielebarchiesi@0: 'title' => t('Title shown when adding the relationship'), danielebarchiesi@0: 'help' => t('More information on this relationship'), danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // Example plain text field. danielebarchiesi@0: $data['example_table']['plain_text_field'] = array( danielebarchiesi@0: 'title' => t('Plain text field'), danielebarchiesi@0: 'help' => t('Just a plain text field.'), danielebarchiesi@0: 'field' => array( danielebarchiesi@0: 'handler' => 'views_handler_field', danielebarchiesi@0: 'click sortable' => TRUE, // This is use by the table display plugin. danielebarchiesi@0: ), danielebarchiesi@0: 'sort' => array( danielebarchiesi@0: 'handler' => 'views_handler_sort', danielebarchiesi@0: ), danielebarchiesi@0: 'filter' => array( danielebarchiesi@0: 'handler' => 'views_handler_filter_string', danielebarchiesi@0: ), danielebarchiesi@0: 'argument' => array( danielebarchiesi@0: 'handler' => 'views_handler_argument_string', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // Example numeric text field. danielebarchiesi@0: $data['example_table']['numeric_field'] = array( danielebarchiesi@0: 'title' => t('Numeric field'), danielebarchiesi@0: 'help' => t('Just a numeric field.'), danielebarchiesi@0: 'field' => array( danielebarchiesi@0: 'handler' => 'views_handler_field_numeric', danielebarchiesi@0: 'click sortable' => TRUE, danielebarchiesi@0: ), danielebarchiesi@0: 'filter' => array( danielebarchiesi@0: 'handler' => 'views_handler_filter_numeric', danielebarchiesi@0: ), danielebarchiesi@0: 'sort' => array( danielebarchiesi@0: 'handler' => 'views_handler_sort', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // Example boolean field. danielebarchiesi@0: $data['example_table']['boolean_field'] = array( danielebarchiesi@0: 'title' => t('Boolean field'), danielebarchiesi@0: 'help' => t('Just an on/off field.'), danielebarchiesi@0: 'field' => array( danielebarchiesi@0: 'handler' => 'views_handler_field_boolean', danielebarchiesi@0: 'click sortable' => TRUE, danielebarchiesi@0: ), danielebarchiesi@0: 'filter' => array( danielebarchiesi@0: 'handler' => 'views_handler_filter_boolean_operator', danielebarchiesi@0: // Note that you can override the field-wide label: danielebarchiesi@0: 'label' => t('Published'), danielebarchiesi@0: // This setting is used by the boolean filter handler, as possible option. danielebarchiesi@0: 'type' => 'yes-no', danielebarchiesi@0: // use boolean_field = 1 instead of boolean_field <> 0 in WHERE statment. danielebarchiesi@0: 'use equal' => TRUE, danielebarchiesi@0: ), danielebarchiesi@0: 'sort' => array( danielebarchiesi@0: 'handler' => 'views_handler_sort', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // Example timestamp field. danielebarchiesi@0: $data['example_table']['timestamp_field'] = array( danielebarchiesi@0: 'title' => t('Timestamp field'), danielebarchiesi@0: 'help' => t('Just a timestamp field.'), danielebarchiesi@0: 'field' => array( danielebarchiesi@0: 'handler' => 'views_handler_field_date', danielebarchiesi@0: 'click sortable' => TRUE, danielebarchiesi@0: ), danielebarchiesi@0: 'sort' => array( danielebarchiesi@0: 'handler' => 'views_handler_sort_date', danielebarchiesi@0: ), danielebarchiesi@0: 'filter' => array( danielebarchiesi@0: 'handler' => 'views_handler_filter_date', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: return $data; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Alter table structure. danielebarchiesi@0: * danielebarchiesi@0: * You can add/edit/remove existing tables defined by hook_views_data(). danielebarchiesi@0: * danielebarchiesi@0: * This hook should be placed in MODULENAME.views.inc and it will be danielebarchiesi@0: * auto-loaded. MODULENAME.views.inc must be in the directory specified by the danielebarchiesi@0: * 'path' key returned by MODULENAME_views_api(), or the same directory as the danielebarchiesi@0: * .module file, if 'path' is unspecified. danielebarchiesi@0: * danielebarchiesi@0: * @param $data danielebarchiesi@0: * An array of all Views data, passed by reference. See hook_views_data() for danielebarchiesi@0: * structure. danielebarchiesi@0: * danielebarchiesi@0: * @see hook_views_data() danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_data_alter(&$data) { danielebarchiesi@0: // This example alters the title of the node:nid field in the Views UI. danielebarchiesi@0: $data['node']['nid']['title'] = t('Node-Nid'); danielebarchiesi@0: danielebarchiesi@0: // This example adds an example field to the users table. danielebarchiesi@0: $data['users']['example_field'] = array( danielebarchiesi@0: 'title' => t('Example field'), danielebarchiesi@0: 'help' => t('Some example content that references a user'), danielebarchiesi@0: 'field' => array( danielebarchiesi@0: 'handler' => 'modulename_handler_field_example_field', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // This example changes the handler of the node title field. danielebarchiesi@0: // In this handler you could do stuff, like preview of the node when clicking danielebarchiesi@0: // the node title. danielebarchiesi@0: $data['node']['title']['field']['handler'] = 'modulename_handler_field_node_title'; danielebarchiesi@0: danielebarchiesi@0: // This example adds a relationship to table {foo}, so that 'foo' views can danielebarchiesi@0: // add this table using a relationship. Because we don't want to write over danielebarchiesi@0: // the primary key field definition for the {foo}.fid field, we use a dummy danielebarchiesi@0: // field name as the key. danielebarchiesi@0: $data['foo']['dummy_name'] = array( danielebarchiesi@0: 'title' => t('Example relationship'), danielebarchiesi@0: 'help' => t('Example help'), danielebarchiesi@0: 'relationship' => array( danielebarchiesi@0: 'base' => 'example_table', // Table we're joining to. danielebarchiesi@0: 'base field' => 'eid', // Field on the joined table. danielebarchiesi@0: 'field' => 'fid', // Real field name on the 'foo' table. danielebarchiesi@0: 'handler' => 'views_handler_relationship', danielebarchiesi@0: 'label' => t('Default label for relationship'), danielebarchiesi@0: 'title' => t('Title seen when adding relationship'), danielebarchiesi@0: 'help' => t('More information about relationship.'), danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // Note that the $data array is not returned – it is modified by reference. danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Describes plugins defined by the module. danielebarchiesi@0: * danielebarchiesi@0: * This hook should be placed in MODULENAME.views.inc and it will be danielebarchiesi@0: * auto-loaded. MODULENAME.views.inc must be in the directory specified by the danielebarchiesi@0: * 'path' key returned by MODULENAME_views_api(), or the same directory as the danielebarchiesi@0: * .module file, if 'path' is unspecified. All plugin files need to be danielebarchiesi@0: * referenced in MODULENAME.info with the files[] directive. danielebarchiesi@0: * danielebarchiesi@0: * @return danielebarchiesi@0: * An array on the form $plugins['PLUGIN TYPE']['PLUGIN NAME']. The plugin danielebarchiesi@0: * must be one of row, display, display_extender, style, argument default, danielebarchiesi@0: * argument validator, access, query, cache, pager, exposed_form or danielebarchiesi@0: * localization. The plugin name should be prefixed with your module name. danielebarchiesi@0: * The value for each entry is an associateive array that may contain the danielebarchiesi@0: * following entries: danielebarchiesi@0: * - Used by all plugin types: danielebarchiesi@0: * - title (required): The name of the plugin, as shown in Views. Wrap in danielebarchiesi@0: * t(). danielebarchiesi@0: * - handler (required): The name of the file containing the class danielebarchiesi@0: * describing the handler, which must also be the name of the handler's danielebarchiesi@0: * class. danielebarchiesi@0: * - path: Path to the handler. Only required if the handler is not placed danielebarchiesi@0: * in the same folder as the .module file or in the subfolder 'views'. danielebarchiesi@0: * - parent: The name of the plugin this plugin extends. Since Drupal 7 this danielebarchiesi@0: * is no longer required, but may still be useful from a code readability danielebarchiesi@0: * perspective. danielebarchiesi@0: * - no ui: Set to TRUE to denote that the plugin doesn't appear to be danielebarchiesi@0: * selectable in the ui, though on the api side they still exists. danielebarchiesi@0: * - uses options: Set to TRUE to denote that the plugin has an additional danielebarchiesi@0: * options form. danielebarchiesi@0: * - help: A short help text, wrapped in t() used as description on the plugin settings form. danielebarchiesi@0: * - help topic: The name of an entry by advanced help for the plugin. danielebarchiesi@0: * - theme: The name of a theme suggestion to use for the display. danielebarchiesi@0: * - js: An array with paths to js files that should be included for the danielebarchiesi@0: * display. Note that the path should be relative Drupal root, not module danielebarchiesi@0: * root. danielebarchiesi@0: * - type: Each plugin can specify a type parameter to group certain danielebarchiesi@0: * plugins together. For example all row plugins related to feeds are danielebarchiesi@0: * grouped together, because a rss style plugin only accepts feed row danielebarchiesi@0: * plugins. danielebarchiesi@0: * danielebarchiesi@0: * - Used by display plugins: danielebarchiesi@0: * - admin: The administrative name of the display, as displayed on the danielebarchiesi@0: * Views overview and also used as default name for new displays. Wrap in danielebarchiesi@0: * t(). danielebarchiesi@0: * - no remove: Set to TRUE to make the display non-removable. (Basically danielebarchiesi@0: * only used for the master/default display.) danielebarchiesi@0: * - use ajax: Set to TRUE to allow AJAX loads in the display. If it's danielebarchiesi@0: * disabled there will be no ajax option in the ui. danielebarchiesi@0: * - use pager: Set to TRUE to allow paging in the display. danielebarchiesi@0: * - use more: Set to TRUE to allow the 'use more' setting in the display. danielebarchiesi@0: * - accept attachments: Set to TRUE to allow attachment displays to be danielebarchiesi@0: * attached to this display type. danielebarchiesi@0: * - contextual links locations: An array with places where contextual links danielebarchiesi@0: * should be added. Can for example be 'page' or 'block'. If you don't danielebarchiesi@0: * specify it there will be contextual links around the rendered view. If danielebarchiesi@0: * this is not set or regions have been specified, views will display an danielebarchiesi@0: * option to 'hide contextual links'. Use an empty array if you do not want danielebarchiesi@0: * this. danielebarchiesi@0: * - uses hook menu: Set to TRUE to have the display included by danielebarchiesi@0: * views_menu_alter(). views_menu_alter executes then execute_hook_menu danielebarchiesi@0: * on the display object. danielebarchiesi@0: * - uses hook block: Set to TRUE to have the display included by danielebarchiesi@0: * views_block_info(). danielebarchiesi@0: * - theme: The name of a theme suggestion to use for the display. danielebarchiesi@0: * - js: An array with paths to js files that should be included for the danielebarchiesi@0: * display. Note that the path should be relative Drupal root, not module danielebarchiesi@0: * root. danielebarchiesi@0: * danielebarchiesi@0: * - Used by style plugins: danielebarchiesi@0: * - uses row plugin: Set to TRUE to allow row plugins for this style. danielebarchiesi@0: * - uses row class: Set to TRUE to allow the CSS class settings for rows. danielebarchiesi@0: * - uses fields: Set to TRUE to have the style plugin accept field danielebarchiesi@0: * handlers. danielebarchiesi@0: * - uses grouping: Set to TRUE to allow the grouping settings for rows. danielebarchiesi@0: * - even empty: May have the value 'even empty' to tell Views that the style danielebarchiesi@0: * should be rendered even if there are no results. danielebarchiesi@0: * danielebarchiesi@0: * - Used by row plugins: danielebarchiesi@0: * - uses fields: Set to TRUE to have the row plugin accept field handlers. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_plugins() { danielebarchiesi@0: $plugins = array(); danielebarchiesi@0: $plugins['argument validator'] = array( danielebarchiesi@0: 'taxonomy_term' => array( danielebarchiesi@0: 'title' => t('Taxonomy term'), danielebarchiesi@0: 'handler' => 'views_plugin_argument_validate_taxonomy_term', danielebarchiesi@0: // Declaring path explicitly not necessary for most modules. danielebarchiesi@0: 'path' => drupal_get_path('module', 'views') . '/modules/taxonomy', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: return array( danielebarchiesi@0: 'module' => 'views', // This just tells our themes are elsewhere. danielebarchiesi@0: 'argument validator' => array( danielebarchiesi@0: 'taxonomy_term' => array( danielebarchiesi@0: 'title' => t('Taxonomy term'), danielebarchiesi@0: 'handler' => 'views_plugin_argument_validate_taxonomy_term', danielebarchiesi@0: 'path' => drupal_get_path('module', 'views') . '/modules/taxonomy', // not necessary for most modules danielebarchiesi@0: ), danielebarchiesi@0: ), danielebarchiesi@0: 'argument default' => array( danielebarchiesi@0: 'taxonomy_tid' => array( danielebarchiesi@0: 'title' => t('Taxonomy term ID from URL'), danielebarchiesi@0: 'handler' => 'views_plugin_argument_default_taxonomy_tid', danielebarchiesi@0: 'path' => drupal_get_path('module', 'views') . '/modules/taxonomy', danielebarchiesi@0: 'parent' => 'fixed', danielebarchiesi@0: ), danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Alter existing plugins data, defined by modules. danielebarchiesi@0: * danielebarchiesi@0: * @see hook_views_plugins() danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_plugins_alter(&$plugins) { danielebarchiesi@0: // Add apachesolr to the base of the node row plugin. danielebarchiesi@0: $plugins['row']['node']['base'][] = 'apachesolr'; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Register View API information. danielebarchiesi@0: * danielebarchiesi@0: * This is required for your module to have its include files loaded; for danielebarchiesi@0: * example, when implementing hook_views_default_views(). danielebarchiesi@0: * danielebarchiesi@0: * @return danielebarchiesi@0: * An array with the following possible keys: danielebarchiesi@0: * - api: (required) The version of the Views API the module implements. danielebarchiesi@0: * - path: (optional) If includes are stored somewhere other than within the danielebarchiesi@0: * root module directory, specify its path here. danielebarchiesi@0: * - template path: (optional) A path where the module has stored it's views danielebarchiesi@0: * template files. When you have specificed this key views automatically danielebarchiesi@0: * uses the template files for the views. You can use the same naming danielebarchiesi@0: * conventions like for normal views template files. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_api() { danielebarchiesi@0: return array( danielebarchiesi@0: 'api' => 3, danielebarchiesi@0: 'path' => drupal_get_path('module', 'example') . '/includes/views', danielebarchiesi@0: 'template path' => drupal_get_path('module', 'example') . '/themes', danielebarchiesi@0: ); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hook allows modules to provide their own views which can either be used danielebarchiesi@0: * as-is or as a "starter" for users to build from. danielebarchiesi@0: * danielebarchiesi@0: * This hook should be placed in MODULENAME.views_default.inc and it will be danielebarchiesi@0: * auto-loaded. MODULENAME.views_default.inc must be in the directory specified danielebarchiesi@0: * by the 'path' key returned by MODULENAME_views_api(), or the same directory danielebarchiesi@0: * as the .module file, if 'path' is unspecified. danielebarchiesi@0: * danielebarchiesi@0: * The $view->disabled boolean flag indicates whether the View should be danielebarchiesi@0: * enabled (FALSE) or disabled (TRUE) by default. danielebarchiesi@0: * danielebarchiesi@0: * @return danielebarchiesi@0: * An associative array containing the structures of views, as generated from danielebarchiesi@0: * the Export tab, keyed by the view name. A best practice is to go through danielebarchiesi@0: * and add t() to all title and label strings, with the exception of menu danielebarchiesi@0: * strings. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_default_views() { danielebarchiesi@0: // Begin copy and paste of output from the Export tab of a view. danielebarchiesi@0: $view = new view; danielebarchiesi@0: $view->name = 'frontpage'; danielebarchiesi@0: $view->description = 'Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page.'; danielebarchiesi@0: $view->tag = 'default'; danielebarchiesi@0: $view->base_table = 'node'; danielebarchiesi@0: $view->human_name = 'Front page'; danielebarchiesi@0: $view->core = 0; danielebarchiesi@0: $view->api_version = '3.0'; danielebarchiesi@0: $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ danielebarchiesi@0: danielebarchiesi@0: /* Display: Master */ danielebarchiesi@0: $handler = $view->new_display('default', 'Master', 'default'); danielebarchiesi@0: $handler->display->display_options['access']['type'] = 'none'; danielebarchiesi@0: $handler->display->display_options['cache']['type'] = 'none'; danielebarchiesi@0: $handler->display->display_options['query']['type'] = 'views_query'; danielebarchiesi@0: $handler->display->display_options['query']['options']['query_comment'] = FALSE; danielebarchiesi@0: $handler->display->display_options['exposed_form']['type'] = 'basic'; danielebarchiesi@0: $handler->display->display_options['pager']['type'] = 'full'; danielebarchiesi@0: $handler->display->display_options['style_plugin'] = 'default'; danielebarchiesi@0: $handler->display->display_options['row_plugin'] = 'node'; danielebarchiesi@0: /* Sort criterion: Content: Sticky */ danielebarchiesi@0: $handler->display->display_options['sorts']['sticky']['id'] = 'sticky'; danielebarchiesi@0: $handler->display->display_options['sorts']['sticky']['table'] = 'node'; danielebarchiesi@0: $handler->display->display_options['sorts']['sticky']['field'] = 'sticky'; danielebarchiesi@0: $handler->display->display_options['sorts']['sticky']['order'] = 'DESC'; danielebarchiesi@0: /* Sort criterion: Content: Post date */ danielebarchiesi@0: $handler->display->display_options['sorts']['created']['id'] = 'created'; danielebarchiesi@0: $handler->display->display_options['sorts']['created']['table'] = 'node'; danielebarchiesi@0: $handler->display->display_options['sorts']['created']['field'] = 'created'; danielebarchiesi@0: $handler->display->display_options['sorts']['created']['order'] = 'DESC'; danielebarchiesi@0: /* Filter criterion: Content: Promoted to front page */ danielebarchiesi@0: $handler->display->display_options['filters']['promote']['id'] = 'promote'; danielebarchiesi@0: $handler->display->display_options['filters']['promote']['table'] = 'node'; danielebarchiesi@0: $handler->display->display_options['filters']['promote']['field'] = 'promote'; danielebarchiesi@0: $handler->display->display_options['filters']['promote']['value'] = '1'; danielebarchiesi@0: $handler->display->display_options['filters']['promote']['group'] = 0; danielebarchiesi@0: $handler->display->display_options['filters']['promote']['expose']['operator'] = FALSE; danielebarchiesi@0: /* Filter criterion: Content: Published */ danielebarchiesi@0: $handler->display->display_options['filters']['status']['id'] = 'status'; danielebarchiesi@0: $handler->display->display_options['filters']['status']['table'] = 'node'; danielebarchiesi@0: $handler->display->display_options['filters']['status']['field'] = 'status'; danielebarchiesi@0: $handler->display->display_options['filters']['status']['value'] = '1'; danielebarchiesi@0: $handler->display->display_options['filters']['status']['group'] = 0; danielebarchiesi@0: $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; danielebarchiesi@0: danielebarchiesi@0: /* Display: Page */ danielebarchiesi@0: $handler = $view->new_display('page', 'Page', 'page'); danielebarchiesi@0: $handler->display->display_options['path'] = 'frontpage'; danielebarchiesi@0: danielebarchiesi@0: /* Display: Feed */ danielebarchiesi@0: $handler = $view->new_display('feed', 'Feed', 'feed'); danielebarchiesi@0: $handler->display->display_options['defaults']['title'] = FALSE; danielebarchiesi@0: $handler->display->display_options['title'] = 'Front page feed'; danielebarchiesi@0: $handler->display->display_options['pager']['type'] = 'some'; danielebarchiesi@0: $handler->display->display_options['style_plugin'] = 'rss'; danielebarchiesi@0: $handler->display->display_options['row_plugin'] = 'node_rss'; danielebarchiesi@0: $handler->display->display_options['path'] = 'rss.xml'; danielebarchiesi@0: $handler->display->display_options['displays'] = array( danielebarchiesi@0: 'default' => 'default', danielebarchiesi@0: 'page' => 'page', danielebarchiesi@0: ); danielebarchiesi@0: $handler->display->display_options['sitename_title'] = '1'; danielebarchiesi@0: danielebarchiesi@0: // (Export ends here.) danielebarchiesi@0: danielebarchiesi@0: // Add view to list of views to provide. danielebarchiesi@0: $views[$view->name] = $view; danielebarchiesi@0: danielebarchiesi@0: // ...Repeat all of the above for each view the module should provide. danielebarchiesi@0: danielebarchiesi@0: // At the end, return array of default views. danielebarchiesi@0: return $views; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Alter default views defined by other modules. danielebarchiesi@0: * danielebarchiesi@0: * This hook is called right before all default views are cached to the danielebarchiesi@0: * database. It takes a keyed array of views by reference. danielebarchiesi@0: * danielebarchiesi@0: * Example usage to add a field to a view: danielebarchiesi@0: * @code danielebarchiesi@0: * $handler =& $view->display['DISPLAY_ID']->handler; danielebarchiesi@0: * // Add the user name field to the view. danielebarchiesi@0: * $handler->display->display_options['fields']['name']['id'] = 'name'; danielebarchiesi@0: * $handler->display->display_options['fields']['name']['table'] = 'users'; danielebarchiesi@0: * $handler->display->display_options['fields']['name']['field'] = 'name'; danielebarchiesi@0: * $handler->display->display_options['fields']['name']['label'] = 'Author'; danielebarchiesi@0: * $handler->display->display_options['fields']['name']['link_to_user'] = 1; danielebarchiesi@0: * @endcode danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_default_views_alter(&$views) { danielebarchiesi@0: if (isset($views['taxonomy_term'])) { danielebarchiesi@0: $views['taxonomy_term']->display['default']->display_options['title'] = 'Categories'; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Performs replacements in the query before being performed. danielebarchiesi@0: * danielebarchiesi@0: * @param $view danielebarchiesi@0: * The View being executed. danielebarchiesi@0: * @return danielebarchiesi@0: * An array with keys being the strings to replace, and the values the strings danielebarchiesi@0: * to replace them with. The strings to replace are ofted surrounded with danielebarchiesi@0: * '***', as illustrated in the example implementation. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_query_substitutions($view) { danielebarchiesi@0: // Example from views_views_query_substitutions(). danielebarchiesi@0: global $language_content; danielebarchiesi@0: return array( danielebarchiesi@0: '***CURRENT_VERSION***' => VERSION, danielebarchiesi@0: '***CURRENT_TIME***' => REQUEST_TIME, danielebarchiesi@0: '***CURRENT_LANGUAGE***' => $language_content->language, danielebarchiesi@0: '***DEFAULT_LANGUAGE***' => language_default('language'), danielebarchiesi@0: ); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hook is called to get a list of placeholders and their substitutions, danielebarchiesi@0: * used when preprocessing a View with form elements. danielebarchiesi@0: * danielebarchiesi@0: * @return danielebarchiesi@0: * An array with keys being the strings to replace, and the values the strings danielebarchiesi@0: * to replace them with. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_form_substitutions() { danielebarchiesi@0: return array( danielebarchiesi@0: '' => 'Example Substitution', danielebarchiesi@0: ); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Allows altering a view at the very beginning of views processing, before danielebarchiesi@0: * anything is done. danielebarchiesi@0: * danielebarchiesi@0: * Adding output to the view can be accomplished by placing text on danielebarchiesi@0: * $view->attachment_before and $view->attachment_after. danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object about to be processed. danielebarchiesi@0: * @param $display_id danielebarchiesi@0: * The machine name of the active display. danielebarchiesi@0: * @param $args danielebarchiesi@0: * An array of arguments passed into the view. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_pre_view(&$view, &$display_id, &$args) { danielebarchiesi@0: // Change the display if the acting user has 'administer site configuration' danielebarchiesi@0: // permission, to display something radically different. danielebarchiesi@0: // (Note that this is not necessarily the best way to solve that task. Feel danielebarchiesi@0: // free to contribute another example!) danielebarchiesi@0: if ( danielebarchiesi@0: $view->name == 'my_special_view' && danielebarchiesi@0: user_access('administer site configuration') && danielebarchiesi@0: $display_id == 'public_display' danielebarchiesi@0: ) { danielebarchiesi@0: $display_id = 'private_display'; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hook is called right before the build process, but after displays danielebarchiesi@0: * are attached and the display performs its pre_execute phase. danielebarchiesi@0: * danielebarchiesi@0: * Adding output to the view can be accomplished by placing text on danielebarchiesi@0: * $view->attachment_before and $view->attachment_after. danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object about to be processed. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_pre_build(&$view) { danielebarchiesi@0: // Because of some unexplicable business logic, we should remove all danielebarchiesi@0: // attachments from all views on Mondays. danielebarchiesi@0: // (This alter could be done later in the execution process as well.) danielebarchiesi@0: if (date('D') == 'Mon') { danielebarchiesi@0: unset($view->attachment_before); danielebarchiesi@0: unset($view->attachment_after); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hook is called right after the build process. The query is now fully danielebarchiesi@0: * built, but it has not yet been run through db_rewrite_sql. danielebarchiesi@0: * danielebarchiesi@0: * Adding output to the view can be accomplished by placing text on danielebarchiesi@0: * $view->attachment_before and $view->attachment_after. danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object about to be processed. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_post_build(&$view) { danielebarchiesi@0: // If the exposed field 'type' is set, hide the column containing the content danielebarchiesi@0: // type. (Note that this is a solution for a particular view, and makes danielebarchiesi@0: // assumptions about both exposed filter settings and the fields in the view. danielebarchiesi@0: // Also note that this alter could be done at any point before the view being danielebarchiesi@0: // rendered.) danielebarchiesi@0: if ($view->name == 'my_view' && isset($view->exposed_raw_input['type']) && $view->exposed_raw_input['type'] != 'All') { danielebarchiesi@0: // 'Type' should be interpreted as content type. danielebarchiesi@0: if (isset($view->field['type'])) { danielebarchiesi@0: $view->field['type']->options['exclude'] = TRUE; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hook is called right before the execute process. The query is now fully danielebarchiesi@0: * built, but it has not yet been run through db_rewrite_sql. danielebarchiesi@0: * danielebarchiesi@0: * Adding output to the view can be accomplished by placing text on danielebarchiesi@0: * $view->attachment_before and $view->attachment_after. danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object about to be processed. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_pre_execute(&$view) { danielebarchiesi@0: // Whenever a view queries more than two tables, show a message that notifies danielebarchiesi@0: // view administrators that the query might be heavy. danielebarchiesi@0: // (This action could be performed later in the execution process, but not danielebarchiesi@0: // earlier.) danielebarchiesi@0: if (count($view->query->tables) > 2 && user_access('administer views')) { danielebarchiesi@0: drupal_set_message(t('The view %view may be heavy to execute.', array('%view' => $view->name)), 'warning'); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hook is called right after the execute process. The query has danielebarchiesi@0: * been executed, but the pre_render() phase has not yet happened for danielebarchiesi@0: * handlers. danielebarchiesi@0: * danielebarchiesi@0: * Adding output to the view can be accomplished by placing text on danielebarchiesi@0: * $view->attachment_before and $view->attachment_after. Altering the danielebarchiesi@0: * content can be achieved by editing the items of $view->result. danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object about to be processed. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_post_execute(&$view) { danielebarchiesi@0: // If there are more than 100 results, show a message that encourages the user danielebarchiesi@0: // to change the filter settings. danielebarchiesi@0: // (This action could be performed later in the execution process, but not danielebarchiesi@0: // earlier.) danielebarchiesi@0: if ($view->total_rows > 100) { danielebarchiesi@0: drupal_set_message(t('You have more than 100 hits. Use the filter settings to narrow down your list.')); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hook is called right before the render process. The query has been danielebarchiesi@0: * executed, and the pre_render() phase has already happened for handlers, so danielebarchiesi@0: * all data should be available. danielebarchiesi@0: * danielebarchiesi@0: * Adding output to the view can be accomplished by placing text on danielebarchiesi@0: * $view->attachment_before and $view->attachment_after. Altering the content danielebarchiesi@0: * can be achieved by editing the items of $view->result. danielebarchiesi@0: * danielebarchiesi@0: * This hook can be utilized by themes. danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object about to be processed. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_pre_render(&$view) { danielebarchiesi@0: // Scramble the order of the rows shown on this result page. danielebarchiesi@0: // Note that this could be done earlier, but not later in the view execution danielebarchiesi@0: // process. danielebarchiesi@0: shuffle($view->result); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Post process any rendered data. danielebarchiesi@0: * danielebarchiesi@0: * This can be valuable to be able to cache a view and still have some level of danielebarchiesi@0: * dynamic output. In an ideal world, the actual output will include HTML danielebarchiesi@0: * comment based tokens, and then the post process can replace those tokens. danielebarchiesi@0: * danielebarchiesi@0: * Example usage. If it is known that the view is a node view and that the danielebarchiesi@0: * primary field will be a nid, you can do something like this: danielebarchiesi@0: * danielebarchiesi@0: * danielebarchiesi@0: * danielebarchiesi@0: * And then in the post render, create an array with the text that should danielebarchiesi@0: * go there: danielebarchiesi@0: * danielebarchiesi@0: * strtr($output, array('' => 'output for FIELD of nid 1'); danielebarchiesi@0: * danielebarchiesi@0: * All of the cached result data will be available in $view->result, as well, danielebarchiesi@0: * so all ids used in the query should be discoverable. danielebarchiesi@0: * danielebarchiesi@0: * This hook can be utilized by themes. danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object about to be processed. danielebarchiesi@0: * @param $output danielebarchiesi@0: * A flat string with the rendered output of the view. danielebarchiesi@0: * @param $cache danielebarchiesi@0: * The cache settings. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_post_render(&$view, &$output, &$cache) { danielebarchiesi@0: // When using full pager, disable any time-based caching if there are less danielebarchiesi@0: // then 10 results. danielebarchiesi@0: if ($view->query->pager instanceof views_plugin_pager_full && $cache->options['type'] == 'time' && count($view->result) < 10) { danielebarchiesi@0: $cache['options']['results_lifespan'] = 0; danielebarchiesi@0: $cache['options']['output_lifespan'] = 0; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Alter the query before executing the query. danielebarchiesi@0: * danielebarchiesi@0: * This hook should be placed in MODULENAME.views.inc and it will be danielebarchiesi@0: * auto-loaded. MODULENAME.views.inc must be in the directory specified by the danielebarchiesi@0: * 'path' key returned by MODULENAME_views_api(), or the same directory as the danielebarchiesi@0: * .module file, if 'path' is unspecified. danielebarchiesi@0: * danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object about to be processed. danielebarchiesi@0: * @param $query danielebarchiesi@0: * An object describing the query. danielebarchiesi@0: * @see hook_views_query_substitutions() danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_query_alter(&$view, &$query) { danielebarchiesi@0: // (Example assuming a view with an exposed filter on node title.) danielebarchiesi@0: // If the input for the title filter is a positive integer, filter against danielebarchiesi@0: // node ID instead of node title. danielebarchiesi@0: if ($view->name == 'my_view' && is_numeric($view->exposed_raw_input['title']) && $view->exposed_raw_input['title'] > 0) { danielebarchiesi@0: // Traverse through the 'where' part of the query. danielebarchiesi@0: foreach ($query->where as &$condition_group) { danielebarchiesi@0: foreach ($condition_group['conditions'] as &$condition) { danielebarchiesi@0: // If this is the part of the query filtering on title, chang the danielebarchiesi@0: // condition to filter on node ID. danielebarchiesi@0: if ($condition['field'] == 'node.title') { danielebarchiesi@0: $condition = array( danielebarchiesi@0: 'field' => 'node.nid', danielebarchiesi@0: 'value' => $view->exposed_raw_input['title'], danielebarchiesi@0: 'operator' => '=', danielebarchiesi@0: ); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Alter the information box that (optionally) appears with a view preview, danielebarchiesi@0: * including query and performance statistics. danielebarchiesi@0: * danielebarchiesi@0: * This hook should be placed in MODULENAME.views.inc and it will be danielebarchiesi@0: * auto-loaded. MODULENAME.views.inc must be in the directory specified by the danielebarchiesi@0: * 'path' key returned by MODULENAME_views_api(), or the same directory as the danielebarchiesi@0: * .module file, if 'path' is unspecified. danielebarchiesi@0: * danielebarchiesi@0: * Warning: $view is not a reference in PHP4 and cannot be modified here. But it danielebarchiesi@0: * IS a reference in PHP5, and can be modified. Please be careful with it. danielebarchiesi@0: * danielebarchiesi@0: * @param $rows danielebarchiesi@0: * An associative array with two keys: danielebarchiesi@0: * - query: An array of rows suitable for theme('table'), containing danielebarchiesi@0: * information about the query and the display title and path. danielebarchiesi@0: * - statistics: An array of rows suitable for theme('table'), containing danielebarchiesi@0: * performance statistics. danielebarchiesi@0: * @param $view danielebarchiesi@0: * The view object. danielebarchiesi@0: * @see theme_table() danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_preview_info_alter(&$rows, $view) { danielebarchiesi@0: // Adds information about the tables being queried by the view to the query danielebarchiesi@0: // part of the info box. danielebarchiesi@0: $rows['query'][] = array( danielebarchiesi@0: t('Table queue'), danielebarchiesi@0: count($view->query->table_queue) . ': (' . implode(', ', array_keys($view->query->table_queue)) . ')', danielebarchiesi@0: ); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hooks allows to alter the links at the top of the view edit form. Some danielebarchiesi@0: * modules might want to add links there. danielebarchiesi@0: * danielebarchiesi@0: * @param $links danielebarchiesi@0: * An array of links which will be displayed at the top of the view edit form. danielebarchiesi@0: * Each entry should be on a form suitable for theme('link'). danielebarchiesi@0: * @param view $view danielebarchiesi@0: * The full view object which is currently edited. danielebarchiesi@0: * @param $display_id danielebarchiesi@0: * The current display id which is edited. For example that's 'default' or danielebarchiesi@0: * 'page_1'. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_ui_display_top_links_alter(&$links, $view, $display_id) { danielebarchiesi@0: // Put the export link first in the list. danielebarchiesi@0: if (isset($links['export'])) { danielebarchiesi@0: $links = array('export' => $links['export']) + $links; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * This hook allows to alter the commands which are used on a views ajax danielebarchiesi@0: * request. danielebarchiesi@0: * danielebarchiesi@0: * @param $commands danielebarchiesi@0: * An array of ajax commands danielebarchiesi@0: * @param $view view danielebarchiesi@0: * The view which is requested. danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_ajax_data_alter(&$commands, $view) { danielebarchiesi@0: // Replace Views' method for scrolling to the top of the element with your danielebarchiesi@0: // custom scrolling method. danielebarchiesi@0: foreach ($commands as &$command) { danielebarchiesi@0: if ($command['method'] == 'viewsScrollTop') { danielebarchiesi@0: $command['method'] .= 'myScrollTop'; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Allow modules to respond to the Views cache being invalidated. danielebarchiesi@0: * danielebarchiesi@0: * This hook should fire whenever a view is enabled, disabled, created, danielebarchiesi@0: * updated, or deleted. danielebarchiesi@0: * danielebarchiesi@0: * @see views_invalidate_cache() danielebarchiesi@0: */ danielebarchiesi@0: function hook_views_invalidate_cache() { danielebarchiesi@0: cache_clear_all('views:*', 'cache_mymodule', TRUE); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * @} danielebarchiesi@0: */ danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * @defgroup views_module_handlers Views module handlers danielebarchiesi@0: * @{ danielebarchiesi@0: * Handlers exposed by various modules to Views. danielebarchiesi@0: * @} danielebarchiesi@0: */