Problem/Motivation

There are way too many theme functions / template files in core. Some are similar (if not identical) and should be consolidated.

Proposed resolution

We have two options:

  1. Remove theme_task_list() and call theme('item_list') instead.
  2. If we really do need a separate preprocess function or markup for the task lists, then call theme('item_list__tasks') instead of theme('item_list') and add all our preprocess magic into template_preprocess_item_list__tasks()

Remaining tasks

Decide which of the 2 options above to pursue, and do it.

User interface changes

None.

API changes

Removal of theme_task_list

#1813426: [meta] Consolidate all item list templates and add theme_hook_suggestions

Original report by JesseBeach

theme_task_list() (http://api.drupal.org/api/function/theme_task_list/7)

Clearly a task for theme_item_list(). If for whatever reason what's happening here isn't possible with theme_item_list(), then it should be extended or fixed.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joachim’s picture

Is the full theme.inc loaded at this point? I suspect it may not be.

Jacine’s picture

Component: theme system » markup
Issue tags: -html5 +theme system cleanup

Possibly not, but that is definitely a crappy reason to create yet another theme function. Hopefully there's a way around that?

Also, in an effort to get a better picture of issues remaining in the HTML5 Initiative, we are removing the "html5" tag from issues that are not directly HTML5-related. Note: Any issues assigned to the "Markup, CSS and JavaScript" components will still be broadcast on the HTML5 Twitter feed so that interested parties are aware and can participate.

andypost’s picture

Is the full theme.inc loaded at this point?

Yes, _drupal_maintenance_theme() loads theme.inc

sun’s picture

Yes, the theme system should be fully operational in the installer as well as in update.php.

The only special part in theme_task_list() is this "active"/"done" text suffix to every item in the list:

   $output .= ($status ? '<span class="element-invisible">' . $status . '</span>' : '');

The suffix indicates whether a task in the list has been completed already, and whether a task is the currently active step.

I wonder whether this cannot be achieved and resolved differently -- through HTML attributes maybe?

Tagging for accessibility to hopefully get some insight from our experts.

andypost’s picture

Another trouble with $title:
theme_item_list() uses h3 but theme_task_list() uses h2

Everett Zufelt’s picture

The difference is not only that theme_task_list() has the extra invisible text, but that it has done / active classes (which is what the text was added to replicate).

I don't believe that there is currently a reliable method of communicating this meaning using html elements + attributes. I'd be happy to test theories that others want to try out.

The meaning we are trying to communicate, as I understand it, is progression through a set of tasks: which are complete, which is active, which remain undone.

andypost’s picture

Component: install system » markup
Status: Needs review » Active
FileSize
31.31 KB
1.2 KB

Wait, currently installer uses seven theme which has no sidebar_first region so no tasks are printed!
Suppose we need some magic to return back task-list

EDIT There's issue #1661814: Make "in maintenance" Seven use a responsive design

sun’s picture

Component: markup » install system
Status: Active » Needs review
FileSize
7.53 KB

The heading level can be easily adjusted in the CSS of Seven theme (which is used for the installer and update.php by default).

Class attributes for items are supported by theme_item_list() already, so that difference presents no problem.

The meaning we are trying to communicate, as I understand it, is progression through a set of tasks: which are complete, which is active, which remain undone.

Yeah, exactly.

If all fails, we'll need a custom theme function preprocessor for theme('item_list__tasks') that injects the suffixes for accessibility - based on a non-standard additional 'active_task' theme variable.

Attached patch demonstrates how that could work.

I additionally hacked the node default page to output a task list for easier testing/debugging.

There are some other theme system issues in the queue that are actually dealing with the problem space of enabling template_proprocess_* functions for derived/subpattern theme hooks.

Closely related to that, a special preprocessor as needed here requires access to all variables that have been passed into theme() (or alternatively, properties on the render element). I'm not sure whether there is an issue for that already, but I've quickly hacked the theme() function to pass all variables forward to the process functions and actual theme function.

What do you think?

andypost’s picture

Component: markup » install system
Status: Active » Needs review
+++ b/core/includes/theme.inc
@@ -924,15 +925,16 @@ function theme($hook, $variables = array()) {
-  // If a renderable array is passed as $variables, then set $variables to
-  // the arguments expected by the theme function.
   if (isset($variables['#theme']) || isset($variables['#theme_wrappers'])) {
     $element = $variables;
     $variables = array();
+    // If a renderable array is passed as $variables, then convert all element
+    // #properties into variables that may be expected as arguments by the theme
+    // function or preprocess functions.
     if (isset($info['variables'])) {
-      foreach (array_keys($info['variables']) as $name) {
-        if (isset($element["#$name"])) {
-          $variables[$name] = $element["#$name"];
+      foreach (array_keys($element) as $key) {
+        if ($key[0] === '#') {
+          $variables[substr($key, 1)] = $element[$key];
         }
       }
     }

This make hook_theme() variable definition useless.
Suppose better to define additional variables in custom preprocess

+++ b/core/includes/theme.inc
@@ -971,6 +973,9 @@ function theme($hook, $variables = array()) {
+    // Provide the originally passed in theme hook name to process functions.
+    $variables['theme_hook_original'] = $original_hook;
+

This should solve this problem

+++ b/core/includes/theme.inc
@@ -2083,6 +2088,29 @@ function theme_item_list($variables) {
+    $active = isset($variables['active_task']) ? $variables['active_task'] : key($variables['items']);

The only question how to pass this additional variables here

+++ b/core/includes/theme.inc
@@ -2083,6 +2088,29 @@ function theme_item_list($variables) {
+    $done = isset($variables['items'][$active]);

Also just add and override defaults

    $variables['type'] = 'ol';
    $variables['attributes']['class'][] = 'task-list';
+++ b/core/update.php
@@ -325,7 +325,10 @@ function update_task_list($active = NULL) {
-  drupal_add_region_content('sidebar_first', theme('task_list', array('items' => $tasks, 'active' => $active)));
+  drupal_add_region_content('sidebar_first', theme('item_list__tasks', array(
+    'items' => $tasks,
+    'active_task' => $active,
+  )));

active task could be set here by preparing $tasks but leads to a code duplication

andypost’s picture

I think introduced $variables['theme_hook_original'] makes sense but better have predefined $variables['theme_context_data'] or a kind of...
this variable could be passed after all variables defined in hook_theme() or with it's own key

sun’s picture

Please consider this as a prototype only.

The main challenge is that we want to allow for process functions that "sub-class" a generic theme function to achieve a more specific purpose.

That means all lists go through theme_item_list(). But a task list requires some additional massaging before the $variables are passed into the final theme function.

The idea of this patch is to allow to pass additional variables to the pre/process functions. This doesn't make the 'variables' declaration in hook_theme() obsolete. It is still used to define and supply default values for each variable.

The final theme function naturally and logically only knows about the $variables that are defined for itself. Any other variables are just simply ignored.

The added 'theme_hook_original' variable definitely pollutes the $variables some more with magic internal variables, but it is not the first variable that is being injected by default by the theme system.

I'm not necessarily defending the prototype I whipped up there; all I'm saying is that it is "a" solution for the overall problem space of reducing/merging theme functions into single implementations. There are some theme system challenges involved, which definitely need to be addressed in dedicated issues.

Very closely related to this are:
#956520: Available theme hook suggestions are only exposed when there are preprocess functions defined
#939462: Specific preprocess functions for theme hook suggestions are not invoked
#1751194: Introduce hook_theme_suggestions[_HOOK]() and hook_theme_suggestions[_HOOK]_alter()

With all of that being said, there are a couple of different possible solutions to the problem space.

The most trivial one would be to redefine the task_list theme hook definition into:

'task_list' => array(
  'variables' => array(...),
  'theme function' => 'item_list',
),

The problem with that approach, however, is that it requires to duplicate the 'variables' definition of 'item_list'. And whenever I hear or see "duplicate", a nuclear bomb starts to tick, in my book.

Though what I'm primarily after is that we could as well investigate to introduce "true sub-classing" of theme hooks; i.e., allow one definition to inherit another definition. So 'task_list' would inherit from 'item_list', and would be able to specify additional variables. — And now that I said it, this particular idea is moot, because it would manipulate the definition of variables for the final theme function, but the final theme function (item_list) only knows about the variables being defined for item_list. So please scratch the sub-classing idea. ;)

andypost’s picture

Thanx a lot for deep explanation, actually there could be a lot of different implementations so we need to choose a most suitable for most cases.

From twig perspective all 'magic' should happen in preprocess functions so my prototype in patch

mgifford’s picture

Status: Needs review » Needs work
Issue tags: +Accessibility, +Needs accessibility review, +theme system cleanup, +Theme Component Library

The last submitted patch, drupal8.theme-task-list.12.patch, failed testing.

mgifford’s picture

Issue tags: +a11ySprint

Sadly this has changed too much and is going to need a rewrite.

Because @jessebeach I think is still going to make the sprint I'm hoping we can advance this.

mgifford’s picture

Status: Needs work » Needs review
FileSize
7.04 KB

re-roll.

Status: Needs review » Needs work

The last submitted patch, drupal8.theme-task-list.16.patch, failed testing.

mgifford’s picture

Status: Needs work » Needs review
FileSize
6.96 KB

Reroll, combining template_preprocess_item_list() with existing one.

Status: Needs review » Needs work
Issue tags: -Accessibility, -Needs accessibility review, -theme system cleanup, -a11ySprint, -Theme Component Library

The last submitted patch, drupal8.theme-task-list.18.patch, failed testing.

mgifford’s picture

Status: Needs work » Needs review

#18: drupal8.theme-task-list.18.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +Accessibility, +Needs accessibility review, +theme system cleanup, +a11ySprint, +Theme Component Library

The last submitted patch, drupal8.theme-task-list.18.patch, failed testing.

mgifford’s picture

Where is node_page_default() now? There's still a reference:

$ grep -ir 'node_page_default' core/*
core/modules/node/node.module: * @see node_page_default()

It's just not clear to me where to insert:

        '#suffix' => '</div>',
      );
    }
+   $build['tasks'] = array(
+     '#theme' => 'item_list__tasks',
+     '#title' => t('Installation tasks'),
+     '#items' => array(
+       'foo' => 'Fool me',
+       'bar' => 'Bar me',
+       'baz' => 'Buzz me',
+     ),
+     '#theme_context' => array(
+       'active_task' => 'bar',
+     ),
+     '#attached' => array(
+       'css' => array(drupal_get_path('module', 'system') . '/system.maintenance.css'),
+     ),
+   );
    return $build;
  }
andypost’s picture

I think this one is replaced with view.
Also related #713462: Content added via drupal_add_region_content() is not added to pages

mgifford’s picture

@andypost - do you know which view?

Also, is it too late for this replacement in the D8 cycle?

andypost’s picture

@mgifford suppose a 'frontpage' view so the front page is view. Please re-roll the patch

mgifford’s picture

Status: Needs work » Needs review
FileSize
6.28 KB

Re-rolled without node.module. I haven't done anything with the frontpage View.

Also noticed that function although node_page_default() is removed from D8, node_form_system_site_information_settings_form_alter() still references it in the inline docs * @see node_page_default()

Status: Needs review » Needs work

The last submitted patch, drupal8.theme-task-list.1222254-29.patch, failed testing.

mgifford’s picture

Status: Needs work » Needs review
FileSize
6.25 KB

re-roll for element-invisible change.

Status: Needs review » Needs work

The last submitted patch, drupal8.theme-task-list.1222254-28.patch, failed testing.

jenlampton’s picture

Issue tags: +Template consolidation

tagging.

jenlampton’s picture

Issue summary: View changes

updated.

jenlampton’s picture

Title: theme_task_list() should be replaced with theme_item_list() in all instances » Remove theme_task_list() and call theme('item_list__tasks') instead.
Issue tags: -a11ySprint, -Theme Component Library

tag cleanup, and title cleanup

mgifford’s picture

Status: Needs work » Needs review
FileSize
6.53 KB

re-roll of 28.

Status: Needs review » Needs work
Issue tags: -Accessibility, -Needs accessibility review, -theme system cleanup, -Template consolidation

The last submitted patch, drupal8.theme-task-list.1222254-32.patch, failed testing.

mgifford’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
Issue tags: +Accessibility, +Needs accessibility review, +theme system cleanup, +Template consolidation

The last submitted patch, drupal8.theme-task-list.1222254-32.patch, failed testing.

mgifford’s picture

Status: Needs work » Needs review
FileSize
6.48 KB

Not sure this addresses the updates in function update_task_list() but least the patch should apply.

The last submitted patch, drupal8.theme-task-list.1222254-36.patch, failed testing.

mgifford’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
Issue tags: +Accessibility, +Needs accessibility review, +theme system cleanup, +Template consolidation

The last submitted patch, drupal8.theme-task-list.1222254-36.patch, failed testing.

mgifford’s picture

get_t() was removed.. No longer needed.

mgifford’s picture

Status: Needs work » Needs review

oops.. bot..

Status: Needs review » Needs work

The last submitted patch, drupal8.theme-task-list.1222254-40.patch, failed testing.

jenlampton’s picture

Assigned: Unassigned » jenlampton

dibbs

jenlampton’s picture

Status: Needs work » Needs review
FileSize
7.46 KB

I didn't like the approach of adding the classes and extra markup in preprocess - we can do that instead before we call the theme function.

Rerolled with this new approach, and now things work with theme_item_list without that specific preprocess function that was blocked on
#1751194: Introduce hook_theme_suggestions[_HOOK]() and hook_theme_suggestions[_HOOK]_alter()

Also, this fixes some untranslatable strings that were forced in from within theme_task_list in D7.

Not sure why these are tagged with accessibility review, if we leave the markup the same as it was before, do we need a new review?

mgifford’s picture

Status: Needs review » Needs work

The last submitted patch, twig-task_list-1222254-44.patch, failed testing.

Anonymous’s picture

Issue summary: View changes

cleanup

mgifford’s picture

Status: Needs work » Needs review
FileSize
7.42 KB

re-roll.

mgifford’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
sun’s picture

mgifford’s picture

Status: Needs work » Needs review
FileSize
7.06 KB

This wasn't a trivial re-roll, but....

Status: Needs review » Needs work

The last submitted patch, 50: twig-task_list-1222254-50.patch, failed testing.

lauriii’s picture

Assigned: jenlampton » Unassigned

Unassigning jenlampton - she probably wont keep working on this after 2 years :)

veerasekar89’s picture

Assigned: Unassigned » veerasekar89
andypost’s picture

yogen.prasad’s picture

Assigned: Unassigned » yogen.prasad
yogen.prasad’s picture

Assigned: yogen.prasad » Unassigned
deepakaryan1988’s picture

Assigned: Unassigned » deepakaryan1988
deepakaryan1988’s picture

Assigned: deepakaryan1988 » Unassigned
mitokens’s picture

saki007ster’s picture

Assigned: Unassigned » saki007ster
FileSize
2.71 KB

Not sure did the right thing, just giving it a try.

saki007ster’s picture

Status: Needs work » Needs review
saki007ster’s picture

Assigned: saki007ster » Unassigned
mgifford’s picture

Thanks @saki007ster for giving it a try. I just went through comparing the work you did with the patch I re-rolled in #50 with what you posted. You've simplified it a lot. Now part of that is that we've eliminated a lot already. For instance theme_task_list() doesn't seem to be part of Core any more.

My question though is how do your changes help meet the goal in the issue summary? Maybe this should just be closed? I've just given this a quick review.

saki007ster’s picture

@mgifford I just re-rolled the patch though it was not a trivial one then, But now I also feel this can be now closed as theme_task_list() is already no more in core which was the main aim of this issue.

mgifford’s picture

Status: Needs review » Closed (cannot reproduce)

@saki007ster - makes sense to me... Thanks!

Sorry that you went through the re-roll before seeing that theme_task_list() had been removed.

Really appreciate your time!