Closed (fixed)
Project:
Panels
Version:
7.x-3.4
Component:
Miscellaneous
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
7 Jan 2011 at 11:59 UTC
Updated:
20 Dec 2014 at 20:34 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
sharpbites commentedI have just noticed the order doesn't depend on when rows or regions are created either.
Comment #2
pazzypunk commentedI have this question too.
Comment #3
sharpbites commentedI didn't notice the first message got broken.
What I was trying to say is that I wanted to use Views in combination with Views exclude previous [1] to create blocks of content listings, and I would like blocks appearing higher in the panel to execute first.
[1] http://drupal.org/project/views_exclude_previous
Comment #4
paranojik commentedWe had exactly the same use case as in #3. As we discovered there is currently no mechanism that would allow us to set the order in which pane content is rendered. Rendering doesn't even follow the visual layout. but the order in which panes were entered into the database.
The attached patch allows you to set pane weights and orders the panes in ascending weight order before rendering.
Comment #5
sharpbites commentedThank you paranojik!
If we need this again I use your patch and update here the results.
Comment #6
merlinofchaos commentedContent already has a 'render last' or 'render first' property, which you can use to ensure that content that needs to know what's already rendered can do so. It seemed unlikely that fine grained weighting of render order would ever be needed, so these 2 settings were deemed enough.
Controlling render order is so rarely needed that I really don't believe it should be in the UI. That simply adds confusion to an already confusing interface.
These two flags will have to be enough.
Comment #7
paranojik commentedCan we at least introduce a new hook, so this could still be possible to achieve.
Comment #8
paranojik commentedCan we disscuss the above mentioned possibility?
Comment #9
Letharion commentedWhat is the use-case for controlling the render order? Since it is currently considered so rare, I don't really see why there should be a hook either. While less of a burden, that would still add to code complexity.
I believe that this is going to be a case where you should just write a ctools plugin to wrap the content you need to control the order for.
But since you want to discuss paranojik, please give a few examples of use-cases.
Comment #10
paranojik commentedThe use-case was mentioned in #3. I would like to use panels to layout a number of blocks (e.g. in a two column layout). Each block displays (let's say) 10 articles with a specified tag (taxonomy term) ordered by post date. Because of the nature of tagging, articles would usually appear in several blocks so I use Views in combination with a similar mechanism mentioned in #3 which is a view filter that modifies subsequent queries to exclude the articles that were already loaded (by a query for the previously loaded articles block).
Now, if I insert blocks A, B, C and D (in that order) on a panel, they get their unique database IDs -pid (let's say they are 1 for A, 2 for B, 3 for C and 4 for D). When Panels prepares content for display it loads these block in that order (in order of increasing pids).
So I have the following layout:
A | B
C | D
Everything is fine now. Block A loads before block B (and C and D), so it contains the newest articles. Let's say block A and C share 1 article (because it's tagged so). When block C loads and the view for block C fires it's query, we have the information about the articles loaded in A, so we can exclude them. The article which would (without the use of this extra filter) appear in block A and C, now only appears in A.
Let's reorder those blocks:
D | C
B | A
What one would expect to happen is that now block C would contain the most recent articles, but because these blocks are rendered in the order of their increasing pids, the result is exactly the same as in the previous example.
If Panels don't provide a way to define the order in which content is rendered this kind of functionality is very hard to achieve. The Panels admin interface is über-powerful and also very very visual (you can define all kinds of layouts, insert all kind of content, preview,...), but from this perspective also somewhat misleading.
Comment #11
Letharion commentedSo that's one usecase, are the any others? Implementing this for solving a single use-case, still doesn't seem right. If I had just this use-case, I would pass the "previously used" taxonomies on to the next pane, as an argument that the View used for excluding.
And I think that's the main argument against this, we have a general and flexible system for solving a great number of use-cases, and in my opinion, this one too. It then seems strange to implement additional functionality, that is so specific.
Comment #12
merlinofchaos commentedI agree, the proper way to handle this is with a context object. If you can do it with a single view then everything probably just works as if; if not you might need something custom, but it sounds like you've got some custom stuff going on anyway.
Comment #13
osopolarI have a Search API view and use the Facets API blocks. The view needs to be executed first, but currently the blocks are rendered first. So I'd like to use 'render first' for the view or 'render last' for the blocks. But as it is plugin based I can't use this options.
Is this just another usecase? Or is there a workaround - I use a custom layout plugin, changing the order in the layout-lugin-name.inc seems to not have an impact to the render order.
Comment #14
merlinofchaos commentedPerhaps hook_ctools_plugins_post_alter() will allow you to add 'render last' to the facet API blocks.
If they're truly blocks and not actual content panes, this is more readily done with hook_ctools_block_info for the module that owns the block. See the bottom of ctools/plugins/content_types/block/block.inc for all of the versions of this done for core. Possibly search api or something should already be doing this for those blocks so that they can always render last, which they almost certainly should.
Comment #15
osopolarThank you merlinofchaos for your help. But it does not work.
the logic for render_last is in panels_renderer_standard::prepare_panes(), right? There you have a $content_type = ctools_get_content_type($pane->type); and then you look into $content_type['render last']. But this is just the content-type plugin info and won't be influenced by the ctools_block_info. Is it possible to change prepare_panes to reflect the block info?
Your first hint with hook_ctools_plugin_post_alter() works, but I don't like it. Facetapi uses real blocks. So I have to change the behavior for all blocks to render last. If another module needs to render all blocks first there will be a conflict. I would like to see the code in facetapi, but I won't recommend facetapi to implement this behavior:
Comment #16
Letharion commentedthis has turned into a support request, and there is no patch, so this is active.
Comment #17
bigsyke commentedThis may also have something to do with the order you add content to panels. I redid my layout and all my Facets disappeared, or went off a different search pane.
Edit: I see that this was already stated.
Comment #18
danielnolde commentedThe original request is very valid and points to a very common problem, which is:
"ensure that pane content A is exectued after pane content B because B depends on A's results".
May i suggest panels maintainers try to be a bit more open to this request, since there have been already two quite common use cases been stated:
For this problem, there should be a solution. If it's accessible programmatically, its probably okay for many developers present in this discussion, but if there's a simple solution which can be made accessible to mere site builders, that way should be preferred, so, for example, a sitebuilder can actually build a facetted search result page based on panels without being forced to code. Introducing a hook to reordering (or probably generally altering) panel content before rendering should be simple to include. Introducing a render weight doesn't sound too complex, either. Don't you think? Again: The problem is a quite common one with several use cases often encountered by developers and power users.
If maintainers still won't accept peoples help to code this kind of solution into panels (i'd love to help/do it!), what would be the suggested way to solve the general problem or the specific use cases? If a hook or a weight is still out of question for maintainers, then please help us and tell us:
How can "render last" be injected programmatically to a specific block or view placed in a panel?
Above examples allow only for a whole class of ctools plugins (like "block") to be "rendered last", but not for individual instances of that class (like a particular block in a particular panel), or am im wrong here?
Again: A hook or weight would be right way to solve the problem.
Comment #19
danielnolde commentedMerlin and others.
The pane-type-wise "first/normal/last" rendering is _way_ too crude and to be honest seems like a uber-ugly workaround for something that should be handled more flexible and cleanly. Several people here need this finer grained control over pane rendering order and gave several good use cases. I am willing to implement that simple and very flexible hook based solution, so please consider this.
So: if i extend class panels_renderer_standard method prepare_panes to include a hook for rearranging pane render order (between lines 253 and 254), would that get considered for inclusion in panels dev branch?
cheers,
daniel
Comment #20
sdboyer commented@danielnolde - first/normal/last is a crude tool, but it was adequate for most simpler cases, and IS adequate for the case you cite in #18:
as the 'render last' capability allows you to ensure that B is placed after A perfectly well. having the 'first' option as well gives you another layer through which you can control this. ideally, as merlin pointed out in #12, this would be handled by a context object, but that's not always going to be the case.
when i rewrote the rendering system into plugins, it did occur to me that we might want to provide more granular control over rendering order (as it is fairly arbitrary at the moment), but we didn't have pressing use cases at the time. without a pressing use case, and given the difficulty of implementing any kind of UI for controlling this behavior, i left it be. so while there are cases for this, it remains tricky, because of your question:
changing rendering order at the level of the plugin is easy, but targeting a specific pane instance within a specific panel is tough, because most of the identifying information you would need to know the panel & pane instance is gone by the time you make it into
panels_renderer_standard::prepare(). for the most part, you'll have a display id and a pane id. and hardcoding renders the panel non-exportable. there are ways to do it, but it'd be mostly tricks.but i would accept a patch that met the following criteria:
Comment #21
danielnolde commentedHey Sam,
the criteria you define seem fine to me and exactly what i was planning anyway.
#context info: If only display id and a pane id are available as context information, that should suffice for most use cases. An implementation of that hook would have to look up more detailed information in the db with those ids, which is not the best way but not bad either.
#render-order:
Add-order: Sadly, i had some cases, where the "add order" which of course i used to define initial render order, was shuffled when exporting/using an panel via feature (i don't know how this happened, but that's what i observed).
Sadly, use case #18 is _not_ solvable with first/last-mechanism, since this is applicable only by type, not by instance, and all the panes that have to be ordered ni a certain way are both of the same type. Only way to solve this with first/last would be to custom-duplicate a ctools content type, which seems to be the utterly wrong approach to achieve this goal/use-case <;)
So, great: I'll care for a simple but flexible hook-based solution and i'll prepare a patch for this - Thanks, Sam for the input and cooperation!
Comment #22
paranojik commentedThis, is my first attempt. It's very simple and respects all points stated in #20. I'm just not sure about passing the whole display_renderer object as a parameter to the hook. Please give some advice on that.
Comment #23
paranojik commentedAnybody got a chance to look at this?
Comment #24
das-peter commentedOnly thing I found: Inline comments require a dot at the end of the comment.
Hint: If you've a patch you'd like people take a look into - set the issue status to "needs review" :)
I'd say this is pretty straight forward and provides the necessary preconditions to achieve the goal with a contrib module.
Comment #25
kars-t commentedExcept the missing "." the patch seems clean and a nice addition.
Comment #26
paranojik commentedAdded missing dot :). Patch still applies.
Comment #27
kars-t commentedOkay I say this would be a great addition and RTBC it.
Comment #28
merlinofchaos commentedCommitted and pushed.
Comment #30
lorenx commentedsorry to reopen this issue but... is it possible that the patch provided here isn't in the 7.x-3.3+41-dev release yet?
thank you.
Comment #31
kopeboyIs this included in a stable release? How to know it? (Sorry for reopening)
Came here because I can't get Facets to work in Panels
Comment #35
Andreas Radloff commentedFor anyone who wants to render panes in the order they are displayed (or rather, the order regions are defined) in the layout, this is how you can do it using the drupal_alter hook implemented in this issue and present in the 7.x-3.4 version at least:
Thought I could post it here as an usage example. Closing since it works.
Comment #36
proteo commented@Andreas, your function works wonderfully, it saved my day. Many thanks!