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