Right now the header and footer just go through ordinary filters. Sure you can put PHP there, but one thing I've learned is that if you're using Views as part of your module and you want to distribute it, having PHP embedded in the view is bad. In fact, embedding PHP anywhere has turned out to not be a great long term solution. Therefore these desperately need to be pluggable so that we can do more things with the header and footer area. Especially if they can get some knowledge of the arguments so we can do more things there.

This is part of the "views 3.x roadmap".

I think there has to be some discussion where and what to implement there exactly: which features etc.

CommentFileSizeAuthor
#82 views-510284-areas.patch30.36 KBdagmar
#81 views-510284-areas.patch27.84 KBdagmar
#81 multiple-areas-screenshot.png65.78 KBdagmar
#79 views-510284-pluggable-areas.patch25.17 KBdawehner
#77 views_add_links.zip3.43 KBjoachim
#76 views_node_texts.tar_.gz1.6 KBdawehner
#75 views-510284-pluggable-areas.patch25.16 KBdawehner
#73 views-510284-pluggable-areas.patch25.92 KBdagmar
#71 views-510284-pluggable-areas.patch25.62 KBdagmar
#68 views-510284-pluggable-areas.patch26.41 KBdagmar
#60 views-510284-pluggable-areas.patch26.27 KBdagmar
#60 pageareas-6-x-1.x.tar_.gz1.82 KBdagmar
#59 views-510284-pluggable-areas.patch25.92 KBdagmar
#58 views-510284-pluggable-areas.patch25.51 KBdagmar
#57 views-510284-pluggable-areas.patch23.74 KBdawehner
#56 views-510284-pluggable-areas.patch24.62 KBdagmar
#51 views_pluggable_areas.patch24.29 KBdagmar
#41 views-pluggable-area-t_7.patch25.46 KBdagmar
#39 views-pluggable-area-t_6.patch25.41 KBdagmar
#38 views-pluggable-area-t_5.patch25.19 KBdagmar
#33 views-pluggable-area-t_4.patch22.89 KBdagmar
#29 views-pluggable-area-t.patch21.33 KBdawehner
#28 views-pluggable-area-t.patch21.33 KBdawehner
#27 views-pluggable-area-t.patch21.39 KBdawehner
#26 views-pluggable-area-translatable.patch22.26 KBdagmar
#24 views-pluggable-area-t.patch20.56 KBdawehner
#23 views-pluggable-area-t.patch20.49 KBdawehner
#22 views-pluggable-area.patch19.6 KBdawehner
#21 views-pluggable-area.patch21.03 KBdawehner
#17 views-pluggable-area.patch21.11 KBdawehner
#14 views-pluggable-area.patch19.71 KBdawehner
#10 views-pluggable-area.patch18.35 KBdawehner
#4 views-pluggable-block.patch10.99 KBdawehner
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

Some thoughts of mine:

  • For this header footer and empty text has to be removed from the displays(the forms and option_defitions), but still (perhaps) called from the displays
  • Use this plugin to replace the code in template_preprocess_views_view
  • Abstract footer / header / empty text into something abstract. Therefore perhaps create something like regions around a view.
  • Keep the current way of theming header and footer. Its good to use by the themers

PS: this are just random thoughts of mine, i have to learn quite a lot how the plugin system works here.

joachim’s picture

> Abstract footer / header / empty text into something abstract. Therefore perhaps create something like regions around a view.
I think that's a bit far perhaps for now. We'd end up reinventing panels if we're not careful.

The feature I'd like to see is a form element that picks a node (like CCK noderef) for the header to output. Add an [edit] link to it on display if the user has edit access.
That would make it easy for non-admins to keep their headers and footers updated.

dawehner’s picture

I think that's a bit far perhaps for now. We'd end up reinventing panels if we're not careful.

Yes thats true. Keep on header and footer. The users can do what they want with the pluggable system :)

If we have pluggable header support your task is definitive quite easy. I think you want to display the node as help, so we could perhaps also integrate advancedhelp/helpinject later.

dawehner’s picture

FileSize
10.99 KB

Thats just a first basic patch, which does not work yet.

joachim’s picture

Is 'block' the best terminology here?

Also, I'm not sure the current slicing will work nicely.
The strings in views_plugin_block_textarea are currently specific to the header -- this class somehow needs to know if it's being put in the header/footer/empty.

I think what we have is:
- three textareas, which not all displays have: empty, header, footer. A page display has all of them, a block has probably just the empty. I'm tempted to call these regions, but it's an overused words and the empty text isn't really a region. There's probably not a need for an OO architecture here -- do we really need to define extra region-type things? Each area defines a name and other useful strings.
- plugins for what actually goes into these areas. Currently we have parent, text, PHP. Later, node.

Random thought: what if we did this with attachments?

dawehner’s picture

Is 'block' the best terminology here?

I just couldn't image a better word, but I'm sure there is one!

Also, I'm not sure the current slicing will work nicely.
The strings in views_plugin_block_textarea are currently specific to the header -- this class somehow needs to know if it's being put in the header/footer/empty.

Ok this could be definitve be done, thats just a very first approach.

plugins for what actually goes into these areas. Currently we have parent, text, PHP. Later, node.

