Coder Social home page Coder Social logo

luckyframework / lucky Goto Github PK

View Code? Open in Web Editor NEW
2.6K 46.0 156.0 12.13 MB

A full-featured Crystal web framework that catches bugs for you, runs incredibly fast, and helps you write code that lasts.

Home Page: https://luckyframework.org

License: MIT License

Crystal 99.63% HTML 0.07% Shell 0.26% Dockerfile 0.04%
crystal web web-framework lucky-framework

lucky's Introduction

github banner-short

Version License

API Documentation Website Lucky Guides Website

Discord

The goal: prevent bugs, forget about most performance issues, and spend more time on code instead of debugging and fixing tests.

In summary, make writing stunning web applications fast, fun, and easy.

Coming from Rails?

Try Lucky

Lucky has a fresh new set of guides that make it easy to get started.

Feel free to say hi or ask questions on our chat room.

Or you can copy a real working app with Lucky JumpStart.

Installing Lucky

To install Lucky, read the Installing Lucky guides for your Operating System. The guide will walk you through installing a command-line utility used for generating new Lucky applications.

Keep up-to-date

Keep up to date by following @luckyframework on Twitter.

Documentation

API (main)

What's it look like?

JSON endpoint:

class Api::Users::Show < ApiAction
  get "/api/users/:user_id" do
    user = UserQuery.find(user_id)
    json UserSerializer.new(user)
  end
end
  • If you want you can set up custom routes like get "/sign_in" for non REST routes.
  • A user_id method is generated because there is a user_id route parameter.
  • Use json to render JSON. Extract serializers for reusable JSON responses.

Database models

# Set up the model
class User < BaseModel
  table do
    column last_active_at : Time
    column last_name : String
    column nickname : String?
  end
end
  • Sets up the columns that you’d like to use, along with their types
  • You can add ? to the type when the column can be nil . Crystal will then help you remember not to call methods on it that won't work.
  • Lucky will set up presence validations for required fields (last_active_at and last_name since they are not marked as nilable).

Querying the database

# Add some methods to help query the database
class UserQuery < User::BaseQuery
  def recently_active
    last_active_at.gt(1.week.ago)
  end

  def sorted_by_last_name
    last_name.lower.desc_order
  end
end

# Query the database
UserQuery.new.recently_active.sorted_by_last_name
  • User::BaseQuery is automatically generated when you define a model. Inherit from it to customize queries.
  • Set up named scopes with instance methods.
  • Lucky sets up methods for all the columns so that if you mistype a column name it will tell you at compile-time.
  • Use the lower method on a String column to make sure Postgres sorts everything in lowercase.
  • Use gt to get users last active greater than 1 week ago. Lucky has lots of powerful abstractions for creating complex queries, and type specific methods (like lower).

Rendering HTML:

class Users::Index < BrowserAction
  get "/users" do
    users = UserQuery.new.sorted_by_last_name
    render IndexPage, users: users
  end
end

class Users::IndexPage < MainLayout
  needs users : UserQuery

  def content
    render_new_user_button
    render_user_list
  end

  private def render_new_user_button
    link "New User", to: Users::New
  end

  private def render_user_list
    ul class: "user-list" do
      users.each do |user|
        li do
          link user.name, to: Users::Show.with(user.id)
          text " - "
          text user.nickname || "No Nickname"
        end
      end
    end
  end
end
  • needs users : UserQuery tells the compiler that it must be passed users of the type UserQuery.
  • If you forget to pass something that a page needs, it will let you know at compile time. Fewer bugs and faster debugging.
  • Write tags with Crystal methods. Tags are automatically closed and whitespace is removed.
  • Easily extract named methods since pages are made of regular classes and methods. This makes your HTML pages incredibly easy to read.
  • Link to other pages with ease. Just use the action name: Users::New. Pass params using with: Users::Show.with(user.id). No more trying to remember path helpers and whether the helper is pluralized or not - If you forget to pass a param to a route, Lucky will let you know at compile-time.
  • Since we defined column nickname : String? as nilable, Lucky would fail to compile the page if you just did text user.nickname since it disallows printing nil. So instead we add a fallback "No Nickname". No more accidentally printing empty text in HTML!

