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.