Thats exactly what i wanted to achieve, different areas(thats perhaps a nice word for the name, instead of region or block).

- three textareas, which not all displays have: empty, header, footer. A page display has all of them, a block has probably just the empty. I'm tempted to call these regions, but it's an overused words and the empty text isn't really a region. There's probably not a need for an OO architecture here -- do we really need to define extra region-type things? Each area defines a name and other useful strings.

Thats also what a wanted to use, just a string for the region. If people want more, lets do them in contrib/custom modules.

Random thought: what if we did this with attachments?

Thats perhaps a good idea, but we would need a display type, which does not act as a view. Additional that could be just a little overhead, not sure.

At the end, discussing is good here.

joachim’s picture

Ah -- I've remembered why we shouldn't use attachments.
Same reason I'm not using them to make image galleries.
An attachment is a type of display, and so tries to be a view, and run a query. Making it not run a query involves a silly amount of overriding code.

dawehner’s picture

Ah yes, thats definitive a good reason.

What do you think about naming it "area"?

joachim’s picture

Area works for me :)

dawehner’s picture

Status: Active » Needs review
FileSize
18.35 KB

So here a the first working version, but there has to be a lot of cleanup to be done :)

dagmar’s picture

Status: Needs review » Needs work

Hi dereine:

I have tested your patch. A few comments.

