Would be great to put this API into core now that the build_modes patch is in. One hitch I see is that this module works upon extending theme('username') but it should not work at theme layer in d7/ it should work during a 'build' layer in order to use build_modes.

Hopefully someone will take this on.

Comments

sun’s picture

yeah, the "how" is the tricky part. yched already created #499192: Fix display and forms for "Fieldable terms" , which is a prerequisite for all of this.

Braindump:

a) Straight mapping of this module's terminology to core:

- "decorator" == "field"

- "user display style" == "build mode"

- "user display class" == non-existing

b) Display classes, i.e. an additional argument to theme('username') and theme('user_picture') is still required to make this work. Classes are specified by developers, to specify the logical appearance of a user. In many cases, __FUNCTION__ might work as well though. Classes do not specify the build mode -- the site administrator maps available classes to build modes instead.

c) Given b), hook_user_display($op == 'classes') would still be required in modules. That said, I'm not entirely sure whether all possible display style elements can be replaced with fields:

/**
 * Implementation of hook_user_display().
 */
function user_visits_user_display($op) {
  switch ($op) {
    case 'elements':
      $items['user_visits_visited'] = array(
        '#type' => 'select',
        '#title' => t('Display last visit time'),
        '#options' => drupal_map_assoc(range(1, 6)),
        '#default_value' => 1,
        '#description' => t('Enter the granularity as option; see !format_interval.', array('!format_interval' => l('format_interval()', 'http://api.drupal.org/api/function/format_interval'))),
        '#category' => 'decorators',
      );
      return $items;

    case 'classes':
      $classes['user_visits_block'] = array(
        'name' => t('User Visits'),
        'description' => t('This class applies to users shown in the User Visits block.')
      );
      return $classes;
  }
}

function custom_user_display($op) {
  switch ($op) {
    case 'elements':
      $items['buddylist_remove'] = array(
        '#title' => t('Display buddylist remove link'),
        '#category' => 'decorators',
      );
      return $items;

    case 'classes':
      $classes['custom_user_info'] = array(
        'name' => t('User info block'),
        'description' => t('This class applies to users shown in the user info block.')
      );
      return $classes;
  }
}

d) The (currently non-existing) UI to map classes to build modes could live in contrib, if that turns out to be not suitable for core. Although that's also the least complicated part:

// 'class' => 'style id' ("build_mode")
$conf['user_display_classes'] = array(
  'comment' => 1,
  'node_event_page' => 1,
  'node_forum_page' => 1,
  'user_block_new' => 1,
  'user_block_online' => 1,
  'user_visits_block' => 8,
);

e) Markup. For flexible theming in different locations and states, depending on the user display style and its elements, one needs a fair amount of markup and CSS classes. I could imagine that this flexibility is not needed on all Drupal sites or in all situations of a Drupal site - that's why User Display API falls back to theme_username()'s regular output when none of its styles shall be rendered.

<div class="user-display user-picture user-user_medium user-status user-offline user-name user-links user-25 user-links-processed">
  <div class="user-picture"><a title="" href="/user/sun"><img class="imagecache imagecache-user_medium" title="" alt="sun's picture" src="/files/imagecache/user_medium/pictures/avatar-default.png" /></a></div>
  <div class="user-status"><img height="12" width="12" alt="Offline" src="/themes/foo/images/icon_offline.png" /></div>
  <span class="user-name"><a title="" href="/user/sun">sun</a></span>
</div>

f) In correlation with c) and e): For proper theming, it's pretty important to be able to re-order all elements in a style. Fields could probably be re-ordered via build mode UI already, but when considering that above mentioned elements/decorators are rather auto-generated information and links from modules, it gets a bit complicated. Since there is no UI currently, ordering is done hard-coded:

$conf['user_display_styles'] = array(
  1 => array(
    'name' => 'Review', // Only used internally.
    'elements' => array(
      array('user_display_imagecache', array('user_small')),
      array('user_display_onlinestatus'),
      array('user_display_username'),
      array('user_display_comments'), // Stats: Displays # of comments.
      array('user_display_nodes', array('review')), // Stats: Displays # of nodes of type 'review' by user.
      array('user_display_links'),
    ),
  ),
);

g) Technically, theme('user_picture') is superfluous with User Display API's approach and could be nuked.

guillaumeduveau’s picture

Subscribe