I realize this is a very late breaking feature request for Drupal 7, however it is a one line addition to field.module that makes a hell a big difference to how we can approach theming fields.

With this patch we can have template suggestions/preprocess functions per #field_type - e.g. theme all taxonomy reference fields in one hit. At the moment, afaikt this is not possible, which means themers hav to either add these suggestions, override every field based on #field_name or live with the markup generated by theme_field - which is not very nice for fields such as taxonomy reference fields which should be, imo, a list and not a bunch of div's.

The one line addition is...

'field__' . $element['#field_type'],

If I'm missing something here let me know, I don't really get all this fields in core stuff but I build a lot of themes and would really want to be able theme per field type (as in changing the markup).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bleen’s picture

Status: Active » Needs review

Here testbot ... here boy

Status: Needs review » Needs work

The last submitted patch, field_type_suggestions_v1.patch, failed testing.

jensimmons’s picture

For reference, this came up working on Bartik discussing taxonomy links #777840: Taxonomy terms should display inline

webchick’s picture

From IRC:

[23:41]  <jensimmons> webchick: Is http://drupal.org/node/784792 something that could happen now? Or is it DOA?
[23:41]  <webchick> jensimmons, That looks reeeeeeeeeeally iffy.
[23:42]  <jensimmons> it'd just be nice to know, since figuring out what to do about http://drupal.org/node/777840 depends on it
[23:42]  <Druplicon> http://drupal.org/node/777840 => Taxonomy terms should display inline => Bartik, User interface, normal, active, 7 comments, 1 IRC mention
[23:42]  <webchick> Yeah. Why aren't we just changing the markup for taxonomy to <li>s?
[23:42]  <jensimmons> i don't know
[23:42]  <jensimmons> well  because it's not in the theme....
[23:42]  <webchick> To me that would feel more like fixing a regression, where this is clearly a new feature, and has performance implications.
[23:43]  <jensimmons> ok. would you say so on the issue?
[23:43]  <jensimmons> then we can kill the effort to go down that road
[23:43]  <webchick> Sure, but I'd prefer to hear first from some of the theme system maintainers and get their view.
[23:43]  <jensimmons> ok
jensimmons’s picture

Issue tags: +Bartik
Jacine’s picture

Issue tags: -Bartik

This is one of the things that annoys me most about the current default core template files.

Suggestions went in kind of late, and it seems like a bug to me that it's not possible rather than a feature request, but I don't know what the performance implications are.

These terms should be output as a list by default, and generally there should be an easy way to do a type override that is inline with how the rest of templating works in Drupal. It's not just taxonomy terms we are talking about here... I can think of endless use cases where the ability to easily target a field type for theming makes sense. Different types of data usually need different markup/presentation.

So... +1.

Jacine’s picture

Issue tags: +Bartik

Sorry, cross-posted... adding the Bartik tag back.

Jeff Burnz’s picture

I pretty much figured the whole reason these may have been left out was performance related - are these known?

For example what is the performance implications of having 10 field_name overrides vrs 1 field_type override - or is that the wrong way of looking at this?

For me as a themer this very much feels like a bug because its inconsistent with the rest of the theme-overriding system and most certainly a pretty big wtf moment when I realized this could not be done in core.

While the mechanism exists for me to override markup for any field its the amount of work that that entails and the fact that I cannot deliver a theme that won't break if the end user adds or changes something.

And while the classes exist for me to style something appropriately, such as .field-type-number-decimal, I want to be able to structure my documents semantically so in many instances labels would be h2 or h3 and the content of the field uses some other markup - not just a div.

So for me it comes down to having a way of cleaning up the output - generating markup the way I want it, without having to resort to field_name ad infinitum preprocess functions or having to add field_type suggestions to every theme I build.

While I will simply get on with it and do it my themes regardless (because its just so powerful, unless there was some show stopping, server breaking performance reason), it would be extremely useful to have this in core.

joachim’s picture

+1

We have a regression here: taxonomy terms should be displayed as an inline UL and currently they are not.

webchick’s picture

So, once again, why are we not just fixing the regression with taxonomy's output?

Edit: Er. I mean I get that this would be a nice thing to have, but it's unclear to me why a solution like this is needed to fix taxonomy. It seems like you're trying to hack around sub-optimal output, so let's just fix the output.

webchick’s picture

As far as performance stuff goes, probably people like catch, effulgentsia, etc. would be good folks to talk to. They did endless amounts of belly-dancing to get field templates to perform at an acceptable level.

This still smells featurey to me.

Jeff Burnz’s picture

@webchick - basically because taxonomy is just an example, its not just about changing the markup for taxonomy terms, its about being able to theme fields by type.

"why are we not just fixing the regression with taxonomy's output"

I'm not really sure what is meant by this, from what I can tell (someone put me strait please) the output of all fields is via theme_field. So from (my limited) POV this is the way to modify the output.

