Using the new custom-homepage feature

Trying out the new custom-homepage feature: DEV: allow themes to render their own custom homepage by pmusaraj · Pull Request #26291 · discourse/discourse · GitHub :tada:

@pmusaraj I wonder what’s the best approach to add components?

  1. So adding the custom-homepage modifier enables the discovery.custom route and shows a default info alert, rendered on the custom-homepage outlet:

  2. I add a component to the outlet and it renders instead:

  3. However, when I add more than one component, I get an error:

    image

  4. I can add more components to other outlets though. Here’s a view with plugin outlets visible:

    image

So I wonder how the new outlet should work:

  • In a way, I wouldn’t need the outlet. I can just use the other available ones and limit components to the discovery.custom route
  • Though it seems I need to put at least one component on the outlet, otherwise the default alert is rendered? Putting an empty template there doesn’t work.
  • On the other hand, if I could add multiple components to the outlet, I wouldn’t need to have a route logic at all. Components would only show on the homepage because the outlet will not be available on other routes?
2 Likes

That’s not surprising?

Put a single template file here and use it to reference your Components in the Components folder (of which you can then have many)

<MyFirstComponent />
<MySecondComponent />
<MyThirdComponent />

Or whatever you want … just stick with one template in this folder?

1 Like

I thought it is because it works with other outlets? As on the screenshot above…

Oh sorry, you are right, it seems legal on Outlets (usually) to publish more than one template file in a single Theme Component (I was aware it handled clashes across Theme Components and plugins so they all get to render). Curious.

I guess though: why would you want to do that? You will have less control over the layout?

One template forces you to compose the entire layout in one go with however many sub-components you want?

The behaviour does appear to be inconsistent though …

If I build a custom homepage, I’d want to be able to render multiple existing components on it. And as mentioned, this already works when using other available outlets and limiting the components to the custom homepage route.

If I can only add one component to the particular custom-homepage outlet, and also need to add one to disable the default yield, then this actually restricts my layout control.

But why can’t you reference all those components in one template?

Oh because they are coming from different Theme Components?

I think we were talking at cross-purposes here.

When I say put all your (Ember) Components in the Components folder, I mean exactly that but in one Theme Component.

I think the crux of this is simply: “why does this outlet behave differently?” I get that you are trying to combine different Theme Components.

Yes, that’s the idea. I just used the plain text templates above as an illustration. E.g. I use Featured Lists. And I can render it on the outlet with these settings:

image

But when I want to render another one the same way I get the multiple connector error.

:+1:t4:

2 Likes

Thanks for testing this out @nolo and for the questions.

I didn’t know the answer to this either, but I looked and figured out roughly why. We recently introduced a distinction between classic plugin outlets and wrapper plugin outlets, in this PR from last year: DEV: Allow PluginOutlets to 'wrap' a core implementation by davidtaylorhq · Pull Request #23110 · discourse/discourse · GitHub

The wrapper plugin outlets are the ones that allow only one connector, the rest allow multiples. To illustrate, the current core plugin outlet code is this:

<PluginOutlet @name="custom-homepage">
  {{#if this.currentUser.admin}}
    <p class="alert alert-info">
      {{i18n "custom_homepage.admin_message"}}
    </p>
  {{/if}}
</PluginOutlet>

and it allows only one connector. But if I change the core outlet code to:

<PluginOutlet @name="custom-homepage" />

It will allow multiple connector templates just fine. We could make this change in core for this particular outlet, but this difference is more general. It does feel a bit opaque to developers, though, I see your point there.

Note also that multiple connectors have an ordering problem, afaik we don’t have a mechanism to decide on ordering.

I think the best approach here, regardless, is what @merefield suggested: use one template and then reference Ember components from it.

Default alert is only shown to admins, FYI.

4 Likes

Thank you for the explanations!

Playing more with this… it’s really fresh and a joy to use!

I used three existing components for that layout and that’s what I’d expect to be a common approach when building a custom homepage. I could only add one of these to the wrapper outlet, that’s why I think having a plain outlet here would be more helpful.

5 Likes

Another observation: I put a link on the sidebar using the /custom url:

image

It’s not highlighted when on the custom route.

If I understand the logic with the sidebar highlights correctly, it should also be highlighted when on the root url /.

2 Likes

I see your issue more clearly after having a quick look at the Featured Lists component. One option is to refactor that component and have it output all of the lists into one Ember component. Then you could add that component to a plugin wrapper outlet.

Another option is to add a second plugin outlet to the custom homepage template, something like <PluginOutlet @name="below-custom-homepage"/>.

I may be hanging on to this custom-homepage outlet with a message for admins for not much good reason, to be honest. That warning is not all that useful…

Yeah, that can be tricky. In my local test just now, /custom there doesn’t work properly. It’s better to use /, that routes correctly. But it still doesn’t highlight.

1 Like

That seems to be a common issue. If I use /it also doesn’t highlight other routes set as the landing page.

Yes, I could also imagine the warning just being displayed differently. The main advantage of wrapper outlets seems to be that I can conditionally yield core code or render custom one. But that would likely never be a case for that info message.

There must be a misunderstanding. The component already wraps all lists in one wrapping component and renders it on any given outlet:

image

So I can add the component without issues to the current wrapper outlet on the custom homepage.
What I can’t do is use that outlet to render more than one standalone component on the custom homepage. Components I would have installed as theme components, like these three:

image

My assumption is that making such use of several standalone theme components to build a custom homepage would be the common approach. Rather than building it all from scratch in one theme.

If you consider adding another outlet or changing the outlet setup, I could give some more feedback from using it so far. Though I’ll wrap that rabbit hole in details :smile:

So I realized that the outlet is rendered within the main-outlet element. The overall structure of these elements then is:

  • main-outlet wrapper
    • sidebar-wrapper
    • main-outlet
      • custom-homepage outlet

As a designer I’m actually not that flexible arranging items on a custom homepage using this outlet. For the design shared above I rather used the before-main-outlet outlet, not only because I can put more than one component, but also because it doesn’t nest components within the main-outlet element.

The structure as shared on the screenshot above looks like this:

  • main-outlet wrapper
    • sidebar-wrapper
    • component: search banner
    • component: featured topics
    • component: featured lists
    • main-outlet

The advantage is that I can arrange elements across the width of the entire main-outlet wrapper and not just within the main-outlet element. To illustrate the point, if I’d render one of the components on the current custom-homepage outlet, it would render nested within the main-outlet element like this:

The most flexibility for custom designs in my view would be offered by a plugin outlet that is placed

  • as a direct child of the main-outlet wrapper (similar to the before-main-outlet outlet)
  • within a wrapping div

That wrapping div would bundle all components added to it and allow for easy ordering. Such a structure would then look like:

  • main-outlet wrapper
    • sidebar-wrapper
    • custom-homepage-wrapper
      • component: search banner
      • component: featured topics
      • component: featured lists
    • main-outlet

So that’s my feedback as a designer. Guess it’s for you to decide how much that aligns with what you’d consider a common application for the custom homepage feature.

3 Likes

Presumably this page is “superficial” in that it will appear for the user but not for “Googlebot” and so won’t be indexed?

Correct, yes, for the crawler view I have opted to outputting just the top menu. Can’t really know from the Rails app what a theme will output in this route.

I am thinking about the suggestions here @nolo, will make some time shortly to test out some changes. Please :bear: with me.

4 Likes