+++ theme/theme.inc
@@ -49,26 +49,34 @@ function template_preprocess_views_view(&$vars) {
+  $header = $view->display_handler->get_area_plugin($view->display_handler->options['header']['type'], 'header');
+  $footer = $view->display_handler->get_area_plugin($view->display_handler->options['footer']['type'], 'footer');
...
-    if (!$view->display_handler->get_option('header_empty')) {

This is not valid if options are saved into default settings.

You should use get_option() in order to get the real value of the settings.

If you use get_option(), the code should be:

  $header_options = $view->display_handler->get_option('header');
  $footer_options = $view->display_handler->get_option('footer');
  $header = $view->display_handler->get_area_plugin($header_options['type'], 'header');
  $footer = $view->display_handler->get_area_plugin($footer_options['type'], 'footer');
  //same for empty text

Typo:

+++ theme/theme.inc
@@ -49,26 +49,34 @@ function template_preprocess_views_view(&$vars) {
+    $vars['empty']    = $empty->render();
+    $vars['header'] = $header->render(TRUE);
+    $vars['footer'] = $footer->render(TRUE);

And for the PHP Plugin:

+++ includes/plugins.inc
@@ -267,6 +267,34 @@ function views_views_plugins() {
+      'php' => array(
+        'title' => t('PHP'),
+        'help' => t('PHP Code which is evaled'),
+        'handler' => 'views_plugin_area_php',
+        'help topic' => 'area-php',
+        'uses options' => TRUE,

Well, this is important. Since Drupal check PHP filter access trough Input Formats, this plugin must provide a method to restrict users to create PHP Areas.

Nice start :)

Changing Status.

This review is powered by Dreditor.

dawehner’s picture

Thanks for the first review, there is quite some work todo.

Additional TODO:

  • Convert header/footer/empty of existing views to the new pluggable system
  • Documentation

  $header_options = $view->display_handler->get_option('header');
  $footer_options = $view->display_handler->get_option('footer');
  $header = $view->display_handler->get_area_plugin($header_options['type'], 'header');
  $footer = $view->display_handler->get_area_plugin($footer_options['type'], 'footer')

is even better to read.

+    $vars['empty']    = $empty->render();

Do you mean the space here?

Well, this is important. Since Drupal check PHP filter access trough Input Formats, this plugin must provide a method to restrict users to create PHP Areas.

Yes definitive, but also the import formats. I can guess a strange situation:
- Admin creates a view with php header.
- "Moderator" edits the view to change the title of a field.(He does not have php rights).

What should happen? What happens at the moment?

PS: I have some time on the train to the con, let's see whether I can do something :)

dagmar’s picture

Hi dereine:

Yes definitive, but also the import formats. I can guess a strange situation:
- Admin creates a view with php header.
- "Moderator" edits the view to change the title of a field.(He does not have php rights).
What should happen? What happens at the moment?

Right now, when a user try to edit the header of a view that uses PHP format, views displays Header: Unknown/missing format

When the view is saved, the Input format change, because, user cannot select PHP again.

In my opinion, I think that views should display something like "You cannot edit this area".

Another option can be Allow user to edit the Top and Bottom of an area with they input formats allowed. But, this can be confussing.

Do you mean the space here?

Yes.

dawehner’s picture

FileSize
19.71 KB

So here is a new patch, which solves the first two things and some minor documentation etc. things.

I will do the access thing tomorrow, but currently is hard to find a permission for it. Drupal has none, beside the php input format.
I think i will use this to check the access.

Just keeping it to needs work, because there is some stuff which has to be done.

dagmar’s picture

Hi dereine:

+++ plugins/views_plugin_area_text.inc
@@ -0,0 +1,51 @@
+  function render($empty = FALSE) {
+    if (!$empty || $this->options['empty']) {
+      return check_markup($this->options['content'], $this->options['format'], FALSE);
+    }
+    else {
+      return '';
+    }
+  }

I'm not sure if this is the better way to do this.

Views uses another method to render a textarea. Maybe this plugin should use the same method.

See views_plugin_display::render_textarea()

And, What do you think about?:

... Especially if they can get some knowledge of the arguments so we can do more things there.

This plugin can access to arguments if we make a call to pre_render() or query(). The question is, Where is the better place to put this hook?

This review is powered by Dreditor.

dawehner’s picture

It was definitive to late yesterday eving ;)

Views uses another method to render a textarea. Maybe this plugin should use the same method.

See views_plugin_display::render_textarea()

I think this function could be copied to views_plugin_area_text and take parameter $value/$content and the format.
Then this function could be called from area_text->render

<?php
  /**
   * Render a text area, using the proper format.
   */
  function render_textarea($value, $format) {
    static $formats = array();

    // Check to make sure the filter format exists; if not, we don't
    // display anything.
    $format = filter_resolve_format(format);

    if (!array_key_exists($format, $formats)) {
      $formats[$format] = db_result(db_query("SELECT name FROM {filter_formats} WHERE format = %d", $format));
    }

    if (!$formats[$format]) {
      return;
    }

    if ($value) {
      return check_markup($value, $format, FALSE);
    }
  }
?>
... Especially if they can get some knowledge of the arguments so we can do more things there.

This is a quote from merlinofchaos in his blog. Currently if a header wants to know about arguments he has to use arg() or views_get_current_view.
But with the pluggable system he has the full access to $display and $views. So it possible to do quite a lot of stuff :)

dawehner’s picture

Status: Needs work » Needs review
FileSize
21.11 KB

So here is a new version of the patch

dagmar’s picture

Status: Needs review » Needs work
+++ plugins/views_plugin_display.inc
@@ -1000,46 +995,126 @@ class views_plugin_display extends views_plugin {
-        $form['#title'] .= t('Empty text');
+        $form['#title'] .= t('Empty');

This change requires a documentation update.

+++ plugins/views_plugin_display.inc
@@ -1000,46 +995,126 @@ class views_plugin_display extends views_plugin {
+          '#options' => views_fetch_plugin_names('area'),

Maybe we can sort this to make appear "None" at the top of the list

+++ plugins/views_plugin_display.inc
@@ -776,31 +775,27 @@ class views_plugin_display extends views_plugin {
     foreach (array('header' => t('Header'), 'footer' => t('Footer'), 'empty' => t('Empty text')) as $type => $name) {

use t('Empty text') here is correct?

Access control to PHP plugin is missing yet, the render_textarea() function seems to be working fine.

I'm on crack. Are you, too?

superbaloo’s picture

Status: Needs work » Needs review
+++ plugins/views_plugin_area.inc
@@ -0,0 +1,39 @@
+  function options_form(&$form, &$form_state) { }

Shouldn't it call the parent ? like
return parent::options_form($form, $form_state);

?

+++ plugins/views_plugin_area_php.inc
@@ -0,0 +1,43 @@
+  function options_form(&$form, &$form_state) {
+    dsm(filter_formats());

Same here, shouldn't you call the parent one ?

+++ plugins/views_plugin_area_php.inc
@@ -0,0 +1,43 @@
+    if (!$empty || $this->options['empty']) {

if (!$empty || (bool)$this->options['empty']) {

+++ plugins/views_plugin_area_text.inc
@@ -0,0 +1,74 @@
+    $form['format'] = filter_form($this->options['format'], NULL, array('format'));

you only need filter_form($this->options['format']); others are default :)

+++ plugins/views_plugin_area_text.inc
@@ -0,0 +1,74 @@
+    if (!$empty || $this->options['empty']) {

+ if (!$empty || (bool) $this->options['empty']) {

+++ plugins/views_plugin_display.inc
@@ -520,6 +503,22 @@ class views_plugin_display extends views_plugin {
+      $name = $area['type'];

if (is_array($area)) {

no ?

This review is powered by Dreditor.

superbaloo’s picture

Status: Needs review » Needs work
dawehner’s picture

Status: Needs work » Needs review
FileSize
21.03 KB

This change requires a documentation update.

I think Empty text is a good string to use. That was just replacing without thinking.

Maybe we can sort this to make appear "None" at the top of the list

I thought that to, but wasn't sure how to do it the best way.

Access control to PHP plugin is missing yet, the render_textarea() function seems to be working fine.

sadly i know, there is nothing in core which really fits in there, for me. Additional if there is the php input format, its duplicate to have an extra plugin for this.

Shouldn't it call the parent ? like
return parent::options_form($form, $form_state);

I just removed the method, so the parent class handles it.

you only need filter_form($this->options['format']); others are default :)

Thanks!.

if (is_array($area)) {

no ?

If cache plugin handles it good, i guess access plugin can use nearly the same code.

Here is an update of the patch.

If someone uses git, here is my clone of views http://github.com/dereine/drupal-views/tree/pluggable-area

dawehner’s picture

FileSize
19.6 KB

Here is new version:
- some code cleanup
- remove php area plugin. I think its not needed, and leads to eval behavior of the user :)

dawehner’s picture

FileSize
20.49 KB

so here is a patch which allows to be header and footer translatable

BUG: The user cannot know, which fields is for which language

dawehner’s picture

FileSize
20.56 KB

next version:
- fixed php bug
- fixed above bug

dagmar’s picture

Status: Needs review » Needs work
+++ plugins/views_plugin_area_text.inc
@@ -0,0 +1,103 @@
+    if (module_exists('locale')) {
+      $langs = locale_language_list();
+      foreach ($langs as $lang_code => $lang_name) {
+        $form['content_' . $lang_code] = array(
+          '#type' => 'textarea',
+          '#default_value' => $this->options['content'],
+          '#rows' => 6,
+          '#description' => t('Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional. Language: %language',
+            array('%language' => $lang_name)),
+        );
+      }
+    }
+    else {
+      $form['content'] = array(
+        '#type' => 'textarea',
+        '#default_value' => $this->options['content'],
+        '#rows' => 6,
+        '#description' => t('Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional.'),
+      );
+    }

We can wrap all languages using:

    if (module_exists('locale')) {
      $langs = locale_language_list();
      foreach ($langs as $lang_code => $lang_name) {
        $form['content_title_' . $lang_code] = array(
          '#type' => 'fieldset',
          '#title' => t('Language @lang', array('@lang' => $lang_name)),
          '#collapsible' => TRUE,
          '#collapsed' => $lang_code != 'en',
        );
        
        $form['content_title_' . $lang_code]['content_' . $lang_code] = array(
          '#type' => 'textarea',
          '#default_value' => $this->options['content_' . $lang_code],
          '#rows' => 6,
          '#description' => t('Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional. Language: %language',
            array('%language' => $lang_name)),
        );
      }
    }
+++ plugins/views_plugin_area_text.inc
@@ -0,0 +1,103 @@
+  function options_submit(&$form, &$form_state) {
+    $form_state['values'][$this->type .'_options']['format'] = $form_state['values']['format'];
+    parent::options_submit($form, $form_state);
+  }

Using fieldsets this has to be changed.

dagmar’s picture

This patch doens't save the settings. I don't know why. Please note "content_en" in order to work with and without locale module.

dawehner’s picture

Status: Needs work » Needs review
FileSize
21.39 KB

Now saving the text works.

dawehner’s picture

FileSize
21.33 KB

removed dsm()

dawehner’s picture

FileSize
21.33 KB

Saving of disabled locale module works now.

joachim’s picture

I really need to find time to try this :/

In the meantime, thought of another use case :)
A lot of sites I do show a particular content type as a view, with edit links for admins. The actual node pages are not used, so for most users the list of nodes IS the content.
A nice touch here would be an automatically generated list of links at the top of the view 'Add another TYPE' for each type that the view filters on.
Would make a nice header plugin :)

BTW, does this patch allow multiple plugins to be put into one area?

dagmar’s picture

Status: Needs review » Needs work

This plugin is not compatible with previous values of headers/empty texts/footers for views.

Some ideas to consider (pseudo code).

when a view is loaded:

If $header is not empty {
   Set content_en = $header
}

foreach languages availables  {
  if lang_code != 'en' {
    $options['content_' . $lang_code] = t($header, array, $lang_code)
  }
}

(same for empty texts and footers)

when a view is saved:

Set header, empty texts and footers to null.
dagmar’s picture

@dereine: What do you think about #543118: Add more input options to TITLE field it is an interesting feature, however this can be problematic when an argument try to rewrite this title.

dagmar’s picture

This patch covers:

Different descriptions for header, footer, and empty text.

An intent to get the previous values for header, footer, and empty text and use as default values for areas.

This patch still needs work.

dawehner’s picture

+++ plugins/views_plugin_area_text.inc	17 Sep 2009 14:02:06 -0000
@@ -0,0 +1,138 @@
+
+    switch ($this->type) {
+      case 'header':
+        $description = t('Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional. ');
+      break;
+      case 'empty':
+        $description = t('Text to display if the view has no results. Optional. ');
+      break;
+      case 'footer':
+        $description = t('Text to display at the bottom of the view. May contain an explanation or links or whatever you like. Optional. ');          
+        break;
+    }     

Why not provide default case. Perhaps a display needs area foo.

I'm on crack. Are you, too?

Perhaps there could be a updates script which converts existing views.

dagmar’s picture

Why not provide default case. Perhaps a display needs area foo:

mmm, I think is not necesary in this patch. If another module needs it, it allways can extend views_plugin_area_text and overwrite options_form()

Perhaps there could be a updates script which converts existing views.

Yes it can be a valid option. However, header, footer, and empty texts are serialized values. This update may be complex. I don't know...

dawehner’s picture

i would just load the view, and save it afterwards.

dagmar’s picture

Another bug in views export:

$handler->override_option('header', array(
  'type' => 'text',
  'empty' => 0,
  'content_title_en' => array(
    'content_en' => 'december',
  ),
  'content_title_es' => array(
    'content_es' => 'diciembre',
  ),
  'content_en' => 'december',
  'content_es' => 'diciembre',
  'format' => '2',
));

Why it is exported twice?

dagmar’s picture

Status: Needs work » Needs review
FileSize
25.19 KB

Ufff, This patch was more difficult to code.

This patch covers:

#37: Duplicated export. Solved
#36: Update script. Not tested

I didn't test the update script, only check if dsm($view) displayed the expected object structure.

dagmar’s picture

Sorry, I forgot some lines in the update script.

We have to use t() or st() in the update script?

dawehner’s picture

Afaik you have to use

$t = get_t();

And then $t('string')

dagmar’s picture

Thanks dereine.

I'm attaching a patch that I have tested. The update script converts old headers, footers and empty text into new text area.

It seems to be working. However this script is a critical task, we have to do a lot of tests before mark this issue as RTBC.

From #2:

The feature I'd like to see is a form element that picks a node (like CCK noderef) for the header to output. Add an [edit] link to it on display if the user has edit access.
That would make it easy for non-admins to keep their headers and footers updated.

This is a good idea. Maybe we can add a new check box to "Provide a link to edit this area" What do you think Daniel?

dawehner’s picture

Yes a additional link to the hover links would be perfect, also for the footer and the empty text.

I will review your changes this evening.

dagmar’s picture

I sent an email to Jonah Ellison, he is the author of http://drupal.org/project/views_header_footer maybe we can design a similar solution for views 3.

dagmar’s picture

From Views 3 Roadmap:

... Especially if they can get some knowledge of the arguments so we can do more things there.

Maybe we can insert as [tokens] the values of the arguments into text areas. Obviously we cannot use the same system that views arguments use for titles.

I'm thinking in something like:

[1|This texts will be displayed if argument 1 is present, the value form argument 1 is %1]

This allow us embed parts of conditional text into areas base on arguments value. But it is only an idea.

dawehner’s picture

+++ views.install	22 Sep 2009 13:42:57 -0000
@@ -296,3 +296,53 @@ function views_update_6007() {
+      }
+    }
+    $view->save();

Perhaps rebuild views cache, not sure whether its needed.

But the rest works well, i convered a installation with 50views for test.

drupov’s picture

subscribing

dagmar’s picture

Yes a additional link to the hover links would be perfect, also for the footer and the empty text.

This links present several problems.

First, a non expert user will want change only the text. Without know anything about views. If we provide a link, users will see all the administrative interface. Usability -10

For other side, admin probably never will enable this option if it means give full access to the view admin system.

For these reasons, I'm thinking in another way to allow users edit areas (header, footer, empty texts).

What do you think about create a new plugin called "Editable area"?, it just be a new kind of header, footer or empty text. But it will can be edited "in situ", if an user has edit access.

This, obviously, is not easy to code, specially because FAPI doesn't work well with method of classes (we cannot use a method of a class to process the submit of a form), and create a new menu link for views is not a reasonable idea.

Opinions?

dawehner’s picture

I suggest you once, to disable js and edit the header. The single form is displayed there. What if you just have this edit link exact to this form, and also a destination to the page attached.

Then the user will never see the full admin screen. Perhaps we can make it also not possible to access it.

dagmar’s picture

Yes, I thought about that too. However, if user don't save the whole view, the change will not be storage. And this, I think, only can be done through views admin screen.

merlinofchaos’s picture

Would it be possible to do this without using an update? Possibly something that checks where the old data is and fakes it with some assumptions if there is no style selected? I think that should not be too hard.

Also, similar to my comments in the pluggable exposed form patch, we need to use the option_definition pattern, not the option_defaults pattern.

dagmar’s picture

FileSize
24.29 KB

3 weeks later... :)

I have relloled this patch, its works without hook_update_N (at least in my tests worked fine) and option_definition was changed for options_defaults.

Since we cannot provide a solid plugin that support translatable full html texts (in fact this is not possible right now) I move the original text_area from #41 into a new plugin installable from i18n. http://drupal.org/node/641812

So, this patch provide pluggable Headers, Footers and Empty texts but if users can translate a text with harmful tags like "div" or "script" they should use i18n area plugin.

dww’s picture

+100 ;) We desperately need a real solution for this on drupal.org over at #366542: Replace hook_help() hacks with a cleaner solution for the dynamic headers on issue views -- which is a blocker for both the d.o redesign and an official 6.x-1.0 release of project_issue. I'll try to review this after Thanksgiving, my hands are totally full for the next week or so with more urgent deadlines...

dagmar’s picture

Status: Needs review » Needs work

We have to change get_plugin_area() to get_plugin() for compatibility with: #503452: Retool exports to drill down properly

dagmar’s picture

Status: Needs work » Needs review

From IRC:

dagmar1: merlinofchaos: hi, i'm trying to do a reroll of Pluggable headers/footers... but with the Retool export patch get_plugin doesn't accept anymore a extra parameter to set the type of area. I think that area plugins are the unique plugins that can be used several times with different uses 
merlinofchaos: That makes sense.
merlinofchaos: get_area_plugin() can be separate for that reason.

So, we don't need to make it compatible with #503452: Retool exports to drill down properly

Changing status

merlinofchaos’s picture

Status: Needs review » Needs work
+  function init(&$view, &$display, &$type) {
+    parent::init($view, $display);
+    $this->options = array();
+    $this->type = $type;
+
+    if (is_object($display->handler)) {
+      // Note: The below is read only.
+      $options = $display->handler->get_option($this->type);
+      if (!is_array($options)) {
+        if (!empty($options)) {
+          $options = array (
+            'content' => $display->handler->get_option($this->type),
+            'format' => $display->handler->get_option($this->type . '_format'),
+            'empty' => $display->handler->get_option($this->type . '_empty'),
+          );
+          $this->options = $options;
+        }
+      }
+
+      $this->unpack_options($this->options, $options);
+    }
+  }

Setting $this->options to an array here will destroy any defaults that were applied during the construct() phase. This is a nono.

How does this get its options if they've moved into the new location?

With pluggable pagers, there's a bit of code in display init that will move options from the older location to the newer location. We can use that to move options around and still preserve older exports.

Options should then just be the simple $this->['format'] etc.

dagmar’s picture

Title: Header/footer/empty text pluggable » Header/footer/empty text and more areas pluggable
Status: Needs work » Needs review
FileSize
24.62 KB

Well, after ten hours of coding - really ten hours :( - I have very good news.

First to all, this patch provides pluggable Header, Footer and Empty texts compatible with the last Retool of export system.

One thing that I ever want to do with views was create a views with a custom header, and allows users modify the header, but protecting my custom header.

This of course, was not possible, because theres one header, one footer and one empty text.

So, I did some research and found a way to isolate the "areas" in plugins, now, plugins can define their own areas, Let say a page with 3 header with different level access, why not?

Of course have to be done using a custom plugin display, but views now allows plugins to do that.

To get new areas plugins only have to:

1) Overwrite display_areas()


  function display_areas($area_options = FALSE) {
    if ($area_options) {
      return array(
        'restricted_header_options' => t('Restricted Header options'),
        'header_options' => t('Header options'),
        'footer_options' => t('Footer options'), 
        'empty_options' => t('Empty text options'),
      );
    }
    else {
      return array(
        'restricted_header' => t('Restricted Header'),
        'header' => t('Header'),
        'footer' => t('Footer'), 
        'empty' => t('Empty text'),
      );
    }
  }

2) Define a new kind of area that override the access() function for this area. Text area by default are editable by everyone with edit access to the views.

3) Create a new template for the display plugin to render this new area

Also, I had to do some changes into views_plugin_display::get_plugin() function. This was necessary because 'areas' are the only plugins that have more than one instance of the same kind of plugin.

I.e., header is an 'area' plugin, but 'footer' and 'empty' are too.

So, we cannot use the 'name' of the option to get the plugin, 'pager' works fine because there is only one pager, but with areas this is not possible.

To help to test this patch:

1) Create a view using an un-patched version of views
2) Install the patch and check if area is displayed, in theory this is done like pagers but i didn't test it.
3) Create a new view an see if areas works when views have results and when it doesn't have results (like a node id filter < 1)
4) Export views and import views, to check that they were exported correctly.
5) If anybody (dww I think it can be useful to D.O) can create a prof of concept of a plugin that provides more areas we can test it too.

