Git Product home page Git Product logo

sugar's Introduction

Sugar

Build Status Coverage Status Hex.pm Version Deps Status ![Gitter](https://badges.gitter.im/Join Chat.svg)

Modular web framework for Elixir

0.4.x -> 0.5.x Upgrade Warning

Please note that ecto and postgrex have been removed from Sugar's dependencies as of version 0.5.0. If your application uses Ecto, you'll need to add it to your application's mix.exs, like so:

def project do
  [ app: :my_app,
  # ...
    deps: deps() ]
end

def deps do
  [ {:sugar, "~> 0.5.0"},
    {:ecto, "~> 2.1"},
    {:postgrex, "~> 0.13.0"} ]
end

Goals

  • Speed. Sugar shouldn't be slow and neither should your project.
  • Ease. Sugar should be simple because simple is easy to learn, use and maintain.
  • Effective. Sugar should aid development. You have better things to which to devote your time.

Reason for Existence

Why build this when Dynamo, Weber, and Phoenix exist with growing communities? While these projects are great in their own right, Sugar aims to be another contender, sparking more development on all three projects (and/or others that may follow) and giving developers another option when deciding what framework fits their needs best. Sugar may even strive to shake things up just as ChicagoBoss has done.

Getting Started

# Clone this repo
git clone https://github.com/sugar-framework/simple.git
cd simple

# Get project dependencies
mix deps.get

# Start the web server
mix server # or `iex -S mix server` if you want access to iex

Configurations

Sugar needs to be configured in your application's config/config.exs in order to work. The following options are supported:

config :sugar, router: MyWebsite.Router

Tells Sugar which module to use as a router. This module should implement Sugar.Router, and should have at least one route defined. This is required.

config :sugar, plug_adapter: Plug.Adapters.Cowboy

Tells Sugar which web server to use to handle HTTP(S) requests. Cowboy is currently the only supported option, and Sugar will default to using Plug.Adapters.Cowboy if this is omitted.

config :sugar, MyWebsite.Router, ...

Tells Sugar how the specified router should be configured. The following options are supported:

  • http: takes a key/value list with options to configure the specified :plug_adapter. Of particular usefulness:
    • ip: IP address the server should bind to. Should be a tuple in the format {x,y,z,w}. Defaults to accepting connections on any IP address.
    • port: port the server should listen on. Defaults to 4000.
    • acceptors: the number of acceptors for the listener. Defaults to 100.
    • max_connections: the maximum number of connections supported. Defaults to :infinity.
    • compress: whether or not the bodies of responses should be compressed. Defaults to false.
  • https: takes a key/value list with the same options as http, or can be set to false if you don't want to enable HTTPS. The following additional options(along with others from Erlang's "ssl" module) are supported:
    • password: a plaintext, secret password for the private SSL key (if it's password-protected)
    • keyfile: path to the PEM-format private key file to use
    • certfile: path to the PEM-format certificate to use
    • otp_app - If present, certfile and keyfile can be relative paths with respect to otp_app's priv directory.

Note: Create a self-signed certificate for easy HTTPS testing.

# Generate a keyfile
$ openssl genrsa -out key.pem 2048

# Create a CSR
$ openssl req -new -key key.pem -out request.pem

# Generate a certfile that expires in $NUM_DAYS
$ openssl x509 -req -days $NUM_DAYS -in request.pem -signkey key.pem -out cert.pem

Example

use Mix.Config

config :sugar, router: MyWebsite.Router

config :sugar, MyWebsite.Router,
  http: [
    port: 80
  ],
  https: [
    port: 443,
    password: "OMG_SUPER_SECRET",
	keyfile: "/path/to/key.pem",
	certfile: "/path/to/cert.pem"
  ]

Routers

Because Sugar builds upon Plug, it leverages Plug.Router to do the heavy lifting in routing your application, adding an alternate DSL.

Routes are defined with the form:

method route [guard], controller, action

method is get, post, put, patch, delete, or options, each responsible for a single HTTP method. method can also be any, which will match on all HTTP methods. controller is any valid Elixir module name, and action is any valid function defined in the controller module.

Example

defmodule MyWebsite.Router do
  use Sugar.Router

  get "/", Hello, :index
  get "/pages/:id", Hello, :show
  post "/pages", Hello, :create
  put "/pages/:id" when id == 1, Hello, :show
end

Controllers

All controller actions should have an arrity of 2, with the first argument being a Plug.Conn representing the current connection and the second argument being a Keyword list of any parameters captured in the route path.

Sugar bundles these response helpers to assist in sending a response:

  • render/2 - sends a normal response
  • not_found/1 - sends a 404 (Not found) response

Example

defmodule MyWebsite.Controllers.Hello do
  use Sugar.Controller

  def index(conn, []) do
    render conn, "index.html.eex", []
  end

  def show(conn, args) do
    render conn, "show.html.eex", args
  end

  def create(conn, []) do
    render conn, "create.html.eex", []
  end
end

Todo Items

  • basic authentication (?)
  • Development error page
  • Caching
    • Compiled HTML
    • Application Data
    • Adapters
      • ETS

Who's behind this?

Why, the contributors, of course! Would you consider being one? Please send a pull request :)

