This is just some test code. What it does is remove devels use of phptemplate_preprocess since it should not be used inside modules.

Instead, it creates a custom function of "devel_preprocess" and it puts it at the very end of the list. This enables it to monitor *all* template logs. Not just the ones set from modules.

It's a dirty hack but it works. If the direction looks good then I hope someone can clean it up. I'm not familiar enough with all the hooks to know where it should be placed. For now you have to manually click the "clear cache" link to have the registry rebuilt.

Comments

StatusFileSize
new3.17 KB

Here's another dirty hack job. I saw your notes on trying to catch theme functions not associated with templates.

It doesn't do anything but intercept and run all theme functions through "devel_catch_theme_function()".

It contains the patch I just posted before also.

I was informed that HOOK_exit would be the best place for this. Unfortunately, I don't have the time to learn how it works + add the UI to turn it on/off.

This would be great for themers, especially the hack to intercept all the theme function so it can display which are being used for a page.

we can't alter the theme registry on every request (and at the end of each request?). hook_exit does not sound right to me. furthermore, will this pass in template suggestions like Views2 will do where you pass in an array of template names that are searched in order?

Yeah, I'm not certain. Is there somewhere it can run after a form submission? Have it trigger a new function with that registry rebuild code and while clearing the cache.

And I don't know how Views2 works. This is all it does..

Here's a partial entry for the "page" hook inside the registry that gets used when theme('page') is invoked. The rendering is done with a .tpl.php file so it contains preprocess functions that can supply template suggestions. Regular "functions" will never run these.

  ...
  ["preprocess functions"]=>
  array(5) {
    [0]=>
    string(24) "template_preprocess_page"
    [1]=>
    string(29) "phptemplate_engine_preprocess"
/////////////////////////////////////////////////////////////////
// devel registers this. Anything after it, it's not aware of. //
    [2]=>
    string(22) "phptemplate_preprocess"
/////////////////////////////////////////////////////////////////
    [3]=>
    string(27) "phptemplate_preprocess_page"
  }

So, if a theme registers more preprocess functions that supply more template suggestions, Devel will not be aware of them since _theme_build_registry() will add them after the engine.

The patch changes it to this..

  ...
  ["preprocess functions"]=>
  array(5) {
    [0]=>
    string(24) "template_preprocess_page"
    [1]=>
    string(29) "phptemplate_engine_preprocess"
    [2]=>
    string(22) "phptemplate_preprocess_page"
///////////////////////////////////////////////////
// Force as last preprocessor. This way it knows //
// about the final state of all variables.       //
    [3]=>
    string(27) "devel_preprocess"
///////////////////////////////////////////////////
  }

The second patch completely replaces the function that's normally run and only affect theme functions not rendered through templates. This has nothing to do with the original issue I brought up.

Original entry for theme_comment_block..

["comment_block"]=>
array(5) {
  ["arguments"]=>
  array(0) {
  }
  ["type"]=>
  string(6) "module"
  ["theme path"]=>
  string(15) "modules/comment"
  ["function"]=>
  string(19) "theme_comment_block"
  ["preprocess functions"]=>
  array(0) {
  }
}

And after the patch, we can intercept it and do whatever..

["comment_block"]=>
array(6) {
  ["arguments"]=>
  array(0) {
  }
//////////////////////////////
// Swap for devel pointers. //
  ["type"]=>
  string(6) "module"
  ["theme path"]=>
  string(23) "sites/all/modules/devel"
//- call to theme('comment_block') runs this instead..
  ["function"]=>
  string(26) "devel_catch_theme_function"
//////////////////////////////
  ["preprocess functions"]=>
  array(0) {
  }
//////////////////////////////////////////
// Save original information to be used //
// inside devel_catch_theme_function(). //
  ["devel"]=>
  array(5) {
    ["arguments"]=>
    array(0) {
    }
    ["type"]=>
    string(6) "module"
    ["theme path"]=>
    string(15) "modules/comment"
    ["function"]=>
    string(19) "theme_comment_block"
    ["preprocess functions"]=>
    array(0) {
    }
  }
//////////////////////////////////////////
}

Sorry if this is obvious to you. Just trying to be clear.

i am understanding better now ... the catch function is quite clever. it is is a bit more intrusive than devel usually gets (intercepting all theme calls) but maybe it is harmless. i don't want code in here that would be bad in a production context. this is meant to be used on live sites too. maybe others can comment here.

I don't think it would be harmful. Just need to ensure that the registry gets cleared when devel is disabled - if it doesn't already.

But imagine if All the theme functions used on a page could be listed in a block. With some jQuery, click a link and highlight all the elements that are using that function. Click another link to go to api.drupal.org. Would make theming so much more understandable.

both good suggestions. this is getting very interesting. i will fiddle and commit.

My suggestion, btw, is in hook_exit, to load the theme registry; check a setting in it to see if devel has already modified it; if so, leave it be.

If not, go through and modify every theme to pass through devel, and write the registry back.

Whenever modules are enabled/disabled, the theme registry is automatically cleared, so you don't need to worry about that.

Title:reserve phptemplate_preprocessor for themes and theme engines.Link the template log items to their corresponding divs in page body