Uff, here are we go...

dawehner’s picture

Status: Needs review » Needs work
FileSize
23.74 KB

Some stuff:
1) created a view...
2) applied the patch: error : Cannot use string offset as an array in /var/www/development/sites/views.dev/modules/views/plugins/views_plugin_display.inc on line <i>99< appeared.
This is fixed by my version of the patch
I saved now this view, looked at the export, and its away...

3) created the same view again.
Issue: You can't override the settings from default, its always overriden....
empty/no-empty works again perfect....
again: the export had no export of the header/footer stuff....

4.. I can't test this because of 3)

dagmar’s picture

Status: Needs work » Needs review
FileSize
25.51 KB

Thanks dereine. Here is a new patch, I had to modify also export_plugin() to export the area plugins correctly.

1, 2 and 3 are working fine, now, (I think)

dagmar’s picture

Some minor changes, also added the validate_options() call to every area plugin.

Talking with dereine via IRC we agree that add an [edit] link to every area is a good idea. However there is some issues with this feature.

First, we cannot only redirect to admin/build/views/nojs/display/admin/default/header_options because this needs a $form_state['view'] or similar to edit the correct view. If we have severals views in the same page, How we can do that?

Also, what happens if the view is blocked by another user. We have to find a balance between functionality and integrity.