How to start contributing

The main product of this repository is the example terms in the file CONTRIBUTING.md. This project uses those guidelines as the basis for its own development process. Please refer to that file.

License

Sugar is released under the MIT License.

See LICENSE for details.

sugar's People

Contributors

chatman-media avatar gitter-badger avatar kination avatar kmwhite avatar lowks avatar marcusoftnet avatar narkoz avatar parroty avatar rrrene avatar slogsdon avatar sschepens avatar vjustov avatar yellowapple 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

sugar's Issues

Replace JSEX with Poison

Most people will probably use Poison in their projects, so it will be an easy way to reduce the total number of dependencies for them.

Resource routing

Allow for RESTful resource routes. Example:

defmodule Router do
  use Sugar.Router

  resource "/users", User
end

is shorthand for:

demodule Router do
  use Sugar.Router

  get "/users", User, :index
  get "/users/:id", User, :show
  put "/users", User, :create
  post "/users/:id", User, :edit
end

Can't start server, dependency error.

I'm on Elixir (0.13.3) looking for a web framework, since Dynamo seems to be dead.
I tried cloning Sugar and starting the server, and I get a dependency error right off, not sure which lib/decimal its complaining about as there isn't one in Sugar,
Any Ideas?

== Compilation error on file lib/decimal.ex ==
** (CompileError) lib/decimal.ex:92: undefined function record_type/1
(elixir) src/elixir.erl:188: :elixir.quoted_to_erl/3

could not compile dependency decimal, mix compile failed. You can recompile this dependency with mix deps.compile decimal or update it with mix deps.update decimal
mix server 22.63s user 8.21s system 117% cpu 26.169 total

Template finder / compiler

Should find matching files, create a Template[] record for each with filename, engine, etc, and compile all valid templates.

[RFC] Soft real-time items

Need something like this to keep up with newer frameworks and web application development trends. The technologies below all allow the client to receive unsolicited updates from the server, while WebSockets allow the client to also send data back to the server on the same connection.

Technologies involved

Items needed

  • Sugar.Events
  • Integration with Plug
  • Sugar.Router.socket/3

Notification/event layer

This would allow notifications/events to be published by producers (data layer, api endpoints, etc.) and subscribed by consumers (clients). Would most likely be built upon GenEvent or something similar.

Interaction layer

This would interface the notification layer with the clients by means of the above technologies, e.g. WebSockets. A behaviour would most likely be created to allow for the differing technologies to talk to the clients via the current Plug adapter (web server) in a consistent manner.

API additions

I already have some macros thought out from working on another project the would remove cruft from a WebSockets handler, which should be easy to expand to include the necessary bits for long polling and SSE.

Routing

  • Basic routing (get, post, put, patch, delete, options)
  • Ensure guards are passed to Plug.Router

How to properly render a template?

How to properly render a template? I want to render index.html.eex by using render. In the docs says render conn, "showing index controller". I did that but not working. I did render conn, "main/index", render conn, "main/index.html" and render conn, "main/index.html.eex" but all ended up error File.Error: could not read file lib/views/main/index. Am I missing something?