I want to reiterate though, taxonomy is just one field type, there are many others, and probably more to come out of contrib - I would think module builders would want this also, so they can theme their their field type?

Jacine’s picture

All I see is the following:

THEMENAME_field__body__article()
THEMENAME_field__article()
THEMENAME_field__body()
THEMENAME_field()

http://api.drupal.org/api/function/theme_field/7

In the above example, article is the content type, and body is the field.

Personally, I would be a lot less likely to theme fields by content type or name, over field type. This is especially true for taxonomy terms, where there are likely a few per site at minimum. Other examples would be fields like phone & fax numbers, dates, numbers/currency, where there are more than one actual field (different names), but which will require the same output. Core provides 2 taxonomy vocabs (tags and forums).

Without the ability to target the field type, I would be inclined to make a ridiculous theme_field() override just to avoid going after each taxonomy field by name to do the same thing with the markup. Why create 3 template files containing the same exact code? It's not very efficient. Still you need to understand theme functions to even consider this.

Even if it's decided that this is a "feature request" I would love to see how it's going to be done, because I don't see an easy way right now, so maybe I'm missing something too.

gapa’s picture

Jeff Burnz’s picture

Priority: Normal » Major

Is it too late for this, this is going to be one of the biggest WTF's in Drupal theming in D7, put simply contrib starter themes will probably add these and we'll have the whole "snippet thing" going on when it should be supported by core.

People need to actually start theming field displays in D7 and see what a joke it is to be forced to deal with screeds of nested DIV's for outputting stuff that should be a list etc etc.

Setting to major, this is simply inconsistent with the rest of Drupal theming and leads to an unnecessarily poor TX.

To reiterate the issue:

