Task
Use Twig instead of PHPTemplate
| Theme function name/template path | Conversion status |
|---|---|
| theme_pager | converted |
| theme_pager_link | converted |
How to test this code
- Create (or devel generate) a number of posts that are all published to the home page
- Edit your front page view so that are fewer items per page than there are items
- You should see a pager on the home page, test it
Related
#1757550: [Meta] Convert core theme functions to Twig templates
| Comment | File | Size | Author |
|---|---|---|---|
| #83 | 1898474-83.patch | 20.46 KB | mondrake |
| #83 | interdiff_80-83.txt | 1.08 KB | mondrake |
| #80 | 1898474-80.patch | 20.5 KB | mondrake |
| #80 | interdiff_65-80.txt | 8.31 KB | mondrake |
| #65 | 1898474-65.patch | 20.25 KB | mondrake |
Comments
Comment #1
c4rl commentedTagging
Comment #2
geoffreyr commentedComment #3
mondrakeRelated,
#1778990: Merge theme_pager_link*() theme functions into theme_link()
#1588138: pager_query_add_page() [in D7, theme_pager_link()] overrides parameters passed programmatically
Comment #4
c4rl commentedBased on #1905584: Move base theme system templates into /core/templates it seems this issue would be accommodated by #1898454: system.module - Convert PHPTemplate templates to Twig, though that may result in a large patch.
Comment #5
c4rl commentedIgnore what I said about system.module in #4, we'll proceed to convert this separately of system.module and put in /core/templates as described in #1905584: Move base theme system templates into /core/templates
Comment #6
chrisjlee commentedWhere do the pager theme files go if there's no folder in d8/core/modules/* ?
Do i just create one?
Comment #7
c4rl commented#6 @chrisjlee, Please see #1905584-16: Move base theme system templates into /core/templates, currently in-progress. We may need to re-roll depending on timing.
Comment #8
chrisjlee commentedThanks c4rl. Will do.
Comment #9
chrisjlee commentedComment #10
star-szrI'll post an initial patch for this issue tonight, just need to convert a handful of theme() calls to render arrays.
Comment #11
star-szrMarkup matches up (other than whitespace and attribute order), let's see if any tests break. The pager tests passed locally.
I’ve removed the following declarations from drupal_common_theme() in theme.inc. These theme functions were removed in #1598886: Clean up pager theme functions and replaced with theme suggestions (i.e. pager_link__first), but the drupal_common_theme() deletions were lost in a reroll on that issue.
This also updates documentation referring to theme_pager(), leaving one reference in aggregator-wrapper.tpl.php to avoid conflict with #1896060: aggregator.module - Convert PHPTemplate templates to Twig.
Comment #12
mondrakeHi Cottser,
I was hoping #1588138: pager_query_add_page() [in D7, theme_pager_link()] overrides parameters passed programmatically could be fixed with this conversion. It would be a change on how the query parameters are resolved within theme_pager_link(). It was already raised within #1778990: Merge theme_pager_link*() theme functions into theme_link(). Could you please consider?
Comment #13
star-szrHi @mondrake, thanks for the feedback (but not sure why you changed the issue status). During the Twig conversion phase we are focusing only on converting theme functions and templates to Twig. Cleanup, consolidating and refactoring will come later, and we could certainly use your help throughout the whole process!
I know your patch is small but I don't think it should be added to this issue. I'll leave a comment on #1588138: pager_query_add_page() [in D7, theme_pager_link()] overrides parameters passed programmatically as well.
Comment #14
mondrakeThank you @Cottser for feedback, and sorry for breaking the workflow.
Comment #14.0
star-szrAdd conversion summary table
Comment #15
star-szrTagging.
Comment #16
star-szrI don't see anything else to change here, assigning to @steveoliver for review.
Comment #17
thedavidmeister commentedWe're just replacing one bug #1410574: Make l() respect the URL query string before adding the 'active' CSS class for another here aren't we? going from all pager links always having the active class to no pager links ever having the active class. Isn't the active class in pagers pretty much the only time the active class is actually useful? I'm possibly missing something about the way pagers work here...
Not quite, that's what href was before it was passed to url(). The return of url() is a relative or absolute URL but not an internal path.
Comment #18
star-szr@thedavidmeister - so it sounds like we should stick with l() for your first point, correct?
Comment #19
thedavidmeister commented#18 - yeah. I was thinking keep it simple and don't change that line here at all as there's already a separate issue open for that bug.
Comment #20
star-szrImplementing #17 - back to l(). theme_pager_link is up for consolidation anyway.
Comment #20.0
star-szrUpdate remaining
Comment #21
fabianx commentedNot to derail this further, but a question:
Can this use #theme => link once gut l() is in or #type => link, so that output is changeable via other preprocess coming later?
Hm, thinking about this again, pager_links should just use #theme or #type link directly, therefore usage of l() here is fine.
Thanks!
Comment #22
c4rl commentedPer #1757550-44: [Meta] Convert core theme functions to Twig templates, retitling to indicate this issue applies to theme_ functions, which are lower in priority than PHPTemplate conversion issues.
Comment #23
intergalactic overlords commentedHTML output for both pager and mini pager is good. rtbc.
Comment #24
thedavidmeister commentedComment #25
geoffreyr commentedProfiling.
Comment #26
geoffreyr commentedScenario: One page with two views, each with pagers. One full, one mini.
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run1=519d3e4861676&...
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run1=519d3e4861676&...
Comment #27
geoffreyr commentedComment #28
dawehnerWe change it from ">>" to ">"
We seem to have lost the title of the item_list ('Pages')
We change it from ">>" to ">"
Comment #29
jwilson3#28, should have been marked CNW, not CNR, right?
Comment #30
hanpersand commented#20: 1898474-20.patch queued for re-testing.
Comment #31
jerdavisComment #32
jerdavis@dawehner #28 -
previous and next were both a single < or > already. First and Last are the links which contain << or >>.
The "Pages" title is present in core/modules/system/templates/pager.html.twig:
Review of the patch looks good. I'm moving on to profiling.
Comment #33
jerdavisProfiling results
Scenario
* Set front page to show 1 item with full pager
* Create block showing 1 item with mini pager, place in sidebar
* Create 3 nodes
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run1=519fd31a307c4&...
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run1=519fd31a307c4&...
Comment #34
jerdavisComment #35
fabianx commentedThis looks good, feedback has been addressed since last RTBC and acceptable performance tradeoff to me!
Comment #37
catch#20: 1898474-20.patch queued for re-testing.
Comment #39
mondrakeSimple re-roll of patch in #20, system.theme.css moved location.
Comment #40
catchIs there a reason we can't make this theme('link') with suggestions now? I'm not sure it needs to wait until #1595614: [meta] Remove all the theme functions and templates in core that simply output a link. Replace with #type 'link' render arrays is resolved for all other link functions.
Comment #41
mondrakeI suppose that's what #1778990: Merge theme_pager_link*() theme functions into theme_link() is meant for
Comment #42
mondrake@catch re comment in #40, I prepared a patch that would combine #39 with #1778990: Merge theme_pager_link*() theme functions into theme_link() and get rid of theme_pager_link altogether. However I am uncertain to post here since #20 was RTBC already. Please advise.
Comment #43
catch@mondrake could you post the patch as do-not-test with an interdiff against #39? If it's a small change relative to this one I think we could go ahead combining the issues.
Comment #44
mondrakeHere we go.
Comment #45
mondrakeSorry, disregard #44.
Comment #46
jwilson3I wouldn't have a problem combining #1778990: Merge theme_pager_link*() theme functions into theme_link() into this issue, particularly since they both touch much of the same code, and if left separate, will ultimately need more work to get a re-roll after one or the other gets in (which-ever goes first). On the other hand, I'm not really sure that the interdiff in #45 could be considered a "small change", but hey, the work to integrate them is already done. Thanks mondrake!.
Maybe we could get both catch's and perhaps even sun's feedback on this (sun originally worked on the other issue).
Comment #47
mondrakeneeds re-roll because of #1363112: Simplify names of "element-x" helper classes
Comment #48
mondrakere-roll of #45
this changes the pager twig template
also added a theme suggestion to the final render array of template_preprocess_pager()
to make it consistent with the output in theme_views_mini_pager()
Comment #49
thedavidmeister commentedrelated #517242: theme_pager() could be more efficient when there is nothing to page
Comment #50
fabianx commentedLets give this one more round of manual testing.
Besides this, this looks very very RTBC to me.
Sooo nice cleanup.
Thanks all!
all++
Comment #51
jwilson3Would it make sense to change these lines that touch the $tags in views mini pager to match the logic in the standard page?
Comment #52
azinoman commentedpatch needed a reroll.
Comment #54
mondrakeThe user.admin.inc piece has been fixed in issue #2009690: Replace theme() with drupal_render() in user module, so no longer relevant here.
@azinoman your patch was including some leftover + removed the Twig template.
Re-roll patch soon.
Comment #55
mondrakeRe-roll, taken away the user.admin.inc piece.
Comment #56
mondrakeComment #57
mondrakeAttempt to fit in input in #51. Let's see if bot is happy.
Comment #59
mondrake#57: 1898474-57.patch queued for re-testing.
Comment #60
mondrakeRe-testing after #1985470: Remove theme_link() went in, is that impacting this issue?
Comment #61
mondrake#57: 1898474-57.patch queued for re-testing.
Comment #62
mondrakeYes, all these render arrays will no longer be rendered as theme('link') is no longer there...
So this would have to be changed to sth like
But:
Comment #64
thedavidmeister commentedThe patch at #2012812: drupal_render() can't distinguish between empty strings from theme() and no hook being matched would help with this if it got reviewed ;) it allows you to safely build a composite #type -> #pre_render -> #markup and #theme => array('suggestion', 'another_suggestion') style arrays, with the #markup from the #pre_render being used as a fallback for when the theme suggestions are not *implemented* (rather than the current situation where #markup only renders if #theme is not *set*).
Comment #65
mondrakeOK, another reroll to cover part of #62 i.e. switching from #theme to #type.
Put in @todos for the rest points in #62.
Comment #66
mondrake#65 is OK, but setting back to needs work because of the @todos. Also, doesn't look as a Novice task any more :(, so removing tag.
Looking for comments/proposals, I'm stuck now.
Comment #67
thedavidmeister commentedyeah, I had a look at this. The suggestions issue is deeper than I first thought. There are ways to make this work eventually, but I don't think there's any immediate "quick fix" :/
I have to admit that I don't know as much as I'd like about the way suggestions work in detail, I'm going to keep looking into this and see what I can come up with - even if it has to just be a workaround for D8 and leave the improvements to the API in D9, i dunno yet..
Comment #68
jenlamptonthis is what we want:
have we tried any of these?
1) the same way we'd call theme:
2) or maybe
I'd like to see us find a way to get #1 working. I think its supposed to work now... perhaps a bug?
Comment #69
mondrake@jenlampton - I tried
'#type' => 'link__pager__next'before wrapping up patch in #65 and can confirm it produces no output (with #title and #href though, not with #text and #path).#2005970: In renderable arrays, #type should provide a #theme suggestion, similar to how drupal_prepare_form() works related maybe?
Comment #70
thedavidmeister commented#69 - yeah, that issue is related. It relies on cleaning up a lot of #type/#theme namespace conflicts in core though. It could also do with a re-roll to handle '__' syntax suggestions.
We also need to make sure that the #pre_render for #type 'link' (or equivalent processing function) handles all the relevant sanitisation and other processing of $variables before the theme suggestion starts doing things assuming they've been processed as a "link". #1985974: Make l() optionally return structured output is related to that bit.
Comment #71
thedavidmeister commentedmaybe related #1751194: Introduce hook_theme_suggestions[_HOOK]() and hook_theme_suggestions[_HOOK]_alter()?
Comment #72
thedavidmeister commentedJust putting it out there, one of the reasons that theme_link() was removed was that in like one or two years of people asking for a use-case for needing a template override across various issues, no good examples came up.
Do we actually need theme suggestions for pager links, or would adding the classes "next" and "pager" for theming and contextual information be enough (keeping in mind that the structure of links can be altered with hook_link_alter)?
I've never done this before with pager links so I don't really know what the goal of the pager suggestions is.
Comment #73
mondrake#72 - neither am I, was just following the patch upstream. IMHO, 3-nested theme suggestion for pager links seems overkill, and core will not implement any of these, falling back on the link type.
+1 for the proposal in #72. I do not think we need to pass scope in the link classes though, as that's already in the wrapper attributes. We may want to keep the $element, $interval context to be passed to hook_link_alter though.
I was just wondering if anything like below may make sense??
Comment #74
jwilson3@73:
Let's say As a themer, I want to replace the "next" pager link with a big fat ugly IMG tag of an arrow (for argument sake).
to do that I have to check *every link in the site* inside my theme_link_alter() function, to test to see if $options['pager_context'] exists, and if it does, if $options['pager_context']['link_type'] is "next". Thats two additional conditionals for every link in the site.
I'm no perf whiz, but that sounds sub-optimal, compared to providing a theme suggestion once, having drupal check once to see if that theme suggestion was implemented somewhere, and calling that theme suggestion implemented in my theme once.
Comment #75
jwilson3i've marked the sister issue #1778990: Merge theme_pager_link*() theme functions into theme_link() as closed wont fix for now, since we're discussing what's the best way forward on this issue.
I'm really sad to see theme link go... I guess I dont understand the underlying reason why its going away.
Its obvious that pagers are a subset of links, but without having theme_link to depend on for suggestions, I think this means that we almost *have* to retain something like theme_pager_item().
Comment #76
mondrake@74:
True. But in this specific case, as a themer, you will most probably use an alternative CSS weapon like e.g.
Comment #77
jwilson3Hrm. Touché.
=)
Another thing to keep in mind, is a progression towards dream markup.
Take for example comment #3 from mortendk: #1912608-3: Update pagination markup for new CSS standards and improved accessibility
I suppose, in an ideal world a Twig themer might just implement the pager.html.twig file in his theme, and do any changes there.
Comment #78
thedavidmeister commented@jwilson3 -
"have to" is too strong - I don't think your use-case warrants a theme override OR an alter. A CSS based image replacement is faster than both an alter and invoking the theme system and is a much better way to separate content and presentation, it's also closer to what is being pushed in the "dream markup" discussions for D8. Using an alter is measurably faster than a theme override, see #1922454: Gut l(), fix theme('link'), have a working framework for consistently generated links inside and outside of Twig for some profiling.
Another option would be to use hook_element_info_alter() to set an extra #pre_render for #type 'link' which would allow you to avoid running your checks against every link running through l() and limit it to render arrays that are expecting to undergo extra processing, by design.
I'm pretty sure you still can implement theme suggestions for pagers if you want using the array syntax rather than 'foo__bar', but the issue is that the preprocessing of variables done for #type link will have to be done in the override, they won't be provided automatically, which leads to...
It was never really there, it had security holes in it in D7 #1187032: theme_link needs to be clearer about saying not to call it directly and didn't do other processing that l() did for "active" class and such. This was rectified only very recently in D8, by making it call l() directly but the performance hit of using theme() over l() or #type 'link' was considered excessive. Using #type 'link' and implementing your own sanitisation in a theme suggestion overriding it is still easier in D8 (just call l()) than it was in D7 using #theme 'link' (can't call l() because l() called theme('link') sometimes so you had to copy and paste the relevant logic from l() manually into the preprocess for your theme suggestion).
So, to be clear, the existing suggestions based on theme 'link' have always been a bit broken in that the base hook wasn't correctly preparing the variables it was passing to the templates and I doubt many people even realised this.
It also wan't compatible with #type 'link' at all, you couldn't do array('#type' => 'link', '#theme' => 'link') without PHP throwing errors, for example, so it wasn't compatible with element_info() implementations. While this problem is solvable, there's more to consider.
Well... in D7, doing just about anything related to theme('link') overrides or preprocessing (which is always required if you want to correctly prepare your link variables as per l()) led to l() calling theme('link') for every single link on the site whether it was relevant to the current link or not, which led to a performance overhead quite significantly larger than implementing a single alter for every single link on the site. What you're describing is not at all how the theme system worked for links in D7 and is only how it worked for about a month or so in D8, and the D8 implementation was not "drillable" or Twig based any way and nobody seemed to be actively working on fixing that in a performant way AFIACS (there were two issues open that I know of, but they both seem stalled on API architectural issues or performance).
There's a general movement at the moment (which probably won't be complete before D8 launches, but is well on its way) to get all the theme functions into Twig templates. When you think about #theme 'link', imagine it not as a relatively "light" function that is invoked (albeit with the overhead of the theme system doing it's "magic" and preprocess phases) but as a full-blown Twig template containing a single tag - which in many people's opinion is total overkill.
For larger templates this Twig conversion is great and usually represents no more than 0.5% performance overhead per template, for small theme functions that generate a single tag, the Twig template represents a much larger % performance overhead (like 10-20%) for no extra flexibility in what can be achieved over an alter on the simple renderable element used to generate the single tag. The nature of the smaller templates is that they are also called many more times in a page than larger templates (like, hundreds of times for links) so that larger % hit is also a larger % of the total page render time. For example, converting #theme 'html_tag' to #type 'html_tag' shaved nearly 4% of the *total* page load time for the front page on a fresh Drupal 8 install #1825090: Remove theme_html_tag() from the theme system.
Using #type -> #pre_render/drupal_alter() -> #markup is essentially guaranteed to be faster than anything run through theme() and for small (single tag), very commonly rendered HTML elements we have to seriously consider whether the theme system is worth what we pay for it.
There's also an argument that the theme system is very "cluttered" with many unnecessary hooks that all do the same or very similar things #1595614: [meta] Remove all the theme functions and templates in core that simply output a link. Replace with #type 'link' render arrays and so if not for the sake of performance, for the sake of simplicity and learnability we should be constantly re-assesing what we really want to build templates for and what could be consolidated/removed/done differently - #1833920: [META] Markup Utility Functions.
Comment #79
thedavidmeister commentedAbsolutely. I don't see why we need suggestions for pager links on the level of individual links if we have a perfectly good pager template wrapping them all (with associated preprocess function that could modify links in a targeted fashion).
Comment #80
mondrakeNot sure discussion landed yet, nevertheless a re-roll attached with #73 implemented and keeping up with #2013094: [policy adopted, patch needed] Stop saying '@see template_preprocess()' in every twig file
Comment #81
siccababes commentedI reviewed this patch, and it seems just fine. After I downloaded the patch, I created four articles and changed the page limit to three. I think this patch works!
Comment #81.0
siccababes commentedRemove sandbox link
Comment #82
thedavidmeister commentedThe discussion about removing __ style theme suggestions with a base hook of 'link' should be a separate issue as it will effect more than just pagers.
Comment #83
mondrakeRe-roll needed because of #2027031: [Change notice] Move views_theme_functions() to ViewExecutable method.
Comment #84
mondrakewas RTBC before
Comment #85
mondrakerelated #2030293: View preview is broken in UI if a pager has to be displayed
Comment #86
thedavidmeister commentedI take this back, it doesn't require a new issue. There are no 'link__' suggestions currently in core, only pager_link__ and menu_link__
Theme suggestions for 'link' would be as useless/broken as theme_link() itself was in D7 (if not more), I don't see any reason/use-case to try and support them.
I believe that trying to introduce a link__ that didn't previously exist would be a mistake, and #type 'link' is the correct implementation here as per #1595614: [meta] Remove all the theme functions and templates in core that simply output a link. Replace with #type 'link' render arrays.
The patches from @mondrake are good in this respect :)
Comment #87
catchYes I think this is fine. There's no flexibility lost that can't be had via other mechanisms, and it's not needed in the majority of cases here anyway.
Committed/pushed to 8.x, thanks!
Will need a change notice.
Comment #88
mondrakeThere are two notices already
Removed theme functions
and
theme_pager functions now use theme suggestions (theme_pager_link__*) (this one is now totally obsoleted).
Shall we edit the existing ones or create new ones?
Comment #89
mondrakeuntagging manual test
Comment #90
catchChanging the existing ones sounds great.
Comment #91
mondrakeSee
https://drupal.org/node/1795832/revisions/view/2628244/2745697
and
https://drupal.org/node/1819788/revisions/view/2409756/2745691
Comment #92
mondrakeJust noticed a small error in views.theme.inc
Follow-up issue #2030817: Wrong link_type passed in link's pager_context in views.theme.inc
Comment #93
jenlamptoncross post added tag back, removing.
Comment #94
star-szrRevised change notices look good to me, thanks very much @mondrake!
Comment #95.0
(not verified) commentedtest steps