Integrate Plug

From the README:

Plug is:

  1. A specification for composable modules in between web applications
  2. Connection adapters for different web servers in the Erlang VM

Integrating Plug into the project will allow for standardization in the future. There is also an added benefit of an expanded development team with the external dependency.

Return helpers

Helpers for creating proper return tuples for Plug.

  • JSON
  • Raw
  • Default 404

`mix server` errors out with `(UndefinedFunctionError) undefined function: Foo.Router.run/0` as of 0.4.4

Full error:

DixonCider:my_website rnorthrup$ mix server
Compiled lib/yellowapple_site.ex
Compiled lib/yellowapple_site/controllers/main.ex
Compiled lib/yellowapple_site/router.ex
Generated yellowapple_site.app
** (UndefinedFunctionError) undefined function: YellowappleSite.Router.run/0
    (yellowapple_site) YellowappleSite.Router.run()
    lib/mix/tasks/server.ex:27: Mix.Tasks.Server.run/1
    (mix) lib/mix/cli.ex:55: Mix.CLI.run_task/2
    (elixir) lib/code.ex:316: Code.require_file/2

This code works fine with Sugar 0.4.3, which indicates (to me at least) that for some reason moving to HttpRouter broke things, and I've yet to figure out why, though my hunch is that there's some confusion about run's arity. Thoughts on this?

Cannot compile with newest source

Have a fresh install of elixir but getting this error on compile:
the dependency excoveralls requires Elixir "~> 0.13.1" but you are running on v1.0.2

how can I work around this or should I just wait for a fix

Error when compilling dependencies.

$ mix deps.compile excoveralls
==> excoveralls
warning: the dependency excoveralls requires Elixir "~> 0.13.1" but you are    running on v1.0.2

== Compilation error on file lib/excoveralls/exceptions.ex ==
** (CompileError) lib/excoveralls/exceptions.ex:1: undefined function  defexception/2
    (stdlib) lists.erl:1352: :lists.mapfoldl/3
    (elixir) lib/kernel/parallel_compiler.ex:97: anonymous fn/4 in  Kernel.ParallelCompiler.spawn_compilers/8

could not compile dependency excoveralls, mix compile failed. You can recompile this dependency with `mix deps.compile excoveralls` or update it with `mix deps.update excoveralls`

The current excoveralls version in the mixfile is 0.2.0 which uses Elixir 0.13. Lets bump the version to ~> 0.3. This just happens when using Hex to install sugar.

compile error when set `show_debugger` to `true` in config.ex

Hi, when I set the show_debugger option to true in config.ex, then restart the server, It always raise exception like this:

** (UndefinedFunctionError) undefined function: Plug.Debugger.init/1
    Plug.Debugger.init([otp_app: :etie])
    lib/plug/builder.ex:112: Plug.Builder.init_module_plug/3
    lib/plug/builder.ex:99: anonymous fn/2 in Plug.Builder.compile/1
    (elixir) lib/enum.ex:1261: Enum."-reduce/3-lists^foldl/2-0-"/3
    lib/plug/builder.ex:99: Plug.Builder.compile/1
    expanding macro: HttpRouter.__before_compile__/1
    lib/etie/router.ex:1: Etie.Router (module)

and the version of Sugar in my app is 0.4.6.
Did I do something wrong ?

JSON parser Plug

We should have a JSON parser Plug because Plug doesn't have one and sending content-type: application/json makes sugar reply a 500

Make Plug dependencies consistent

Plugs have a requirement of Plug 0.4.3 and Sugar has Plug ~> 0.4.3.
This slight inconsistency makes elixir 0.13.3 throw this error:
Unchecked dependencies for environment dev:

  • plug (package)
    the dependency plug defined

    In deps/sugar/mix.exs:
    {:plug, "~> 0.4.3", [hex_app: :plug]}

    does not match the requirement specified

    In deps/plugs/mix.exs:
    {:plug, "0.4.3", [hex_app: :plug]}

    Ensure they match or specify one of the above in your Watcher.Mixfile deps and set override: true
    ** (Mix) Can't continue due to errors on dependencies

