Use constant layout for all pages

i have a constant page layout like this : Pages Content Goes Here…

How i can do this in version 3?

I’m not sure what you mean by “Pages Content Goes Here…” but typically layout is done with a combination of the application template (markup like navbar, footer, etc that is the same on all pages) and layout components (very contrived example):

{{#my-page type="profilePage" as |page|}}
  {{page.heading title="blah blah"}}
  {{#page.content}}
    Page content goes here
  {{/page.content}}
{{/my-page}}

what is “my-page” ? is it a component? how i can create this?

Yes it’s a hypothetical component I made up. I’ll show a couple of examples.

Components can be rendered two ways:

  1. without a block.e.g.
{{my-page}}
{{!-- or angle bracket syntax --}}
<MyPage/>
  1. With a block
{{#my-page}}
  {{!-- block content here --}}
{{/my-page}}
{{!-- or angle bracket syntax --}}
<MyPage>
  {{!-- block content here --}}
</MyPage>

To render a passed block within the context of the component template you use the yield helper:

{{!-- templates/components/my-page.hbs --}}
<div class="page-wrapper">
  {{yield}}
</div>

You can also conditionally yield based on whether or not there is a block provided to the component:

<div class="some-stuff">
  {{#if (has-block)}}
    Default content here
  {{else}}
    {{yield}}
  {{/if}}
</div>

NOTE: if you are using glimmer components you can specify the wrapping div yourself in the template (like I did above), but if you’re using classic components there will be a wrapping div automatically created so it’s better to attach classnames via the classNames property on the backing js instead:

export default Component.extend({
  classNames: ['some-stuff']
});

You can also yield data, actions, or other components. If you recall in my original example I used:

{{#my-page type="profilePage" as |page|}}
  {{page.heading title="blah blah"}}
  {{#page.content}}
    Page content goes here
  {{/page.content}}
{{/my-page}}

In this case my-page yields two components, heading and content. What this might look like in the my-page component is:

{{!-- templates/components/my-page.hbs --}}
{{yield (hash
  heading=(component "page-heading")
  content=(component "page-content" contentType=this.contentType)
)}}

In the above example the “my page” component yields the heading and content components, and in the case of content is passing extra “context” (contentType, which I just made up as a hypothetical) in the process. You can use this to assemble a very flexible component that glues together sub components with actions and properties but each sub component can also render a block, and you can leave it up to the rendering template to determine if the yielded components are rendered at all (for example you could have a my-page component that renders a heading but not a content block).

2 Likes