this has been committed. i'd really appreciate some jquery person to add some code that turns each template in template log into a hyperlink. upon clicking, the corresponding div in the page body is highlighted.

Status:Needs work» Needs review
StatusFileSize
new16.94 KB

This patch goes a lot further by intercepting all themeable functions. It knows about all the template files considered for a loaded page and the active one in use. This also works with wildcard functions, list of preprocess functions and variables.

It no longer adds a preprocessor since it's no longer needed. There's tons of code duplicated from theme() and that was the only way I found it to work.

I tried to minimize the clutter. It will not repeat each hook. Instead it's displayed once and the relevant data under it. It filters or aggregates all the meta info that were run for every iteration for a hook.

All that's needed is some jQuery to do a sibling selector which shouldn't be difficult.

StatusFileSize
new117.17 KB

And a preview. :)

StatusFileSize
new17.03 KB

Small css correction.

StatusFileSize
new101.01 KB

A few more tweaks and bug fixes.. a preview.

StatusFileSize
new18.81 KB

Wildcard functions now work. Tested with Merlin's wildcard patch test files. Noticed some timer code in there so I added that in. It only tests theme functions. Anything else will not be counted.

It now knows if template suggestions actually exist or if they were just suggestions.

what would be lose if we refuse to keep a copy of all of theme()? i don't think i can stomach that in devel.module .. thankd for the screenshots. very helpful. soon you will need to write boxes and arrows on them so we know what each item means.

Status:Needs review» Needs work

Yeah, it is a bit too much. Of course I realize now that it's not needed. I don't think we'll loose anything important. I forgot about debug_backtrace() that can help gather some data. At first I saw how it could work, got excited and just went in that direction. :) No big deal, I consider it another learning exercise.

But what do you think of the output? I'd like to recreate that format. Having a HUGE list would be hard to navigate and understand.

With the current output, I was thinking of having a link from the theme function names to trigger jQuery to highlight every dom element using that function. The same goes for the preprocessor functions and actual template files.

I'll work on it a bit slower this time. Maybe within the week.

Oo, it just occurred to me. It may be possible to generate hierarchy of all the theme functions with debug_traceback(). Would be super useful on visualize and getting a mental map of how the page was generated.

Maybe in another revision.

i think thats the right idea for a UI. It would be annoying though to have template log at bottom of page and then all links just keep popping you to the top. so maybe we have a single template log link on the page and when clicked it shows a hidden div at top that has the template log along with the links which highlight content. hope that makes sense.

Moshe, there is something pretty big we would loose. The ability to push the markers into the dom for templated functions. Since their rendering is done way down inside theme(), there's no way to push anything before it renders. Everything else is doable.

Doh, I think that can be worked around also. Need to coax the global $theme_engine inside theme() to point to devel and back. A tiny bit of code to catch the output by pointing the render function inside devel, injecting the dom marker then output as usual. Hope that makes sense. This is a lot of trickery but I'll look into it further.

the template log would still output in same place in the HTML. it would just be hidden and when exposed, so css would move it to a comfortable spot.

I'm talking about all the empty div markers sprinkled all over the dom so it can be used with Jquery. Not the template log.

Templated functions run a very different course making them hard to push in the markers.

http://api.drupal.org/api/function/theme/6

StatusFileSize
new21.09 KB

Here's a very, very rough patch to get jQuery to select the DOM from clicking on a log entry. I haven't touched jQuery in a while and I'm not so great with it to begin with.

As for the registry and the theme() function. Only a tiny bit is copied over. What it does now is create a duplicate for each entry in the registry. The original points to devel_catch_theme_function but then theme() is called again from the catch function but it points to the duplicate entry with the original data. So, in a way it bounces back between the two.

That part works well and I'll post something a bit cleaner without jQuery. Hopefully someone can jump on that.

StatusFileSize
new110.74 KB

Click on the 'toggle' link and the log slides down from the top..

StatusFileSize
new110.45 KB

Click one of the entries, the log hides and highlights the DOM..

It kinda works. I think the DOM markers need to be placed at two points so it can reliable select between two ends.

Steven's field spotter module has some jquery and UI which highlights certain DOM elements. would be good to copy that. see http://drupal.org/project/field_spotter

Yeah, I'll look into that. Looks very simple. I love it!

dvessel - any chance you can get back to this? would be sweet.

Sorry Moshe, I've been busy. I'll get back to this ASAP.

@dvessel - i think we can also clean up how we inject our logging function into the theme registry. we have an alter operation now during registry building.

Title:Link the template log items to their corresponding divs in page bodyInformational popup for all theme functions on the page
Assigned:Unassigned» moshe weitzman
Category:bug» feature
Status:Needs work» Active

I've pushed this much farther and checked it all into HEAD. We now have fancy hover on every themeable element on the page. I also put all the variables and so on into the Drupal javascript settings framework so the hover is going to be very information rich. jjeff is helping with the design of the popup right now. I'll share some screenshots when this is a bit more polished. Beware, great stuff is coming soon.

Component:Code» devel_themer
Status:Active» Fixed

this is kicking much ass. i'll make screencast when it is ready for all. meanwhile, this issue can close.

Status:Fixed» Closed (fixed)

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