In Lucky, Components are small, reusable bits of HTML that relate to some smaller portion of a site.
We create a separate class for these and they go in your src/components/
directory. We’ve already
seen two of them in use in our AuthLayout
. The Shared::LayoutHead
, and Shared::FlashMessages
.
Let’s take a look at the Shared::LayoutHead
component in src/components/shared/layout_head.cr
. In this file,
we can see all of the markup that would go in our website’s <head>
tags are here. They are in the render
method (required for all components).
At the top of this file you will see a line that starts with needs
. The needs page_title : String
.
This tells the Shared::LayoutHead
component that it requires the page_title
value to be passed in
when mounting this component. (e.g. mount Shared::Header, page_title: "Clover App"
)
Each needs
specified will create a method with that name that will return the value type specified.
We use needs
in several different classes in Lucky. It’s used for type-safety when a class requires specific data.
We currently have two separate layouts, but our custom footer is only in the AuthLayout
. Let’s create a
new component that will allow us to render our footer in both layouts with the gen.component
CLI task:
lucky gen.component Shared::Footer
Next we need to open up our AuthLayout
in src/pages/auth_layout.cr
and move our footer
block in to the render
method of
our newly generated Shared::Footer
component.
# src/pages/auth_layout.cr
- footer class: "footer mt-auto py-3 bg-light" do
- div class: "container" do
- span "CloverApp", class: "text-muted"
- end
- end
+ mount Shared::Footer
Then in our Shared::Footer
, paste our code in the render
method:
# src/components/shared/footer.cr
def render
footer class: "footer mt-auto py-3 bg-light" do
div class: "container" do
span "CloverApp", class: "text-muted"
end
end
end
The mount
method takes the component class and handles setting it up and calling render.
As an added benefit, if you inspect your page’s markup, you’ll see HTML comments wrapped around each
component. This allows you to see which component is responsible for the markup being rendered.
When creating your own components that require specific data (i.e. page_title
), you will add your needs
for that data, then in your mount
, you’ll pass each as a named argument. (e.g. mount Shared::Footer, copyright_year: 3099
)
For more information on components, read the Components guide in Rendering HTML.
Getting the hang of Components can really help to clean up your code and using them well can make testing your views easier. Now it’s your turn to play with them a bit.
Try this…
needs
line to your component, and pass in the dataneeds
method in your component