Testing

You need to make sure to install the Crystal dependencies.

  1. Run shards install
  2. Run crystal spec from the project root.

Contributing

See CONTRIBUTING.md

Lucky to have you!

We love all of the community members that have put in hard work to make Lucky better. If you're one of those people, we want to give you a t-shirt!

To get a shirt, we ask that you have made a significant contribution to Lucky. This includes things like submitting PRs with bug fixes and feature implementations, helping other members work through problems, and deploying real world applications using Lucky!

To claim your shirt, fill in this form.

Contributors

Thanks & attributions

  • SessionHandler, CookieHandler and FlashHandler are based on Amber. Thank you to the Amber team!
  • Thanks to Rails for inspiring many of the ideas that are easy to take for granted. Convention over configuration, removing boilerplate, and most importantly - focusing on developer happiness.
  • Thanks to Phoenix, Ecto and Elixir for inspiring Avram's save operations, Lucky's single base actions and pipes, and focusing on helpful error messages.
  • lucky watch based heavily on Sentry. Thanks @samueleaton!

lucky's People

Contributors

5minpause avatar actsasflinn avatar ajwann avatar arr-dev avatar bcardiff avatar bdtomlin avatar citizen428 avatar edwardloveall avatar gabrielrios avatar grepsedawk avatar hanneskaeufler avatar hibachrach avatar ianagne avatar jwoertink avatar kcerb avatar matthewmcgarvey avatar mdwagner avatar mikeeus avatar nodemd avatar paulcsmith avatar rmarronnier avatar rnice01 avatar robacarp avatar russ avatar sija avatar skojin avatar smadeja avatar stephendolan avatar vlazar avatar wout avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lucky's Issues

Ikagi

ikigai

The Lucky philosophy is to try to be at the intersection of happiness, usefulness, ease of use, what you can get paid for, and what is fulfilling. A framework with as few tradeoffs as possible.

Make assign more robust

If you have the same assign in multiple pages it duplicates it the asking. That needs to be fixed

Add HerokuDeploy task

So it can be inherited from in the default lucky deploy task, but can be overridden if you want to implement your own task

Use git-crypt for storing and reading secrets

https://www.agwa.name/projects/git-crypt/ Transparent file encryption. Can use symmetric keys so devs can easily share it, or use GPG.

Add some lucky tasks to get it working well, make it easy to publish the key to Heroku on setup

lucky secrets.encrypt_file # Add file(s) to .git-attributes
lucky secrets.sync_key prod # Pushes the key as an env var on Heroku

Add helper for rendering in a layout

class InnerPage < BaseView
  layout BaseLayout # This would probably go in the BaseView

  def inner
    # The inner page
  end

  def title
    "A great title"
  end
end

class BaseLayout < BaseLayout
  @page : BaseView

  def render
    title @page.title
    main do
      # Consider forwarding missing to @page so you can use it's helpers more easily
      @page.inner
    end
  end
end

Instead of this old way

class InnerPage < LuckyWeb::HTMLView
  def render
    Layout.new(self).render.to_s
  end

  def title
    "A great title"
  end
end

class Layout < LuckyWeb::HTMLView
  @page : InnerPage

  def initialize(@page)
    @io = IO::Memory.new
  end

  def render
    title @page.title
  end
end

Discuss: Add optional template rendering to pages

class Users::IndexPage < MainLayout
  needs users : UserQuery

  render_template # Assumes ./index_template.ecr/.slang - Use kilt to support just about anything
  
  # or specify template
  render_template "./some_other_extension.rss.ecr
end

The default would still be to use the HTML tag methods, but sometimes it's much nicer to use templating languages like ECR when doing content heavy pages like landing pages, pricing pages, etc. They're usually quite simple and have large paragraphs of text, which work better in template languages

Add raise_typeof helper

I want to make it easy for beginners to figure out the types of things. This will be helpful when using assigns in Pages, or really for anytime you need a type

macro show_typeof(var)
  raise "Type of `{{var.id}}` is: #{typeof({{var}})}"
end

number = 1
show_typeof(number)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.