[Poll] Real-time stuff or caching?

Which should go first, #17 or #51? Any preferences?

At this point, I'm leaning towards real-time stuff because it's a little more straight-forward with less in the air regarding implementation, but I could be swayed either way.

Response code for json helper

It would be great to make a json/3 helper which receives a status code to send along with the body, instead of just forcing 200

Edit: juse watched the code, it accepts a status option, but it think it would be more consistent and clean to let it just be:
json conn, 400, body
or conn |> json 400, body

Update Docs on Website

Hello,

Documentation on the website is really outdated and not full.
I can try to update it

Thanks!

Demo Application

A Demo Application that implements the stuff mentioned in the README.md would be really helpful for elixir n00bs like me to play around with it. If I could for example just do a git clone, install the dependencies and fire up the server I bet I can get pretty existed and want to learn some more Elixir to play with it! ๐Ÿ˜

Session adapters

Session adapters should follow a defined interface to allow for new adapters to be added/used easily. Adapters for this issue:

  • Cookie
  • ETS

Dependency postgrex 0.5.5 conflicts with Elixir 1.0.0

Working through the Getting Started tl;dr steps:

# Create your new project
mix new your_project
cd your_project

# Add '{:sugar, github: "sugar-framework/sugar"}'
# to your deps
vi mix.exs

# Get dependencies and compile them
mix do deps.get, deps.compile

Output:

Generated plug.app
==> plugs
Compiled lib/sugar/plugs/parsers/json.ex
Compiled lib/sugar/plugs/hot_code_reload.ex
Compiled lib/sugar/plugs/exceptions.ex
lib/sugar/plugs/logger.ex:1: warning: behaviour Plug.Wrapper undefined
Compiled lib/sugar/plugs/logger.ex
Generated plugs.app
==> postgrex
warning: the dependency postgrex requires Elixir "~> 0.15.0" but you are running on v1.0.0
Compiled lib/postgrex/binary_utils.ex
Compiled lib/postgrex/error.ex
Compiled lib/postgrex/structs.ex
lib/postgrex/types.ex:5: warning: unused import Postgrex.BinaryUtils

== Compilation error on file lib/postgrex/types.ex ==
** (CompileError) lib/postgrex/types.ex:97: cannot invoke local nil?/1 inside guard
    (stdlib) lists.erl:1352: :lists.mapfoldl/3
    (elixir) src/elixir_clauses.erl:53: :elixir_clauses.translate_guard/4
    (elixir) src/elixir_clauses.erl:49: :elixir_clauses."-guards/4-lc$^0/1-0-"/4
    (elixir) src/elixir_clauses.erl:39: :elixir_clauses.clause/7
    (elixir) src/elixir_clauses.erl:82: anonymous fn/5 in :elixir_clauses.do_clauses/4
    (elixir) src/elixir.erl:175: :elixir.erl_eval/3

could not compile dependency postgrex, mix compile failed. You can recompile this dependency with `mix deps.compile postgrex` or update it with `mix deps.update postgrex`

Adding { :postgrex, "~> 0.6.0" } to the mix.exs deps section gets a clean get/compile cycle. To run mix sugar.init however, it required me to also update deps/sugar/mix.exs with the upgraded postgrex version.

I have no idea if this workaround can be plugged straight in as I've only recently started learning Elixir and know next to nothing :) mix server did successfully start and I could get a "hello world" from the server, so it's working so far.

Error on mix server

I am following the getting started guide. When i run mix server i get the following error

** (FunctionClauseError) no function clause matching in Keyword.put_new/3
(elixir) lib/keyword.ex:320: Keyword.put_new(nil, :ref, Router.HTTP)
lib/plug/adapters/cowboy.ex:35: Plug.Adapters.Cowboy.args/4
lib/plug/adapters/cowboy.ex:120: Plug.Adapters.Cowboy.run/4
lib/mix/tasks/server.ex:27: Mix.Tasks.Server.run/1
(mix) lib/mix/cli.ex:55: Mix.CLI.run_task/2

I am running this on Mac Yosemite and Elixir is v1.0.2

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.