An introduction to Lucky Framework, Lucky HTML, and the Crystal Language

An introduction to Lucky Framework, Lucky HTML, and the Crystal Language

By Nolan Mayersky | Nolan's Rambles | 9 Dec 2020


What is Lucky?

Lucky is a framework written in the Crystal programming language. Crystal is a static typed, compiled language with syntax EXTREMELY similar to Ruby. In Lucky's own words, "Lucky is a web framework written in Crystal. It helps you work quickly, catch bugs at compile time, and deliver blazing fast responses."

For more or less, Lucky is similar to other web application frameworks such as Python's Django or Ruby's Ruby on Rails.

What I like about Lucky is that it uses Crystal. The static typing catches a lot of bugs at compile time. There is also LuckyHTML, which I will talk a little more about, which allows you to render your HTML using Crystal methods! Neat! This also provides type checks and safety, thus reducing bugs.

So, what is Lucky HTML?

Well, it's basically what I just said. Lucky uses Crystal methods for rendering HTML. The Crystal methods map as closely as possible to how HTML is used.

Lucky uses Crystal methods for rendering HTML. The Crystal methods map as closely as possible to how HTML is used.

Here is an example of rendering a page in Lucky HTML. This example is assigning the the array of names to 'user_names' which can then be called in the Index page template.

# in src/actions/users/index.cr
class Users::Index < BrowserAction
  get "/users" do
    # Renders the Users::IndexPage
    html IndexPage, user_names: ["Paul", "Sally", "Jane"]
  end
end

and here is how that user_names would be called:

# in src/pages/users/index_page.cr
class Users::IndexPage < MainLayout
  needs user_names : Array(String)

  def content
    ul class: "my-user-list" do
      user_names.each do |name|
        li name, class: "user-name"
      end
    end
  end
end

That's about all I'll give you on Lucky for now. This is just a really brief introduction to a small part of Lucky. It's a pretty big framework.

There is a lot more that I could go into, but if you're interested you can head over to the Lucky and/or Crystal website to learn more about both. They do a better job at explaining it anyway. 🤣

I'll leave you with one more example from an app I'm currently working on. This is a page template. So, this will render on every page. It's using Bootstrap as a CSS framework, so the nav classes may look a bit familiar to you.

abstract class MainLayout
  include Lucky::HTMLPage

  # 'needs current_user : User' makes it so that the current_user
  # is always required for pages using MainLayout
  needs current_user : User

  abstract def content
  abstract def page_title

  # MainLayout defines a default 'page_title'.
  #
  # Add a 'page_title' method to your indivual pages to customize each page's
  # title.
  #
  # Or, if you want to require every page to set a title, change the
  # 'page_title' method in this layout to:
  #
  #    abstract def page_title : String
  #
  # This will force pages to define their own 'page_title' method.
  def page_title
    "Welcome to Ask.cr, where you can learn more about the Crystal programming language!"
  end

  def render
    html_doctype

    html lang: "en" do
      mount Shared::LayoutHead, page_title: page_title, context: context

      body do
        div(class: "container mt-3") do
          render_top_nav
          mount Shared::FlashMessages, context.flash
          content
        end
      end
    end
  end

  private def render_top_nav
    ul(class: "nav nav-fill justify-content-center") do
      li(class: "nav-item") do 
        link "Home",  Users::Dashboard, class: "nav-link"
      end
      li(class: "nav-item") do 
        link "Dashboard", Users::Dashboard, class: "nav-link"
      end
      li(class: "nav-item") do 
        link "Questions",  Questions::Index, class: "nav-link"
      end
      li(class: "nav-item dropdown") do 
        a "#{current_user.display_name}", href: "#", class: "nav-link dropdown-toggle", data_toggle: "dropdown", role: "button", aria_haspopup: "true", aria_expanded: "true"
        div(class: "dropdown-menu") do 
          link "Edit Profile",  Users::Edit.with(current_user.id), class: "dropdown-item"
          link "Sign out", SignIns::Delete, class: "dropdown-item"
        end
      end
    end
  end
end

As I said, here's the links to check out Lucky and Crystal. Enjoy!

https://luckyframework.org/
https://crystal-lang.org/


Nolan Mayersky
Nolan Mayersky

I'm a 30 year old software engineer from the good ol' USA.


Nolan's Rambles
Nolan's Rambles

A blog of my ramblings about software engineering.

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.