Another idea is to provide an "editable by users" area using a custom module but i don't know if this is reliable.

Ideas?

dagmar’s picture

Well I think this will be one of my last patch before a full review, I swear!

In this patch I have moved the logic of when render each area outside theme.inc, also theme.inc fetch all available areas using display_areas()

Also I'm attaching an small module to test two things.

This module is a prof of concept that provides two kinds of plugins, a "restricted" area plugin which is only editable by users with "administer nodes" permissions. The other is a display plugin that provide a page with two headers and two footers.

Combining the display plugin with the restricted area plugin designers can build a view with a PHP header and allows webmaster to edit the headers of views to put some HTML Filtred text.

So, now the fourth text described in #56 can be performed now.

1) Create a view using an un-patched version of views. Install the patch and check if area is displayed.
2) Create a new view an see if areas works when views have results and when it doesn't have results (like a node id filter < 1)
3) Export views and import views, to check that they were exported correctly.
4) If anybody (dww I think it can be useful to D.O) can create a prof of concept of a plugin that provides more areas we can test it too. (now you can use the attached module)

castawaybcn’s picture

thanks for working on such an essential feature. Any chance this could be backported to 6.x-2.8?

merlinofchaos’s picture

Not to 2.8 since releases are static. It is likely that this one will be ported back to the 2.x line because there is a need for it on drupal.org and it is not too invasive. It is going to be an exception to my "reduce the 2.x new feature list" rule.

