I'm working to fill enhance the Comparison of Layout editors wiki, and am wondering about one particular aspect:

Allow different Features to each specify elements (blocks, etc.) to be displayed in a particular layout such that, e.g., home page content is the sum of blocks supplied by several optional modules.

I've often desired this ability as a distribution developer so that, for example, you could define a frontpage panel and have optional feature modules shipped with the distro add content to the frontpage, without all being dependencies of the module that defines the frontpage panel.

Is this possible through the Features export UI? Would adding this ability be a major level of work?

Alternatively, I suppose as distro devs that we could use hooks for this rather than making it possible through the UI. Another option might be the Features override module.

Comments

merlinofchaos’s picture

If it's exportable, there's an _alter() hook. You could then add panes via that alter.

Caveats:

1) It stops working as soon as they modify it (i.e, new things will not add to the front page because it's now overridden in the database)
2) It's a little tricky to manually add panes to a display but it's not impossible. There's an add_pane() method on the display object that I think can help.

Would that be sufficient?

ezra-g’s picture

Would that be sufficient?

It sounds like that would be helpful for developers, but it would really be ideal for site-builders to be able to add content to an existing Panel, similar to the way one can incrementally add blocks to a page with Context.

Perhaps one way to expose that in the UI would be Panels-specific support in http://drupal.org/project/features_override ?

ezra-g’s picture

nedjo’s picture

The Open Academy distro is a useful reference here. Panels is the main page building tool, with each feature both providing pane content and including a panels page layout.

In order to present information provided by other features, the news feature's panels page includes "Upcoming events" and "Recent publications" panes. This works and - drawing on the Panopoly distro - provides a great UI for layout editing, but raises two issues:

  • If the news feature is enabled but either events or publications is not, the news feature shows in an overridden state, because its panels page is incomplete (lacks panes).
  • There are barriers to enhancing the featuers because anyone wanting to use this same approach would need edit access to all existing features, to be able to patch them each time a new block display need arises.

Either a custom form_alter() or introducing a dependency on Features override might work, but it's also worth musing about how this could be addressed directly in ctools or panels. The specific question might be: can we export just a pane setting in a way that references the panels page and region it should belong to? The general question might be: can we export a sub-node of a ctools exportable? But this second question is straying into territory already mapped out by Features override, wit a lot of accompanying complexity.

ezra-g’s picture

Issue tags: +commonslove

Adding the 'commonslove' tag.

nedjo’s picture

Title: Allow Feature module exports to add Panes with Existing Panels » Allow Feature module exports to add Panes to Existing Panels

Been thinking a bit more about this problem.

The need seems to include both specific and general changes:

  • Make a specific alteration to a particular existing panels page. Example: add a "upcoming events" block (provided by one app/feature) to a "news" node type template sidebar region.
  • Make a sitewide alteration. Example: add a login block to a sidebar region of all site pages (including panels pages).

Panels excels at variation but makes consistent sitewide elements relatively challenging. In different ways Panels sections, Panels everywhere, and Page manager existing pages try to mitigate.

If we itemize what we're trying to achieve here, we need:

  • Pane identification: which pane should be added?
  • Pane configuration: what data should be passed with the pane?
  • Region: which layout region should the pane be placed in?
  • Pages: which pages and variants should the pane be added to?
    If we're trying to support any sitewide panes, this item is going to be tricky, since potentially we'd need to add to all pages, but only if they support a given region (or a region mapping).
  • Optional enhancement: panes enhance existing pages if they're present but don't create dependencies.
  • Intuitive UI: both admins creating features can easily place panes and site admins using them can easily move them around.

Anything we do here is going to be up against some pretty severe UI challenges. The Context module's in place editor is instructive. If there are multiple contexts placing blocks on a page and you're trying to edit the blocks using the in place editor, you have to first intuit which context to edit and then, when you're editing it, you have access only to its blocks. We're going to be up against the same kind of problem if we're trying to enable intuitive editing of panels that contain elements that come from different sources.

