Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Suggested by catch: #1805996-15: [META] Views in Drupal Core
Is there an issue for this stuff? Views should be able to make the assumption that people use #attached properly or have to fix their code.
+ /**
+ * Start caching javascript, css and other out of band info.
+ *
+ * This takes a snapshot of the current system state so that we don't
+ * duplicate it. Later on, when gather_headers() is run, this information
+ * will be removed so that we don't hold onto it.
+ */
+ function cache_start() {
+ $this->storage['head'] = drupal_add_html_head();
+ $this->storage['css'] = drupal_add_css();
+ $this->storage['js'] = drupal_add_js();
+ }
Comment | File | Size | Author |
---|---|---|---|
#77 | vdc-1811828-77.patch | 28.86 KB | tim.plunkett |
#73 | drupal-1811828-73.patch | 28.82 KB | dawehner |
#73 | interdiff.txt | 4.3 KB | dawehner |
#65 | drupal-1811828-65.patch | 27.8 KB | dawehner |
#65 | interdiff.txt | 3.05 KB | dawehner |
Comments
Comment #1
dawehnerIt's currently certainly problematic because views is not using an render array to render itself, so where should, for example a style plugin, attach it files to.
Comment #2
tim.plunkettAs a short term, instead of doing
We could do
Comment #3
dawehnerI'm not really sure how we get $whatever. If everything is using render arrays, this should work automatically right?
If we don't use render arrays we could store the css/js on the view object and then set it in the returning render array.
Comment #4
moshe weitzman CreditAttribution: moshe weitzman commentedWould be fantastic to fix this for D8. I'm happy to help if folks have questions. In general, I think you have to pass a $build element around and let modules/plugins enrich it with css/js/markup, etc. I guess build could be right on the $view object
Comment #5
dawehnerAssign to myself.d
Comment #6
dawehnerSlightly related issue: #1748164: Use #attached to add all CSS and JS
Comment #7
dawehnerEven though if we store the build array/the attached css/js we can't really figure out caching
perfectly.
Here comes an example: A view with node teasers, which adds a special css for the teaser. To figure out caching,
at least from my perspective you have to know each css/js files and therefore the only approach is recording the css/js.
One thing we can do is to attach this css/js in the outer render element.
So here is a patch.
I'm totally not sure about this piece of code.
Comment #9
dawehnerGet rid of the problem in the patch.
Comment #10
tim.plunkettThese lines are really confusing already, can we instantiate $this->view->attached['whatever'] as an empty array not in this line?
?
JS/CSS
Is the $render variable used later in the function? If not, might as well avoid the temporary variable
Comment #11
moshe weitzman CreditAttribution: moshe weitzman commentedDon't know how plausible it is, but the end goal should be to not render to HTML ourselves, but rather to pass a render array back to the caller that has a #theme on it. Let Drupal do the themeing later. We have #pre_render if we need to do some processing before we themeing occurs.
Comment #12
tim.plunkettOkay, I'm working on #11
Comment #13
tim.plunkettThis required a lot of changes that would otherwise seem out of scope, but they're all positive ones:
Comment #15
tim.plunkettSo we JUST introduced the title area, and already it's breaking things.
Comment #16
moshe weitzman CreditAttribution: moshe weitzman commentedAwesome!
+ $vars['rows'] = drupal_render($vars['rows']);
. Calls to drupal_render() are a code smell. I don't really care when they happen in Views UI such as in preview() method, but ones that happen inside of regular page processing are an issue. Specifically, the one in template_process_views_view() should be moved to the arender($content)
orrender($rows)
in template file(s).Comment #17
dawehnerIf we have problems like this we should better set the title on pre_render? It feels smelly to require such hacks :(
Comment #18
tim.plunkettYeah, that hack should definitely be revisited before commit, I'm just trying to get tests to pass for now.
This should fix the bugs, and address #16.
Comment #19
dawehnerHere are some points why building up an render array might not be the best idea.
They sure are sort of influenced of the problems we had with converting views in drupal 7 to render arrays, and failed especially in terms of backwards comparability, but sure this IS the time when we can actually do it right, whatever this ominous word means.
So please let discuss that.
If you do really late rendering of a view, in the global page array, you can't throw away the view and all the other objects containing
to a executed view. This might be easy for a simple view page, but if you have a huge and complicated frontpage with a slideshow here, and a teaser-list there, at least from my point this could be problematic. Please correct me if i'm wrong
We might be better put this into hook_library, i'm not sure what common practise is for single css files.
I really like that!
Comment #20
tim.plunkettThe rest of our CSS and JS should be turned into libraries as well, but that should be another issue.
I think that since render arrays are still "the right way" in D8, we should wait to see what happens. If anything, when the "new way" gets adopted, we'll be able to convert from render arrays to that, like the rest of core.
This uncomments those tests and cleans up a bit of extra code.
Comment #21
tim.plunkettOh, I forgot I still have to take out that one hack, reassigning.
Comment #22
dawehnerIn order to have a proper render array for a view, and based on that nice css/js
caching we should have a proper render array, which have stored at least the following points
As we would have memory problems storing all the views objects during the full request,
we came up with using the view element, which already exists in drupal 8.
It looks like:
The pre_render array will set a $view->build (or similar) which can be altered by any object
during the lifetime of a view. Style plugins for example would add additional CSS/JS files,
and cache plugins #cache.
On top of that we could convert the internal rendering of the view, but this is simply not needed for this issue.
Comment #23
tim.plunkettI think this could go in as is, and #22 could be a follow-up. This already passes tests. But I leave that call to @dawehner.
Comment #24
tim.plunkettForgot interdiff
Comment #25
tim.plunkettFor the next reroll, change
in ViewExecutable::render()
This adds at least 90 seconds to the test run, so this SHOULDN'T go in until #22 is done.Apparently, the branch tests got slower too? They're up to 7.5 minutes...
Comment #26
aspilicious CreditAttribution: aspilicious commentedPerforms
Comment #27
dawehnerFixed #26
This is currently in the state work in progress.
Things which are known to be broken
The positive part: At least late rendering of the page view works fine.
Comment #29
tim.plunkettThis should be public now
= &$element, please
This should just be reverted
Whaaaaat?
dpm() ;)
Okay, that's kinda cool
I don't understand this
I think this
Except all of the weird "special_block" parts, I like this too
What's with the views_pre_render_view_element? Why isn't that part of the regular #type => view stuff?
This could use a comment.
Comment #30
dawehnerI really tried hard but it seems to be impossible for me to either have title on blocks or pages,
but beside of that it's working pretty fine, so if someone has an idea, i would like to hear it!
@tim
Thanks for your long feedback, i corrected all of them, added comments or we figured out on IRC earlier.
Comment #32
xjmComment #33
dawehnerHere is a rerole against 8.x
The reason why drupal_set_title doesn't work in Page.php is because template_process_page which loads the page title is executed before the page.tpl.php which
calls render($page['content']) which actually executes the view.
Comment #35
moshe weitzman CreditAttribution: moshe weitzman commentedOh right. For now, I think we give up on late render and just do late themeing. We still get the advantage of properly using #attached. Is this doable?
Comment #36
dawehnerSure, but you will simply not being able to do caching as it is supposed to be, but sure this is still an improvement.
I will work on that tomorrow.
Comment #37
dawehnerFinally managed to get it running without breaking again. PUH!
Comment #39
dawehnerI'm really not sure why the CacheTest does break, but maybe someone else has an actual idea.
Comment #41
moshe weitzman CreditAttribution: moshe weitzman commentedCode looks good to me. I dont know much about the test fails other than it would be good if they went away :)
Comment #42
catchBumping to major, the diffing of the global CSS before and after is really fragile, and it's going to be completely incompatible if we end up doing subrequests, and/or if drupal_add_css()/js() get refactored significantly (which seems likely at the moment).
The patch is collecting things from #attached, but it's not removing the handling of the globals yet?
Comment #43
dawehnerLinked a new issue which came out of the discussion with catch: #1830588: [META] remove drupal_set_title() and drupal_get_title()
Comment #44
dawehnerups.
Comment #45
moshe weitzman CreditAttribution: moshe weitzman commentedNice. We could also add ['#attached']['#block-title'] and that would solve our other problem. #block-title would be consulted when processing a top level block item.
Comment #46
dawehner#39: drupal-1811828-39.patch queued for re-testing.
Comment #48
nod_tag
Comment #49
dawehnerThis is not the full interdiff due to
but hey this passes the tests!
Comment #51
dawehnerLet's fix the notices.
Comment #52
tim.plunkettUnless @dawehner wanted to do more with this, I'm very very happy with this. Let's get it in!
Comment #53
dawehnerOnce that part is in, i would like to work on other issues which will allow lazy-execution of a view.
Comment #54
catchI'm confused about this bit. If we're using #attached, then we can assume that everyone else is. If contrib or custom code isn't using #attached to add css or js for context-specific stuff then it's broken - especially since we'll be doing our best to eliminate all calls to drupal_add_*() if not the functions themselves this release.
Rest of the patch looks good though - is it easy to remove the global CSS/JS handling or should that be a follow-up?
Comment #55
dawehner@catch
Once we have a proper rendering, like #1811828-33: Use #attached to find the css/js of a view tried to do, we don't need global css handling,
but until then it seems to be, that we sadly still need this kind of behavior, see #1811828-7: Use #attached to find the css/js of a view.
I'm happy with getting the other blockers into to be able to convert views to late executing.
Comment #56
catchThe comment in #7 is talking about node teasers. If you have node teasers, those are renderable arrays, which can have #attached set, and there's functions in common.inc to get the #attached from nested render arrays.
Comment #57
moshe weitzman CreditAttribution: moshe weitzman commented#51: drupal-1811828-51.patch queued for re-testing.
Comment #58
dawehnerRegarding #56
Not sure how we continue here, because to rid of the global handling we end up
with the render element, which is blocked at the moment.
I think the current patch is a step forward and will allow further improvements later.
Comment #59
dawehnerHey!
Comment #60
tim.plunkettI agree.
Comment #61
sunI think it's perfectly fine to make progress in smaller steps.
However, let's make sure to create a follow-up issue then.
(Alternatively, we could also keep this issue open, but that most often turned out to be not a good idea.)
Comment #62
dawehnerSure, here you go: #1849822: Convert (HTML) view rendering to a render array
Comment #63
webchickCatch seems to have his fingers in this particular pie.
Comment #64
catchI don't understand why #1849822: Convert (HTML) view rendering to a render array affects the global js/css diffing, that seems to be about making the view itself return a render array?
Comment #65
dawehnerAfter a short talk with catch i think this is the way to go: kill a lot of code.
Comment #66
moshe weitzman CreditAttribution: moshe weitzman commentedNice work.
It isn't too clear what 'the head' means
I see that we call render($rows) in the views-view.tpl.php so i'm surprised to see a drupal_render() call in preprocess as well. Ideally we render within the template and not in preprocess.
Comment #67
tim.plunkett@moshe, to answer your second point, we make a copy of the row values, and render that, to see if they're empty or not.
The original values are not rendered, and passed along.
Comment #68
catchYes this is more like it!
Comment #69
catchComment #70
moshe weitzman CreditAttribution: moshe weitzman commentedI think we are ready.
Comment #71
catchSorry one more question. Why would the hook_library_info() implementation depend on the configuration setting for js or not? I'd think we'd check that setting when actually attaching the js? hook_library_info() isn't cached, but there's an issue to do that, and if it was then changing the configuration setting would require invalidating that cache to avoid a missing library.
Comment #72
dawehnerWorking on fixing the comment in #71
Comment #73
dawehnernod_ suggested to add proper requirements to the hook_library entries
Comment #74
moshe weitzman CreditAttribution: moshe weitzman commentedBack to RTBC
Comment #75
catch#73: drupal-1811828-73.patch queued for re-testing.
Comment #77
tim.plunkettConflicted with #1818450: Introduce core token support in PluginBase class, straight reroll. Wait for green.
Comment #78
catchThanks for the re-roll. Committed/pushed to 8.x.
Comment #80
Dave ReidAn issue that was marked a duplicate of this was set to be backported to Drupal 7. I'm looking at how I can add #attached information to a view render and wondering if this in fact needs to be backported?
Comment #81
Dave ReidFiled new issue #1894736: Cannot use #attached to add general CSS/JS/Library to a View to discuss so I won't ping this issue anymore.