castawaybcn’s picture

thanks for your answer Earl.
For those interested I found a "creative solution" through another module in the meantime, check http://drupal.org/project/language_sections which made my day regarding this issue

dagmar’s picture

About the test number one of #62

There are two possible cases.

1) The options are storaged into default display.
2) The options are overridden in another display.

We have to check if it is working properly in both cases because there is a similar issue with pluggable pagers here: #652712: Pager settings are not stored

Bilmar’s picture

subscribing

jantoine’s picture

subscribing.

Thanks to everyone for all the work on this.

dagmar’s picture

Issue tags: +alpha-2 blocker

tagging

dagmar’s picture

Well I have done a full review of the patch.

This were my test:

First test:
I created a few Views with default display, and 3 page displays. Some options overridden, some other by default.
Save changes
Apply the patch
All areas works without problems, even more I unpatch views, and they still work, and patched again and of course, works :)

Second test:
From previous views, I export the view.
Apply the patch.
Import the view, works without problems.

Third test:
With patched view, I created a new view, like test one, every worked as expected.

Fourh test:
I installed the prof of concept attached in #60, when I save the view, without assign settings to new areas and displayed the created page I saw an error:

Cannot call to render() on non-object() ...

The problem was that theme.inc didn't check if plugin was correctly loaded, and it didn't assign a 'none' area for this. I fixed it in the new patch