Here are some possible approaches--not sure how much sense they make.

  • Each page variant has multiple content objects. On variant creation a default content object is automatically created but new ones can be added. The content objects aren't individually edited, but each pane is assigned a content object. On page generation, the multiple content objects are merged. The default content object is exported with the variant, while additional ones can be exported separately.
  • Elsewhere, not in Panels core, a special case page sitewide page is created, maybe using Panels sections. Content objects added to this page are also used in altering all other panels pages, inserting their content in the corresponding region (using a region mapping that's drupal_altered to allow for equivalent regions in different layouts).
nedjo’s picture

For sitewide panes in apps and/or distributions we could simply use a convention, like maybe: Include in all panels pages a mini-panel (empty), 'sitewide'. Alter this mini-panel to add panes site-wide.

sdboyer’s picture

this is, in essence, the key remaining functional architecture problem with panels. i've been bouncing it around in my head for years, so it's nice to have an issue. nedjo's points in #6 are a good starting point:

Make a specific alteration to a particular existing panels page. Example: add a "upcoming events" block (provided by one app/feature) to a "news" node type template sidebar region.

this is a difficult, but mostly-solveable problem. your list of needs of requirements is basically good (pane ident, pane conf, region, positioning), but does become quite a bit more complicated when factoring in managing changes via panes that have been injected via a hook. mess with that panel, and things can get messy, because pane positions are assigned sequentially and we don't do a very good job of keeping track of those sequences in a way that makes such injection friendly. the other tricky thing is dealing with the situation where you don't know the layout (and its region names) into which you are injecting. solving these things in a one-off way is not especially difficult, but solving them in the main module itself is not so easy.

Make a sitewide alteration. Example: add a login block to a sidebar region of all site pages (including panels pages).

this is really *only* possible if we're talking about things that pass through page manager. and even then, it can be a little sketchy. since the core panels engine is detached from client applications that use it, we can never really make a guarantee that "everywhere a panel is, these panes will be injected at the right spot" not only because of the problems listed above, but because the safest way to "inject everywhere" is to use an alter hook that's invoked out of the core engine, not one of the applications. which means it REALLY goes into every panel...and that might have unintended consequences.

mostly this is me whinging, though. what would be most useful for me in figuring this out is mapping out the possible (and then the realistic) use cases that need to be satisfied. with all the different layers to the system, it's tough for me to keep priorities and the use cases straight in my head while down in the plumbing :)

Each page variant has multiple content objects. On variant creation a default content object is automatically created but new ones can be added. The content objects aren't individually edited, but each pane is assigned a content object. On page generation, the multiple content objects are merged. The default content object is exported with the variant, while additional ones can be exported separately.

i need this described a little more, i'm not completely zeroed-in on the idea. i will say, though, that we've generally considered an automated merge of anything a non-option; deciding how and when your content displays cannot be a heuristic process.

Elsewhere, not in Panels core, a special case page sitewide page is created, maybe using Panels sections. Content objects added to this page are also used in altering all other panels pages, inserting their content in the corresponding region (using a region mapping that's drupal_altered to allow for equivalent regions in different layouts).

yeah, i've thought of things a bit like this as well. really, it could just be a mini-panel. we could solve one case very easily with something like that: the one where we want to add panes before OR after all the other panes that have been placed into a given region. that can work great with not too much effort, but is useless for the case where you want to splice a pane in between two others.

nedjo’s picture

On the topic of site-wide elements, I've been looking at sun's clever code a couple of years back for allowing panels to use theme's regions in #680064: Control theme regions.

I'm looking at whether I can rework the Open Outreach distro to use Panopoly in #1664956: Make Open Outreach Panopoly-based. Currently Open Outreach uses Context for block placement. I don't see combining Context with Panels--too much overlap. So figuring out sitewide panes is an immediate need.

Also opened this related issue on Panopoly: #1642308: Define best practices for block placement in Panopoly-based distros or sites.

i need this described a little more, i'm not completely zeroed-in on the idea.

What I was picturing is that the content of a given page variant or minipanel is always handled (edited, displayed) as a single whole, but stored as distinct subsets. So, when adding or editing a pane, you can select in the pane's settings whether it should be assigned to the default, um, set of content or to a different or new one. You never have an interface for viewing or editing a single set of content for the variant, but when saved the distinct sets are saved into separate arrays and, yes, on load those arrays are merged, with pane weight ensuring correct ordering.

sdboyer’s picture

On the topic of site-wide elements, I've been looking at sun's clever code a couple of years back for allowing panels to use theme's regions in #680064: Control theme regions.

hah, i hadn't seen that before. interesting. yeah, there's no reason that you couldn't use a simple custom layout like that to inject things into the theme's regions like that. only now, with d7, injections could be even more far-reaching thanks to hook_page_alter().

I'm looking at whether I can rework the Open Outreach distro to use Panopoly in #1664956: Make Open Outreach Panopoly-based. Currently Open Outreach uses Context for block placement. I don't see combining Context with Panels--too much overlap. So figuring out sitewide panes is an immediate need.

i figured that might be the goal here :) very excited to hear that. feel free to ping me in irc anytime to discuss it. and yes, probably too much overlap to make them work well together.

So, when adding or editing a pane, you can select in the pane's settings whether it should be assigned to the default, um, set of content or to a different or new one.

ah ok, i think i got it now. and here's my thought - maybe we should look at this in the other direction. rather than trying to build independent panels that later get something injected in from a master via obscured logic that is non-obvious at edit-time (and where that logic is inherently funny on the master, for all the sequencing and region-matching issues i pointed out in #8), maybe we should let the masters be stupider and leave the hard work of sequencing up to the individual panels. which would mean individual panels need to be aware of what's going to be injected at edit-time, so that a human can make intelligent decisions about how to place those elements.

that does get a bit off from your goal, though. it sounds like you're aiming for pane instances that exist independent of any single panel, and can be reused/edited across a number of different panels. yeah, that idea has been bounced around for a while, and it's a good one. the tricky bits are UI/naming and exportability. on the former, we'd need a UI for 'detaching' a pane from the particular panel its on and placing it in a general storage bin, then a way of making things in that general storage bin also available to the 'add content' modal. not impossible, just tricky, since it's yet another layer of abstraction and duplication in an already-confusing interface.

on the latter...well, it's even trickier, as we'd need names (or, i would dramatically prefer, uuids) for those reusable panes, and then we'd need to be able to transparently merge them into the load process. and that would need to work for any combination of the pane OR the panel being in code OR in database. which would also be slightly complicated by the fact that we'd need to normalize {panels_pane}.panel and {panels_pane}.position into a new table, {panels_pane_positions} which would have those two columns plus pid and did in order to allow joins into {panels_pane} and {panels_display}. this would all be necessary since ordering and region position would need to be tied to the display, NOT to the pane. these are not necessarily insurmountable problems, but would require a lot of work and testing.

of course, if those 'sitewide' panes are stored in the database, we lose the nice convenience of being able to inject the panes via a hook that gets them onto all panels sitewide. probably. bleh. really depends on on whether we're optimizing for developer or maintainer ease.

sdboyer’s picture

nedjo’s picture

@sdboyer: thx for your thoughts here. I haven't got any further in puzzling through these questions. I'm not up enough on D8 developments to know how these questions are shaping up. If in D7 there's a tension between site-wide theme regions and other page-specific regioning systems - Panels but also Display suite and others - presumably a challenge of a D8 layout system is to reconcile the two.

nedjo’s picture

Re sitewide elements I opened #1737024: Add a "sitewide_sidebar" minipanel.