At the moment you can only add field template suggestions by field name and/or bundle, so if you have 6 image fields and you want to change them all (and you want them all the same) you have to add either 6 overrides or override the bundle (yeah, because we will want to do that, and it assumes they're all in the same bundle).

  $variables['theme_hook_suggestions'] = array(
    'field__' . $element['#field_name'],
    'field__' . $element['#bundle'],
    'field__' . $element['#field_name'] . '__' . $element['#bundle'],
  );

What we should be able to do is add one template by type and override ALL of them, with name based suggestions taking precedence if they exist. I have already done this in my D7 starter themes and it works very well.

I blogged about this about this back in March. Whats doubly absurd here is that we have these almost useless field-[bundle] suggestions, but not the hugely useful field-[type] suggestions...

Jacine’s picture

I agree 100%. I don't understand the objection either.

webchick’s picture

As far as performance stuff goes, probably people like catch, effulgentsia, etc. would be good folks to talk to. They did endless amounts of belly-dancing to get field templates to perform at an acceptable level.

Jacine’s picture

We are not adding a template though. We are simply asking to add a suggestion for #field_type. I don't get it. I'll try to find catch or effulgentsia on IRC and ask them.

Jacine’s picture

Ok, I couldn't get catch, but I asked merlinofchaos, and he showed me how to test it myself. I tested this on the homepage of my test site, which has 10 nodes on it. I hacked drupal_render() and did the following:

  // Call the element's #theme function if it is set. Then any children of the
  // element have to be rendered there.
  if (isset($elements['#theme'])) {
    // Start hack
    if ($elements['#theme'] == 'field') {
      timer_start('field_test');
      foreach (range(1, 1000) as $count) {
        $elements['#children'] = theme($elements['#theme'], $elements);
      }
      $time = timer_stop('field_test');
      dsm($time['time'] / 1000 . ' s');
    }
    else {
      $elements['#children'] = theme($elements['#theme'], $elements);
    }
    // End hack
  }

These were the results:

Before

0.12404 s
0.47532 s
0.98916 s
1.12415 s
1.64731 s
1.78298 s
1.92098 s
2.05935 s
2.19844 s
2.3373 s
2.47671 s
2.61559 s
2.7545 s

After

0.12473 s
0.4762 s
0.99204 s
1.12848 s
1.6549 s
1.79142 s
1.92889 s
2.06738 s
2.20873 s
2.34799 s
2.48726 s
2.62643 s
2.76581 s

There is a performance impact, but it's very small and I think we really need this. The current suggestions are really not very useful, or consistent, and I'd be willing to bet that what themes end up doing to get around this will be considerably worse in the long run.

Jacine’s picture

Status: Needs work » Needs review
FileSize
725 bytes

Here's the patch again, since something was wrong with the format of the other one.

bleen’s picture

Status: Needs review » Reviewed & tested by the community

The patch looks good, and based on Jacine's AB test result I dont think there is a significant performance impact here. So.... RTBC

webchick’s picture

Status: Reviewed & tested by the community » Needs review

I still need to see sign-off on this from one of the people who worked on the original field templates patch. This is also very late, but the case has been made to at least consider this in D7.

Those numbers do indeed look like there's a fairly small performance impact, although I can't quite tell if they're accurate in a more typical "real world" scenario where we're showing a list of 10 nodes with ~10 fields each.

joachim’s picture

Won't the one extra filename to search for only have an impact when the theme registry is being refreshed?

Jeff Burnz’s picture

I took the hack in #19 and applied this to my install:

10 nodes on the front page with 8 fields each:
2x image fields
2x text fields
1x long desc fields
2x taxonomy fields
1x integer field

I wanted to test 4 variations:

1 - default (field_name, bundle, bundle__field_name)
2 - patched (field_type, field_name, bundle, bundle__field_name)
3 - field_name only
4 - field_type, field_name

I ran the test 3 times for each variation and average the results of the first 20 rows of data:

suggestions-summary.png

As you can see in order of performance we have:

#1 - field_name only
#2 - field_type + field_name
#3 - un-patched
#4 - patched (patch in 19)

The interesting thing for me here is that while field bundle suggestions have worse performance they have been added to core. I really question this because of the usefulness of these suggestions. AFAICT bundle suggestions will theme ALL the fields in a bundle with a single function/template override. You can then override one or more of these with bundle__field_name. To me this whole bundle + bundle_field_name suggestions feel like an edge case - why would you ever want to do this? Whereas there is an immediate use case for field_type in core, and IMO would have much broader use cases in the wild.

I think you can see what I am driving at - if this came down a to a strait out cost vs benefit - field_type + field_name win (according to my data and view of the issues overall - it would be very good if someone who actually built this system could chime in a give some reasoning as to why these bundle suggestions are included by default, to me they look like a performance hit and with rather limited application).

Additionally the above performance stats do not account for one very glaring fact - what are the performance implication of actually having 2x template overrides for 2 fields (of the same type), verses 1 for both?

Jacine’s picture

I think we are trying to optimize based on a false assumption that most themes will not attempt to modify theme_field() or actually use these suggestions in some way shape or form. The taxonomy term example (needing to be a list) is just one example. theme_field()'s markup doesn't make sense in many situations, and themers WILL change it. The suggestions as they are now promote idiotic theming behavior. It's like saying, we're not going to allow you to theme nodes by node--type, but instead you need to do node--id for every node you want to style which is insane.

Since template files are rampant in Drupal these days, many themers don't think twice about adding them to themes, let alone have any idea there is any performance impact at all. By not adding the type suggestion (which is the only sane way to theme fields IMO), we are telling themes that it's okay to create templates for every single field name, and it's really not. If it wasn't a big deal, then we would even be talking about performance right now.

Also, @joachim brings up a very good question. That's what I thought, so I would like some clarification on this too:

Won't the one extra filename to search for only have an impact when the theme registry is being refreshed?

But, webchick is right, at this point, what we need catch or effulgentsia to weigh in on this.

moshe weitzman’s picture

There is miniscule performance impact for this patch. It can be up to 100 more file_exists() calls on a page with many fields displaying but that file_exists() is cached by the OS anyway. I think it can proceed. Would still be good to hear from catch or alex.

There is a general truism that templates are more expensive than theme functions but thats unrelated.

sun’s picture

Status: Needs review » Reviewed & tested by the community

This patch just makes sense. There is no real performance impact.

That said, if we'd really care for performance, then the theme system should cache theme hook suggestions results. That would only make sense, because everything else in the theme system is equally cached already. I wouldn't have remotely assumed that you can simply put a template file somewhere, anywhere, and expect that to work immediately. Likewise, you need to flush the theme registry cache(s), after changing a theme's .info file to add a CSS file or do whatnot.

What I'm trying to say is: If we're concerned about performance, then we should attempt the real, underlying performance issue seriously, instead of adding burden on themers.

catch’s picture

Template discovery performance was massively improved already due to #678714: Unify use of theme hook / template suggestions, fix clobbering problems, and improve suggestion discovery performance which removed all the runtime file_exists() calls, so I don't have any problem with this patch, didn't profile it but I think it'd more or less just make a couple of foreach() loops a bit longer, and that's nothing compared to the rest of what's going on here.

If people want to open D8 issues for removing the bundle suggestion that seems fine though - no point doing work for no reason.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Cool, thanks catch. I couldn't remember the details, I just remember there being a lot of teeth gnashing and crying and whatnot. I'm glad Jacine and Jeff Burnz also posted benchmarks to back this up, thanks.

I'm going to allow this in. It's technically an API change (more properly, API addition) after beta, but I think the argument has been well-made that the original field templates that were designed by the field team didn't take into account the reality of what themers would need from the system. This gives a lot more flexibility with one line of code and minimal performance impact.

So, committed to HEAD. :)

Status: Fixed » Closed (fixed)

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

RobW’s picture

Status: Closed (fixed) » Needs work

[edit] Whoops, posted in the wrong issue. Sorry friends.

RobW’s picture

Status: Needs work » Closed (fixed)