Fifth test:
Assign some areas to new areas provided by the prof of concept. They didn't storage the Input format. I fixed it in the new patch

Sixth test:
Change the level of access defined in the restricted_area plugin provided by the prof of concept. Level access for edit and views are working fine.

Some small changes:

+   * @param $options
+   *  'edit' or 'view'

By dereine:
$empty = !empty($vars['rows']) ? FALSE : TRUE;

Changed by
$empty = empty($vars['rows']);

So, after two hours of review with dereine via IRC, I think it is ready.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

From my perspective its fine.

merlinofchaos’s picture

+  function option_definition() {
+    $options = parent::option_definition();
+    return $options;
+  }

This is pointless. If you don't have it, you get the same result.

I don't think I like having 'instance' be an option. I thought, at first, this would be to make it invisible to get_plugin() but it doesn't seem to do that. I suppose it's not terrible but it seems like it should maybe be separate.

The newer plugins have had a storage format like this:

array(
  'type' => 'plugin_name',
  'options' => array('options'),
);

I notice this is using a separate $area . '_options' -- I was moving away from that because I find it a little clumsier. I'd prefer this use the above array.

dagmar’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
25.62 KB

Thanks merlinofchaos.

I have modified this patch creating a new class of "instantiable" plugin. views_plugin_areas extends this plugin.

In this patch get_plugin is not modified, instantiables plugins area loaded using get_plugin_instance.

Also, export_plugin is not modified and a new export_plugin_instantiable was created.

Option definition was modified to use a format:

array(
  'type' => 'plugin_name',
  'options' => array('options'),
);

get_plugin_instance will load the correct instance of the plugin.

dawehner’s picture

+++ includes/plugins.inc	24 Dec 2009 16:02:19 -0000
@@ -451,3 +473,30 @@ class views_plugin extends views_object 
+   */
+  function init(&$view, &$display, $options = array()) {
+    $this->instance = $options['instance'];
+    unset($options['instance']);
+
+    $this->view = &$view;
+    $this->display = &$display;
+
+    $this->unpack_options($this->options, $options);
+  }

parent::init could be used here so safe some code

This review is powered by Dreditor.

dagmar’s picture

Thanks dereine.

Ok, I have reviewed again this patch. I reviewed some comments, line endings and not much more. I haven't got more comments to do about this issue. Opinions?

joachim’s picture

I've finally got round to applying this patch! :D

Looking at the UI, the choice of plugin is a radio button -- does this mean an area can only have one plugin at a time?

This means a lot of the useful applications of this are not possible.

Eg, some hypothetical modules/use cases:
- views_node_texts: lets you pick a node whose body is used for the text area.
- views_add_more: if the view is a node view and has a node:type filter, render a list of create content links for those types.
- show taxonomy child terms above a node view with taxonomy argument -- basically, a cleaner way of doing what image_gallery modules currently does.

Surely more than one of these may be desirable at one time -- ie have several of these in the header, along with the plain text area.

dawehner’s picture

validation did not worked

dawehner’s picture

FileSize
1.6 KB

Here is a example implementation

joachim’s picture

