Lucky Logo

# What are Components?

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.

# Reusing Components

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.

# Your Turn

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…

  • Generate a new component for a nav bar
  • Mount your new component in both layouts
  • Add a needs line to your component, and pass in the data
  • Display the value of that needs method in your component
See a problem? Have an idea for improvement? Edit this page on GitHub