It’s nice that we can boot our application and see a home page, but we know that page won’t stick around. We will swap it out for our own Home page to make this site a little more ours.
First, we should create a new Page. We will use the gen.page CLI task. Enter lucky gen.page Home::IndexPage.
lucky gen.page Home::IndexPage
This will generate a new Page class in src/pages/home/index_page.cr which we will need to make a small change
in. Open that file, and update this code:
# src/pages/home/index_page.cr
- class Home::IndexPage < MainLayout
+ class Home::IndexPage < AuthLayout
The MainLayout is currently setup to be our site layout for users logged in to the app.
The AuthLayout is used for pages like the login/signup pages, and now our Home Page. Eventually, you’ll
be creating your own layouts to better suit your needs.
Next, we need to tell our root action to render our new page instead of the default Lucky page. Open up your
Home::Index action in src/actions/home/index.cr. Update this code:
# src/actions/home/index.cr
- html Lucky::WelcomePage
+ html Home::IndexPage
The html macro here will take the page class we want to render, and mix the content with our layout.
For more information on rendering HTML, read the Rendering HTML guide.
As mentioned previously, we currently have two separate layouts. One for when users are logged in MainLayout, and one for
when users are logged out AuthLayout. These files live in the root of your src/pages/ directory. We will update our AuthLayout
to start so we can get a feel for writing HTML in Lucky.
When it comes to writing HTML in Lucky, we use plain Crystal methods that generate HTML for us! Read the HTML guide for more details.
Open up the AuthLayout in src/pages/auth_layout.cr. This file has a render method which contains the start to our HTML. Within this method
are several other Crystal methods like html_doctype, html, and body which should be pretty recognizable. Any HTML tag has an associated method
you can call from here. In addition, there’s a few helper methods which are explained more in the HTML guide.
Two methods that may look unfamiliar are mount, and the content method you see inside of the body block.
The mount is related to Components
which we will cover later. The content method is used to render the page content from pages that inherit from this layout.
For example, our Home::IndexPage inherits from AuthLayout, so the Home::IndexPage has a content method where all of the Home page HTML will go.
Let’s update the html block, and replace it with this code:
# src/pages/auth_layout.cr
html class: "h-100", lang: "en" do
mount Shared::LayoutHead, page_title: page_title
body class: "d-flex flex-column h-100" do
mount Shared::FlashMessages, context.flash
main class: "flex-shrink-0" do
content
end
footer class: "footer mt-auto py-3 bg-light" do
div class: "container" do
span "CloverApp", class: "text-muted"
end
end
end
end
As you can see, we can write methods that match up with HTML tags like span, div, main, and footer. We can
even add our own custom CSS classes by using the class: "" argument of each tag method.
Boot up your app (lucky dev), and give it a shot! See that you now have “CloverApp” displaying below the content of your Home page.
If you haven’t guessed by now, we’ve started adding Bootstrap classes to our HTML. You’re free to use any (or no) CSS framework you wish. There are no limitations since Lucky includes LaravelMix which just wraps Webpack. We will stick with Bootstrap just for the purposes of this Tutorial.
Lucky uses yarn by default, so this tutorial will as well. If you prefer a different installation you may use that.
Before we install Bootstrap, we should shut down our server. (ctrl-c) Then from the terminal, we can run:
yarn add bootstrap @popperjs/core
PopperJS is required for some of the Bootstrap components such as dropdowns and popovers to function correctly.
Next we will import Bootstrap in our stylesheet. Open up src/css/app.scss. You’ll find some default normalize styles in here. Now that we’re using
a CSS framework, all of these can go away! Replace everything with this code:
// src/css/app.scss
@import "bootstrap";
Now, import Bootstrap into src/js/app.js to ensure the Bootstrap components that require Javascript function correctly.
Open that file and add this code:
// src/js/app.js
require("@rails/ujs").start();
+ import "bootstrap";
Finally, restart the dev server from the terminal lucky dev.
For more information on handling assets, read the Asset Handling guide.
Now that we have a layout, we can update our Home page to match our new styles.
Open up the Home::IndexPage file in src/pages/home/index_page.cr. In here, we will see the content method defined.
This is the method that’s called in the AuthLayout class. In this content method we can see the h1 method. Let’s update
that with this code:
# src/pages/home/index_page.cr
def content
div class: "px-4 py-5 my-5 text-center" do
h1 "CloverApp", class: "display-5 fw-bold"
div class: "col-lg-6 mx-auto" do
para "It's your Lucky day! See a fortune, and share the luck.", class: "lead mb-4"
div class: "d-grid gap-2 d-sm-flex justify-content-sm-center" do
link "Join", to: SignUps::New, class: "btn btn-primary btn-lg px-4 me-sm-3"
link "Login", to: SignIns::New, class: "btn btn-outline-secondary btn-lg px-4"
end
end
end
div class: "container" do
# we will use this later
end
end
Notice that we’re using the link method. Your first thought might be “Why would we use the <link> tag here?”.
This is one of the few exceptions to the “every tag has an associated method” rule. In this case link creates an anchor tag <a></a>.
The to: argument takes a Lucky Action class allowing the links to be type-safe and more future proof.
The other new tag here is para. This replaces the <p></p> tag due to Crystal already having a p() method used for printing to STDOUT.
For more information on special tags, read the Special Tags guide in Rendering HTML.
We’ve created a layout and a new home page. Now it’s your turn to play with some HTML.
Try this:
src/css/app.scss.If you have existing HTML you want to convert try the HTML to Lucky Converter utility.