+ drush_log(dt('A total of @total views were analyzed and @messages problems were found.', array('@total' => $total, '@messages' => $messages_count)), 'ok');
+ '#value' => t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.'),
+ );
+ }
+
+ /**
+ * Determine if the handler is considered 'broken'
+ $output = '<p>' . t('The following tokens are available. If you would like to have the characters \'[\' and \']\' please use the html entity codes \'%5B\' or \'%5D\' or they will get replaced with empty space.' . '</p>');
+ '#description' => t('Select whether to include this default argument when constructing the URL for this view. Skipping default arguments is useful e.g. in the case of feeds.')
+ function ensure_my_table() { /* No table to ensure! */ }
+ function query($group_by = FALSE) { /* No query to run */ }
+ function options_form(&$form, &$form_state) {
+ $form['markup'] = array(
+ '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+ );
+ }
+
+ /**
+ * Determine if the handler is considered 'broken'
+ '#title' => t('Allow multiple filter values to work together'),
+ '#description' => t('If selected, multiple instances of this filter can work together, as though multiple values were supplied to the same filter. This setting is not compatible with the "Reduce duplicates" setting.'),
+ '#description' => t('Glossary mode applies a limit to the number of characters used in the filter value, which allows the summary view to act as a glossary.'),
+ '#default_value' => $this->options['glossary'],
+ '#fieldset' => 'more',
+ );
+
+ $form['limit'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Character limit'),
+ '#description' => t('How many characters of the filter value to filter against. If set to 1, all fields starting with the first letter in the filter value would be matched.'),
+ '#description' => t('When printing the title and summary, how to transform the case of the filter value.'),
+ '#options' => array(
+ 'none' => t('No transform'),
+ 'upper' => t('Upper case'),
+ 'lower' => t('Lower case'),
+ 'ucfirst' => t('Capitalize first letter'),
+ 'ucwords' => t('Capitalize each word'),
+ ),
+ '#default_value' => $this->options['case'],
+ '#fieldset' => 'more',
+ );
+
+ $form['path_case'] = array(
+ '#type' => 'select',
+ '#title' => t('Case in path'),
+ '#description' => t('When printing url paths, how to transform the case of the filter value. Do not use this unless with Postgres as it uses case sensitive comparisons.'),
+ '#title' => t('Allow multiple filter values to work together'),
+ '#description' => t('If selected, multiple instances of this filter can work together, as though multiple values were supplied to the same filter. This setting is not compatible with the "Reduce duplicates" setting.'),
+ debug(t('Handler @handler tried to add additional_field @identifier but @table could not be added!', array('@handler' => $this->definition['handler'], '@identifier' => $identifier, '@table' => $info['table'])));
+ '#description' => t('Choose the HTML element to wrap around this field and label, e.g. H1, H2, etc. This may not be used if the field and label are not rendered together, such as with a table.'),
+ '#description' => t('The text to display for this field. You may include HTML. You may enter data from this view as per the "Replacement patterns" below.'),
+ '#dependency' => array(
+ 'edit-options-alter-alter-text' => array(1),
+ ),
+ );
+
+ $form['alter']['make_link'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Output this field as a link'),
+ '#description' => t('If checked, this field will be made into a link. The destination must be given below.'),
+ $output = t('<p>You must add some additional fields to this display before using this field. These fields may be marked as <em>Exclude from display</em> if you prefer. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>');
+ // We have some options, so make a list.
+ if (!empty($options)) {
+ $output = t('<p>The following tokens are available for this field. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.
+If you would like to have the characters \'[\' and \']\' please use the html entity codes \'%5B\' or \'%5D\' or they will get replaced with empty space.</p>');
+ foreach (array_keys($options) as $type) {
+ if (!empty($options[$type])) {
+ $items = array();
+ foreach ($options[$type] as $key => $value) {
+ $items[] = $key . ' == ' . check_plain($value);
+ }
+ $output .= theme('item_list',
+ array(
+ 'items' => $items,
+ 'type' => $type
+ ));
+ }
+ }
+ }
+ // This construct uses 'hidden' and not markup because process doesn't
+ // run. It also has an extra div because the dependency wants to hide
+ // the parent in situations like this, so we need a second div to
+ // make this work.
+ $form['alter']['help'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Replacement patterns'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#value' => $output,
+ '#dependency' => array(
+ 'edit-options-alter-make-link' => array(1),
+ 'edit-options-alter-alter-text' => array(1),
+ 'edit-options-alter-more-link' => array(1),
+ ),
+ );
+
+ $form['alter']['trim'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Trim this field to a maximum length'),
+ '#description' => t('Enable to trim the field to a maximum length of characters'),
+ '#description' => t('The maximum number of characters this field can be.'),
+ '#dependency' => array(
+ 'edit-options-alter-trim' => array(1),
+ ),
+ );
+
+ $form['alter']['word_boundary'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Trim only on a word boundary'),
+ '#description' => t('If checked, this field be trimmed only on a word boundary. This is guaranteed to be the maximum characters stated or less. If there are no word boundaries this could trim a field to nothing.'),
+ '#description' => t('The text which will be displayed on the more link. You may enter data from this view as per the "Replacement patterns" above.'),
+ '#description' => t('List the tags that need to be preserved during the stripping process. example "<p> <br>" which will preserve all p and br elements'),
+ '#description' => t('Provide text to display if this field contains an empty result. You may include HTML. You may enter data from this view as per the "Replacement patterns" in the "Rewrite Results" section below.'),
+ '#description' => t('Enable to hide this field if it is empty. Note that the field label or rewritten output may still be displayed. To hide labels, check the style or row style settings for empty fields. To hide rewritten content, check the "Hide rewriting if empty" checkbox.'),
+ function ensure_my_table() { /* No table to ensure! */ }
+ function query($group_by = FALSE) { /* No query to run */ }
+ function options_form(&$form, &$form_state) {
+ $form['markup'] = array(
+ '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+ );
+ }
+
+ /**
+ * Determine if the handler is considered 'broken'
+ '#description' => t('If "Custom", see the <a href="@url" target="_blank">PHP manual</a> for date formats. Otherwise, enter the number of different time units to display, which defaults to 2.', array('@url' => 'http://php.net/manual/function.date.php')),
+ if (in_array($format, array('custom', 'raw time ago', 'time ago', 'raw time hence', 'time hence', 'raw time span', 'time span', 'raw time span', 'inverse time span', 'time span'))) {
+ '#description' => t('Enter mathematical expressions such as 2 + 2 or sqrt(5). You may assign variables and create mathematical functions and evaluate them. Use the ; to separate these. For example: f(x) = x + 2; f(2).'),
+ '#title' => t('Expose this filter to visitors, to allow them to change it'),
+ '#type' => 'checkbox',
+ );
+
+ // Then add the button itself.
+ if (empty($this->options['exposed'])) {
+ $form['expose_button']['markup'] = array(
+ '#markup' => '<div class="description exposed-description">' . t('This filter is not exposed. Expose it to allow the users to change it.') . '</div>',
+ '#markup' => '<div class="description exposed-description">' . t('This filter is exposed. If you hide it, users will not be able to change it.') . '</div>',
+ '#description' => t('Remember exposed selection only for the selected user role(s). If you select no roles, the exposed data will never be stored.'),
+ function ensure_my_table() { /* No table to ensure! */ }
+ function query($group_by = FALSE) { /* No query to run */ }
+ function options_form(&$form, &$form_state) {
+ $form['markup'] = array(
+ '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+ );
+ }
+
+ /**
+ * Determine if the handler is considered 'broken'
+ */
+ function broken() { return TRUE; }
+}
+
+/**
+ * Filter by no empty values, though allow to use "0".
+ 'date' => t('A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred.'),
+ 'offset' => t('An offset from the current time such as "!example1" or "!example2"', array('!example1' => '+1 day', '!example2' => '-2 hours -30 minutes')),
+ $errors[] = t('The value @value is not an array for @operator on filter: @filter', array('@value' => views_var_export($this->value), '@operator' => $this->operator, '@filter' => $this->ui_name(TRUE)));
+ function ensure_my_table() { /* No table to ensure! */ }
+ function query() { /* No query to run */ }
+ function options_form(&$form, &$form_state) {
+ $form['markup'] = array(
+ '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+ );
+ }
+
+ /**
+ * Determine if the handler is considered 'broken'
+ t("The sort criteria is applied to the data brought in by the relationship to determine how a representative item is obtained for each row. For example, to show the most recent node for each user, pick 'Content: Updated date'."),
+ );
+
+ $form['subquery_order'] = array(
+ '#type' => 'radios',
+ '#title' => t('Representative sort order'),
+ '#description' => t("The ordering to use for the sort criteria selected above."),
+ '#description' => t('Advanced. Use another view to generate the relationship subquery. This allows you to use filtering and more than one sort. If you pick a view here, the sort options above are ignored. Your view must have the ID of its base as its only field, and should have some kind of sorting.'),
+ );
+
+ $form['subquery_regenerate'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Generate subquery each time view is run.'),
+ '#description' => t('Will re-generate the subquery for this relationship every time the view is run, instead of only when these options are saved. Use for testing if you are making changes elsewhere. WARNING: seriously impairs performance.'),
+ );
+ }
+
+ /**
+ * Helper function to create a pseudo view.
+ *
+ * We use this to obtain our subquery SQL.
+ */
+ function get_temporary_view() {
+ views_include('view');
+ $view = new view();
+ $view->vid = 'new'; // @todo: what's this?
+ $view->base_table = $this->definition['base'];
+ $view->add_display('default');
+ return $view;
+ }
+
+ /**
+ * When the form is submitted, take sure to clear the subquery string cache.
+ */
+ function options_form_submit(&$form, &$form_state) {
+ '#title' => t('Expose this sort to visitors, to allow them to change it'),
+ '#type' => 'checkbox',
+ );
+
+ // Then add the button itself.
+ if (empty($this->options['exposed'])) {
+ $form['expose_button']['markup'] = array(
+ '#markup' => '<div class="description exposed-description" style="float: left; margin-right:10px">' . t('This sort is not exposed. Expose it to allow the users to change it.') . '</div>',
+ '#markup' => '<div class="description exposed-description">' . t('This sort is exposed. If you hide it, users will not be able to change it.') . '</div>',
+ function ensure_my_table() { /* No table to ensure! */ }
+ function query($group_by = FALSE) { /* No query to run */ }
+ function options_form(&$form, &$form_state) {
+ $form['markup'] = array(
+ '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+ );
+ }
+
+ /**
+ * Determine if the handler is considered 'broken'
+ '#description' => t('The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is "Year" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date.'),
+ '#title' => t('Sort within each hierarchy level'),
+ '#description' => t('Enable this to sort the items within each level of the hierarchy by weight and title. Warning: this may produce a slow query.'),
+In the category <strong>Other</strong> you have different options to set Advanced configurations in your View.
+
+<strong>Machine Name:</strong>
+You can change the default machine name of the view.
+
+<strong>Comment: No comment</strong>
+You can Use the comment option to write comments for your Views, the comments are only shown in the Views UI. Comment your Display for other Maintainer
+
+<strong>Use AJAX: No</strong>
+If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This prevents the entire page from refreshing. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content. Block displays require this setting to be ON if exposed filters are being used.
+
+<strong>Hide attachments in summary: No</strong>
+
+<strong>Use aggregation: No</strong>
+All fields that are selected for grouping will be collapsed to one record per distinct value. Other fields which are selected for aggregation will have the function run on them. For example, you can group nodes on title and count the number of nids in order to get a list of duplicate titles.
+For more Information how aggregation work see the "Use Aggregation" Help Page
+
+<strong>Query settings: Settings</strong>
+
+Here can you set advanced Settings for the SQL Settings
+<ul>
+ <li><strong>Disable SQL rewriting</strong></li>
+
+ <li><strong>Distinct: No</strong></li>
+ This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution.
+
+ <li><strong>Use Slave Server</strong></li>
+
+ <li><strong>Query Comment</strong></li>
+</ul>
+<strong>Field Language: Current user's language</strong>
+
+<strong>Caching: None</strong>
+You can choose a "Time-based" Caching if you want. With it you get the option to choose the length of time raw query results should be cached and "The length of time rendered HTML output should be cached."
+
+<strong>Link display: Page</strong>
+
+<strong>CSS class: None</strong>
+You can define some own CSS Classes for your View
+
+<strong>Theme: Information</strong>
+Clicking on the "Theme: Information" link provides you with a listing of all posiible theming files. The highlighted files are the ones Views is currently using. All other filenames are suggested templates.
+For more Information see the <a href="/help/views/analyze-theme" title="Theme Information" >"Theme information"</a> Page
+In Views 3 you can set Advanced Style Settings, they help you to insert markup of your own from the Views UI, so that you can fairly easily override the default markup without having to restyle via templates.
+
+
+<ul>
+<li> Customize field HTML</li>
+With Customize field HTML you can generate html tags around the field.
+
+<li>Customize label HTML</li>
+Here you can generate html tags around the label of a field.
+
+<li>Customize field and label wrapper HTML</li>
+Here you can generate html tags around the wrapper of the label and field
+<li>Configure the field. (Click on the field.)</li>
+
+<li>In the modal that opens, scroll down to <strong>Style Settings</strong>.</li>
+
+<li>Choose one or more of the three <i>Customize</i> options. This will reveal a dropdown menu where you can choose from one or more HTML tags to use on that field and allow you to add a CSS class specific to that field should you desire.</li>
+
+<li>Decide if you want to keep the Views default classes. Unchecking this box means your markup is *it*.</li>
+</ol>
+
+In Views 2 you needed for Style Settings the <a href="http://drupal.org/project/semanticviews">Semantic Views</a> Modul, now the Semantic Views module has been mostly incorporated into Views 3.x. Semantic Views is still around for people who need it, though. For some details on how the original module is different from the Views implementation, please see <a href="http://drupal.org/node/1013876">this issue</a>.
+Modifying default values of a views exposed form is tricky, because FAPI was not designed to work with GET forms. One consequence is that it often can't tell if textfields (there are others) were submitted or not.
+
+As a consequence, it *always* thinks the value was submitted, even if it was not. To fix that, Views modifies $form_state['input'][$identifier] with the default value if $form_state['input'][$identifier] was not set. In order to modify the default value in an alter, you need to do this:
+where $identifier is the particular filter for which you want to change the default value, and $default_value is the new default value you want to set.
+
+If you use a hook_form_FORM_ID_alter or hook_form_alter, you can modify exposed filters on the fly based on information that is external to Views. For example, I modified the exposed filter of a form to set a taxonomy term ID based on the user's GeoIP.
+
+To do this, I used the following function, where geoip_redirect_get_tid() loads the relevant term id based on the user's current ip_address():
+<p>Clicking on the "Theme: Information" link provides you with a listing of all posiible theming files. The highlighted files are the ones Views is currently using. All other filenames are suggested templates.</p>
+<p>You may use any of the following possible theme files to modify individual parts of your view. In total, there are four parts to theming a view.</p>
+<ul>
+ <li> The <strong>display</strong> theme is usually views-view.tpl.php and it largely controls the decorations around a view; where the header, footer, pager, more link, feed icon, etc, will be placed. </li>
+
+ <li> The <strong>style</strong> will control how all of the results of the display are put together. It may be as simple as just displaying all of the rows, or it may be a complex table generator or something in between. </li>
+
+ <li> The <strong>row</strong> style controls each individual row; not all styles utilize the row style (notably the table), but most others do.
+
+ <li> Finally, <strong>field</strong> themes allow you to override the look and even the data of each individual field, if the style uses fields. The actual template the system will use should be hilighted in <strong>bold</strong>.</li>
+<p>The link to the left of each type will give you information about the default template used for that type. You may cut and paste this and place it in your theme with the appropriate template, or you may copy the base file from the views/theme directory (or, if provided by a module, from the module's directory). <strong>It is important that you clear the theme registry cache every time you add a new template, or the new template will not be picked up.</strong></p>
+
+<p><strong>Important note:</strong> You place your custom template files in your theme directory, <strong>not views/theme</strong>. This is always true of theming with Drupal.
+
+<p>In addition to this tool, the very useful <a href="http://drupal.org/project/devel">devel</a> module contains a tool called the "Theme developer" which does a good job of visually showing you which areas of your site use which themes. Be careful with it, though, as the theme developer causes the Views edit page to break.</p>
+
+<p>Also, this feature will only work properly with Drupal 6.3 and later; prior to Drupal 6.3 <a href="http://drupal.org/node/241570">this patch</a> will be required.</p>
+For the new table defined by the Node example module to be understood by the views module you need to create a node_example.views.inc file that describes the table and its relationships to the rest of the database. In order for views to know that this file is to be loaded you need to implement hook_views_api. This is done by adding the following function into your node_example.module file
+
+<pre>
+<?php
+/**
+ * Implements hook_views_api().
+ *
+ * This tells drupal that there is Views integration file named
+ * module-name.views.inc
+ */
+function node_example_views_api() {
+ // Note that you can include 'path' in this array so that your views.inc
+ // file can be stored in a different location.
+ return array(
+ 'api' => 2.0
+ );
+}
+?>
+</pre>
+
+Below is the contents of a simple node_example.views.inc file that allows you to create views that include the new color and quantity information.
+
+<pre>
+<?php
+
+/**
+ * This file is used to tell the views module about the new node_example table.
+ *
+ * Database definition:
+ * @code
+ * CREATE TABLE node_example (
+ * vid int(10) unsigned NOT NULL default '0',
+ * nid int(10) unsigned NOT NULL default '0',
+ * color varchar(255) NOT NULL default '',
+ * quantity int(10) unsigned NOT NULL default '0',
+ // Let Views know that our example table joins to the 'node'
+ // base table. This means it will be available when listing
+ // nodes and automatically make its fields appear.
+ //
+ // We also show up for node revisions.
+ $data['node_example']['table']['join'] = array(
+ 'node_revisions' => array(
+ 'left_field' => 'vid',
+ 'field' => 'vid',
+ ),
+ 'node' => array(
+ 'left_field' => 'vid',
+ 'field' => 'vid',
+ ),
+ );
+
+ // quantity
+ $data['node_example']['quantity'] = array(
+ 'title' => t('Quantity'),
+ 'help' => t('Quantity of items.'),
+ 'field' => array(
+ 'handler' => 'views_handler_field_numeric',
+ 'click sortable' => TRUE,
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_numeric',
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ );
+
+ // Color
+ $data['node_example']['color'] = array(
+ 'title' => t('Color'),
+ 'help' => t('Color of item.'),
+
+ 'field' => array(
+ 'handler' => 'views_handler_field',
+ 'click sortable' => TRUE,
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ );
+
+ return $data;
+}
+
+?>
+</pre>
+
+Some notes on usage:
+
+Within Views, click on the Add tab. You have a number of type options here. Normally you would select either 'Node' (if you only want to display information on current nodes) or 'Node revision' (if you want to display information on all revisions of the nodes)
+
+With this configuration you always pull out of the database, data for every single node, whether or not it has color and quantity information. To display information on just those nodes that have color and quantity information you can use a filter so that only nodes which don't have a NULL color or a NULL quantity are displayed.
+
+<h3>Type/relationship extension</h3>
+
+When your tables have first class data, you will often need to have own View types and View relationships defined. With the current node_example table this isn't required although I try to justify it below on an efficiency basis. See [[http://groups.drupal.org/node/17236#comment-58980|this discussion]] as to why it isn't justified.
+
+Pulling data out of the database for every node when you only want data for the new Example node type is inefficient. To reduce the initial data extraction to just that relating to the new Example nodes requires that you make the node_example table the base table. This can be done by adding the following code into the node_example.views.inc file just before the 'return $data;'
+
+<pre>
+<?php
+
+// **** Begin optional extra for type and relationships ****
+
+ // Use node_example as a new base table
+ // by creating a new views type called 'Node example'
+ // This allows it to be selected as the 'view type'
+ // when you initially add a new view.
+ $data['node_example']['table']['base'] = array(
+ 'field' => 'vid',
+ 'title' => t('Node example'),
+ 'help' => t("Node example type with color and quantity information."),
+ 'weight' => -9,
+ );
+
+ // When using the new 'Node example' type you need to use relationships
+ // to access fields in other tables.
+
+ // Relationship to the 'Node revision' table
+ $data['node_example']['vid'] = array(
+ 'title' => t('Node revision'),
+ 'help' => t('The particular node revision the color and quantity is attached to'),
+ 'relationship' => array(
+ 'label' => t('Node revision'),
+ 'base' => 'node_revisions',
+ 'base field' => 'vid',
+ // This allows us to not show this relationship if the base is already
+ // node_revisions so users won't create circular relationships.
+ 'skip base' => array('node', 'node_revisions'),
+ ),
+ );
+
+ // Relationship to the 'Node' table
+ $data['node_example']['nid'] = array(
+ 'title' => t('Node'),
+ 'help' => t('The particular node the color and quantity is attached to'),
+ 'relationship' => array(
+ 'label' => t('Node'),
+ 'base' => 'node',
+ 'base field' => 'nid',
+ // This allows us to not show this relationship if the base is already
+ // node so users won't create circular relationships.
+ 'skip base' => array('node', 'node_revisions'),
+ ),
+ );
+
+// **** End optional extra for type and relationships ****
+
+?>
+</pre>
+
+The above code adds a new 'Node example' to the view types that can be selected within the Add tab window of views. Selecting this sets the node_example table to be the base table.
+
+If you select 'Node example' as view type, when you initially go into the edit window of views you will find the only fields available are the color and quantity fields. To get fields from other tables you need to add a relationship. Relationships may be found at the top in the same column as the fields.
+ // Here you just return a string of your content you want.
+ if ($render = parent::render($empty)) {
+ $element = array(
+ '#type' => 'fieldset',
+ '#title' => t('Title'),
+ '#value' => $render,
+ );
+ $output = theme('fieldset', $element);
+ return $output;
+ }
+ }
+}
+</pre>
+
+As on every handler you can add options so you can configure the behavior. If the area isn't shown yet in the views interface, please clear the cache :)
+ * The type of sanitization needed. If not provided, check_plain() is used.
+ */
+function sanitize_value($value, $type = NULL) {
+ switch ($type) {
+ case 'xss':
+ $value = filter_xss($value);
+ break;
+ case 'url':
+ $value = check_url($value);
+ break;
+ default:
+ $value = check_plain($value);
+ break;
+ }
+ return $value;
+}
+</pre>
+These functions are meant to be used in the render() functions of field handlers,
+for fetching data (usually by alias) from the $values object, and for sanitizing values.
+
+The abstraction of fetching data from rendering data is important because
+different query backends have different ways of storing data in $values, and the field alias
+is a SQL specific thing. So instead of overriding the whole render() function and copying
+all of the logic there (as well as having to constantly keep up with upstream Views changes),
+the backend can just override get_values(), which is significantly less code.
+
+Of course, different ways of fetching and displaying data might require different
+ways of sanitizing it, hence the usage of the sanitize_value() function.
+
+Examples of converting render() field handler implementations:
+<pre>
+// This
+$value = $values->{$this->field_alias};
+// Becomes this
+$value = $this->get_value($values);
+
+// And this
+$format = $values->{$this->aliases['format']};
+// Becomes this
+$format = $this->get_values($values, 'format');
+
+// Instead of this:
+return check_plain($value);
+// We write:
+return $this->sanitize_value($value);
+
+// Since sanitize_value() supports different sanitization functions, this:
+return filter_xss($value);
+// Can become:
+return $this->sanitize_value($value, 'xss');
+</pre>
+
+
+<h3>Changed views_get_page_view</h3>
+In contrast to 6.x views_get_page_view now does stores the current view, not the current page display.
+
+<h3>Removed views-view-row-node</h3>
+Due to changes in comment.module there is no extra views-view-row-node template needed to display the comments. If you do some custom stuff there you should now be able to do everything in your node.tpl.php.
+
+<h3>Entity type Key on Base tables</h3>
+During the development of the drupal7 version of views the entity type associated with a table got added to $data['name']['table']['base']['entity type']. It should be moved to $data['name']['table']['entity type'].
+Attachment displays are 'attached' to another display in the same view. When the display is visited, the attached display will also be rendered and may be placed before, after or both before and after the original display. Attachment displays are often useful for displaying an argument summary view along with a page display that accepts arguments. This can be used to provide a kind of glossary.
+Block displays will show up on your blocks administration page. Once a block display is created and saved, it can be enabled and positioned in your theme by visiting <strong>administer >> site building >> blocks</strong> and selecting it from the list.
+
+Blocks <strong>do not</strong> accept arguments from any source; the only way to get arguments to a block is to provide defaults to it, possibly via the PHP Code default setting.
+
+<ul>
+<li>Edit the argument in question; you may want to override this argument if you have multiple displays using it.</li>
+<li>Change the "Action to take if argument is not present" to "Provide default argument". This will bring up a new box called "Provide default argument options".</li>
+<li>The most common default argument type used for blocks is Node from URL, where it attempts to determine if the URL refers to a node, for example if visiting 'node/1' or 'node/1/edit'. User ID from URL is also very common.</li>
+<li>If you change the default argument type to 'PHP Code' (note: You must have permission to use PHP code on your site) you can enter PHP to define the argument needed. Simply return the argument.</li>
+<li>If you are using a <strong>more link</strong> with a block, you must have a page display for that more link to attach to. The more link will not print if there is no place (no display) for it to link to.</li>
+The default display is primarily a display to store settings, and isn't actually used anywhere within the Views system. It is possible for external programs to use the default display, but if they do they will (hopefully) tell you which display they will be working with. The default display is also a convenient display to use to embed into your site using PHP snippets; this is useful, for example, in node content, but this is something that should generally only be done by administrators.
+
+In general, you probably want to add either a <a href="topic:views/display-page">page display</a> or a <a href="topic:views/display-block">block display</a>.
+Page displays have a <a href="topic:views/path">path</a> and an optional <a href="topic:views/menu">menu</a> component. Page displays will be the primary content for the page, meaning they will be displayed in the main content area when you visit the URL that corresponds to the path.
+
+Page displays take their arguments from the URL. You can embed arguments into the URL using %; in previous versions of Views, this was '$arg'. For example, 'node/%/foo' will accept URLs such as 'node/1/foo'.
+
+Please remember that using a % placeholder makes the argument required. If you wish to have an optional argument, simply omit the % from the path. I.e. using "page/%" as the path requires an argument and visiting 'http://www.example.com/page' will not trigger the view.
+
+If you intend to embed a view manually into another view, it is recommended that the page display not be used for embedding. Select a different display type to embed.
+To figure out the id of a display, hover your mouse over the tab to select that display. Everything after the '#views-tab-' is the id of that display. This ID is guaranteed never to change unless you delete the display and create a new one.
+The Emtpy Text content will be displayed when you choose the option <em>Display empty text</em> under the <strong>Arguments</strong> labelled <em>Action to take if argument is not present</em>.
+
+By default you can choose one or more text areas.
+<p>In this example you will create a page that displays a list of the content authored by the current logged-in user. This will demonstrate using Views <em>filters</em> and <em>relationships</em> to dynamically filter the view's contents at display time.</p>
+
+<p>For this example, we are assuming you have a content type "Blog Post".</p>
+
+<h3>Creating the View</h3>
+<p>The first step is creating a view for our content list page. Because the page will show the titles of content, this view is considered a "Content" type. Go to <a target="_blank" href="base_url:admin/structure/views/add">add new view</a>, enter the following properties, and click <strong>Next</strong>:</p>
+
+<dl>
+ <dt>View name</dt>
+ <dd>content_by_current_user</dd>
+ <dt>Description</dt>
+ <dd>List of content authored by the current user.</dd>
+</dl>
+
+<p>Choose <strong>Show</strong> <em>Content</em> <strong>of type</strong> <em>Blog Post</em>. You can choose any way you wish to sort the content.</p>
+
+<h3>Creating the page</h3>
+<p>Tick the box next to <strong>Create a page</strong>. Enter a page title and a path. For our purposes here, the default settings for the rest of this page are sufficient.</p>
+
+<p>Click on <strong>Continue & edit</strong>.</p>
+
+<h3>Creating the relationship</h3>
+<p>In order to have access to the author of the content, it is important to create a relationship between the current content type, and users.</p>
+
+<p>Under <strong>Advanced</strong> in the right culumn, select <strong>add</strong> next to <strong>Relationships</strong>.</p>
+<p>Select <em>Content: Author</em> and click on <strong>Add and configure relationships</strong>. Leave the settings as they are and click on <strong>Apply (all displays)</strong>.</p>
+
+<p>You now have access to the user data related to the content you are viewing.</p>
+
+<h3>Filtering the view</h3>
+<p>Now you need to filter the view to display only content authored by the current user. This data is now available for the content because you have created the relationship in the step above.</p>
+
+<p>Next to <strong>Filter criteria</strong> click on <strong>add</strong> to add a new filter to your view.</p>
+
+<p>Filter the list of fields by selecting <em>User</em> next to <strong>Filter</strong> at the top. You now have more fields than before due to the relationship you created.</p>
+
+<p>Select <em>User: Current</em> from the list and click on <strong>Add and configure filter criteria</strong>.</p>
+
+<p>Since this field is only visible due to the relationship you created, <em>author</em> will already be selected under <strong>Relationship</strong>. This shows that the relationship you created is being used for the filter field.</p>
+<p>Select <em>Yes</em> under <strong>Is the logged in user</strong>, and click on <strong>Apply (all displays)</strong>.</p>
+
+<p>If you have authored content of the type <em>Blog Post</em>, you should now see a list of those posts under the preview section at the bottom.</p>
+
+<h3>Saving & testing the view</h3>
+<p>Click on <strong>Save</strong> to save the view.</p>
+<p>You can test the view by going to the path you entered in the first part of this example.</p>
+<p>In this example you will create a views block that displays images in a slideshow using thumbnails of the images as a pager underneath the slideshow. This will demonstrate using <em>Views Slideshow </em>and <em>Image Styles</em> to display images.</p>
+
+<p>For this example, we are going to display a single image from each content item of the type "Photos", which we assume you have already set up with an image field. We are also assuming that <em>Views Slideshow</em> and at least one plugin is installed and activated.</p>
+
+<h3>Creating the image styles</h3>
+
+<p>The first step is creating the right image styles to display the images from the node. We will create one for the slideshow image, and one for the pagers. Go to <a target="_blank" href="base_url:admin/structure/views/add">Image Styles</a> and create the following two styles:</p>
+
+<dl>
+ <dt>Style name</dt>
+ <dd>slideshow_image</dd>
+ <dt>Effects</dt>
+ <dd>Scale and crop: 600px wide, 400px high</dd>
+</dl>
+<dl>
+ <dt>Style name</dt>
+ <dd>slideshow_thumbnail</dd>
+ <dt>Effects</dt>
+ <dd>Scale and crop: 30px wide, 20px high</dd>
+</dl>
+
+<h3>Creating the View and block</h3>
+
+<p>The next step is creating a view for the slideshow. Because the block will show the images in content, this view is considered a "Content" view. Go to <a target="_blank" href="base_url:admin/structure/views/add">add new view</a>, enter the following properties, and click <strong>Next</strong>:</p>
+<dl>
+ <dt>View name</dt>
+ <dd>Photo Slideshow</dd>
+ <dt>Description</dt>
+ <dd>Slideshow of images from Photos.</dd>
+</dl>
+
+<p>Choose <strong>Show</strong> <em>Content</em> <strong>of type</strong> <em>Photos</em>. You can choose any way you wish to sort the content.</p>
+<p>Untick the box next to <strong>Create a page</strong> and tick the box next to <strong>Create a block</strong>. Enter a block title and choose Slideshow from the <strong>Display format</strong> select box. Select <em>fields</em> from the other select box. Leave the remaining settings as they are.</p>
+<p>Click on <strong>Continue & edit</strong>.</p>
+
+<h3>Editing the view settings</h3>
+
+<p>Turn off the pager by clicking on <strong>Display a specified number of items</strong> in the middle column and selecting <strong>Display all items</strong> in the next screen, and applying the settings.</p>
+<p>Enter a Block name by clicking on <strong>None</strong> at the top of the middle column.</p>
+<p>Next, remove the <em>Content: Title</em> field from the fields list in the left column by blicking on <strong>rearrage</strong> under the arrow.</p>
+<p>Next we have to add the thumbnail image field. Click on <strong>Add</strong> under the fields section and select your image field from the list. In the next screen, turn off the label, select <em>Exclude from display</em> and select <em>slideshow_thumbnail</em> from the Image Style select box. Under MORE, enter <em>Thumbnail</em> under Administrative Title.</p>
+<p>Click on <strong>Apply (all displays)</strong>.</p>
+<p>Now we have to add the image field to display in the slideshow. Clcik on <strong>Add</strong> under the fields section and select your image field from the list. In the next screen, turn off the label and select <em>slideshow_image</em> from the Image Style select box. Under MORE, enter <em>Display Image</em> under Administrative Title.</p>
+<p>Click on <strong>Apply (all displays)</strong>.</p>
+
+<h3>Editing the slideshow settings</h3>
+
+<p>Click on <strong>Settings</strong> next to Format: Slideshow in the first column. In the screen that opens we can choose the options for our slideshow.</p>
+<p>For the purpose of this example, we will only add the thumbnails as a pager, and leave the remaining slideshow settings as they are. Select the tick box next to <em>Pager</em> under Bottom Widgets. Select <em>Fields</em> from the Pager Type select box. Select the tick box next to <em>Thumbnail</em>.</p>
+<p>Click on <strong>Apply (all displays)</strong>.</p>
+
+<h3>Saving & testing the view</h3>
+<p>Click on <strong>Save</strong> to save the view.</p>
+<p>You can test the view by adding the block you have created to your theme.</p>