FileSize
3.43 KB

And here is another one :D

This displays node creation links for the types in the view; eg if the view is filtered to story and page, you get:
'Create story Create page'.

This is obviously only relevant if the view is a node view and has the node type filter -- therefore validate() needs to be called on these plugins, as discussed on IRC.

merlinofchaos’s picture

Ok, in thinking about this...yes, multiple plugins would be nice. However, I think that the UI would be distracting. TO do it right you basically need to promote the header and footer areas to something the size of fields, where you can add/remove/rearrange/configure each item. That's quite a bit of work, to start with, and I don't think MOST people would ever use more than one. Yes I can see where people WOULD use more than one.

So I'm thinking of punting on that for the time being unless/until it's demonstrated that the need for it is stronger than I believe it is, and is worth the added UI complexity.

Going to give #75 a good review next. Hoping to get this in soon!

dawehner’s picture

options_validate now uses the same kind of code as options_submit

merlinofchaos’s picture

Some doxygen related comments:

+class views_plugin_instantiable extends views_plugin {
+
+  var $instance;

Missing doxygen on this class.

+
+  function set_instance($instance) {
+    $this->instance = $instance;
+  }

And this function.

+ * @ingroup views_area_plugins

Requires a @defgroup if you use @ingroup

I'm not sure area_plugins needs its own group.

dagmar’s picture

One of the most interesting things in the Drupal community is: "Doesn't matter how many time do you spent in a patch, it always can be modified :)".

So, here is, a completely different approach for this issue.

Now, areas are handlers instead of plugins. Why? Well, if we want multiple areas per views like @joachim suggested in #74 we should think areas like something reusable (like fields, or arguments)

This patch need a bit of work related to the input_required exposed form plugin, that modified the empty text of the view. Now this way cannot be used any more, so we have to fix it.

I didn't test the conversion from views 2 to views 3 but the conversion script is present in this patch, so I somebody can test it...

I'm attaching a screenshot of what this patch does.

dagmar’s picture

FileSize
30.36 KB

Conversion from views 2 to views 3 tested (and fixed) using views bulk operations.

Exposed form plugin: Input required updated to work with this patch.

Use this patch for test. #81 produced white screens.

merlinofchaos’s picture

Version: 6.x-3.x-dev » 7.x-3.x-dev
Status: Needs review » Patch (to be ported)

I didn't try to run this on 7.x, assuming it would fail. It may actually not. =)

But committed to 6.x-3.x!

merlinofchaos’s picture

While I had originally wanted to target this to 2.x, this change is too complicated for my tastes. While it is valuable, I think we'l have to leave this a 3.x only feature.

dawehner’s picture

Issue tags: -views 3.x roadmap, -alpha-2 blocker

remove tag.

joachim’s picture

Though... beyond the updated existing areas, what area handlers would we like to include in Views, if any?

merlinofchaos’s picture

I would like some way to do a view links. Most common use case: You've got a view that lists 'foo' nodes and at the end you want 'create a new foo' as a link. It would need some way to test access control or something.

joachim’s picture

> Most common use case: You've got a view that lists 'foo' nodes and at the end you want 'create a new foo' as a link. It would need some way to test access control or something.

That's on my list too! I started an implementation (zipfile posted in an earlier comment, but for the old plugin system, and yes, TOTALLY lacking access control). Wondering if it would it be more efficient to try to hijack the menu system and see what paths beneath 'node/add' the user may access, or call hook_access?

merlinofchaos’s picture

These are good questions that I do not have any immediate answers for. =)

joachim’s picture

We should probably also add the text area handler to the three areas as default for new views; otherwise this change adds a heap of UI steps for users just to get what they used to have.

joachim’s picture

One more thing....

Area handlers are defined in hook_views_data... I know that's because they're handlers and that's how the handler system works, but isn't that a bit of a WTF?

dawehner’s picture

No. you have to use hook_views_handlers. Thats where handlers are defined :)

function views_views_handlers() {
       'views_handler_sort_group_by_numeric' => array(
         'parent' => 'views_handler_sort',
       ),
+
+      // area handlers
+      'views_handler_area' => array(
+        'parent' => 'views_handler',
+      ),
+      'views_handler_area_text' => array(
+        'parent' => 'views_handler_area',
+      ),
     ),
   );
joachim’s picture

Indeed; I saw that. My point is that it feels strange! ;)

dagmar’s picture

I didn't have time to code it to this patch, but I would like to see this handlers for areas:

  • Embeb an existent block.
  • Provide the sum of a field (like a total for price).
  • Collapsible text areas.
merlinofchaos’s picture

Oh yes, running totals would be quite nice.

dawehner’s picture

views calc is already much easier than in views2: count/sum support. Thats cool.

joachim’s picture

Status: Patch (to be ported) » Active

Ok. Let's farm out new handlers to their own issues (#697248: Text area handler: node creation links) and concentrate here on the hook_views_data weirdness and defaults for new views.

On IRC just now: merlinofchaos: That should be moved to hook_views_handlers

joachim’s picture

dawehner’s picture

Status: Active » Fixed

ported, tested, yeah

Bilmar’s picture

nice! =)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.