{"id":13800426,"url":"https://github.com/kivra/giallo","last_synced_at":"2025-05-13T09:31:38.094Z","repository":{"id":6886311,"uuid":"8135750","full_name":"kivra/giallo","owner":"kivra","description":"Small and flexible web framework on top of Cowboy","archived":false,"fork":false,"pushed_at":"2013-08-01T07:52:02.000Z","size":310,"stargazers_count":67,"open_issues_count":0,"forks_count":6,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-11-18T15:53:27.395Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"javatechig/Advance-Android-Tutorials","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kivra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-11T09:54:37.000Z","updated_at":"2024-10-28T19:12:07.000Z","dependencies_parsed_at":"2022-07-09T14:30:58.620Z","dependency_job_id":null,"html_url":"https://github.com/kivra/giallo","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kivra%2Fgiallo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kivra%2Fgiallo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kivra%2Fgiallo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kivra%2Fgiallo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kivra","download_url":"https://codeload.github.com/kivra/giallo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253913137,"owners_count":21983264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T00:01:12.474Z","updated_at":"2025-05-13T09:31:37.035Z","avatar_url":"https://github.com/kivra.png","language":"Erlang","funding_links":[],"categories":["Web Frameworks"],"sub_categories":[],"readme":"Giallo (v0.2.0) [![Build Status](https://travis-ci.org/kivra/giallo.png?branch=master)](https://travis-ci.org/kivra/giallo)\n======\n\nGiallo (Italian pronunciation: [ˈdʒallo], plural gialli) is an Italian\n20th-century genre of literature and film, which in Italian indicates crime\nfiction and mystery.\n\nGiallo is released under the terms of the [MIT](http://en.wikipedia.org/wiki/MIT_License) license\n\nCurrent stable version: [0.2.0](https://github.com/kivra/giallo/tree/0.2.0)\n\nCurrent α alpha version: [0.3.0](https://github.com/kivra/giallo)\n\ncopyright 2012-2013 Kivra\n\nGoals\n-----\n\nGiallo aims to provide a small and flexible web framework. Giallo\nbuilds on [Cowboy](https://github.com/extend/cowboy) and provides a bare\nminimum to implement a basic View-Controller pattern. Yes we've removed\nthe Model from MVC, this is not a \"everything but the kitchen sink\" type of\nframework.\n\nGiallo can easily be embedded and provides some conveinient methods for\nworking with Controller and Views while still giving you possibility to use\nstandard Cowboy features when necessary.\n\nExamples\n--------\n\nHere's some [examples](https://github.com/kivra/giallo_examples) that will\nshow Giallo in action.\n\nGetting Started\n----\n\nA minimal working app could look like this:\n\n```erlang\n-module(minimal_handler).\n\n-export([start/0]).\n-export([hi/4]).\n\nstart() -\u003e\n    giallo:start([{'_', [{\"/[...]\", minimal_handler, []}]}]).\n\nhi(\u003c\u003c\"GET\"\u003e\u003e, _PathInfo, _Extra, _Req) -\u003e\n\t{output, \u003c\u003c\"Ohai!\"\u003e\u003e}.\n\n```\n\nThis would map the `my_handler` using standard Cowboy\n[Routing](http://ninenines.eu/docs/en/cowboy/HEAD/guide/routing) to the\nURI `http://yourserver/`. Implementing the action `hi` would make\nGiallo output \"Ohai!\" when performing a GET on `/hi` or anything\nbelow `/hi/extra...`. Any Giallo action that is implemented, such as `hi/4`\ngets precedence over the standard Cowboy Handler.\n\nThe first argument is the HTTP method being used.\n\nThe `_PathInfo` argument contains any extra url fragments as binaries in a\nlist such as `/hi/extra/path/information` would give a list like\n`[\u003c\u003c\"extra\"\u003e\u003e, \u003c\u003c\"path\"\u003e\u003e, \u003c\u003c\"information\"\u003e\u003e]`. The exact match, i.e.\n`/hi` would result in an empty list, `[]`.\n\nThe third argument contains any extra variables that either get passed\nfrom the cowboy dispatcher or via an other action redispatching using\n`action_other` or from the before_/4 function.\n\nThe `Req` argument is the standard Cowboy [Request]\n(https://github.com/extend/cowboy/blob/master/src/cowboy_req.erl#L128) Object.\nIt's an opaque record so take a look at the functions in\n[cowboy_req.erl]\n(https://github.com/extend/cowboy/blob/master/src/cowboy_req.erl) on how\nto use it.\n\nIt's also possible to use standard Cowboy handlers and also to mix the\ntwo behaviors, i.e.\n\n```erlang\n-module(default_handler).\n\n-export([start/0]).\n-export([hi/4]).\n\n%% Standard Cowboy callback handlers\n-export([init/3]).\n-export([handle/2]).\n-export([terminate/3]).\n\n\nstart() -\u003e\n    giallo:start([{'_', [{\"/[...]\", default_handler, []}]}]).\n\n%% Standard Cowboy callback handlers\ninit(_Transport, Req, []) -\u003e\n\t{ok, Req, undefined}.\n\nhandle(Req, State) -\u003e\n\t{ok, Req2} = cowboy_req:reply(200, [], \u003c\u003c\"Hello World!\"\u003e\u003e, Req),\n\t{ok, Req2, State}.\n\nterminate(_Reason, _Req, _State) -\u003e\n\tok.\n\n%% Giallo handler\nhi(\u003c\u003c\"GET\"\u003e\u003e, _PathInfo, _Extra, _Req) -\u003e\n\t{output, \u003c\u003c\"Ohai!\"\u003e\u003e}.\n\n```\n\nThis would output \"Ohai!\" for the same URI's as the previous example but\nfor anything else it would use the standard Cowboy `handle/2` function.\nSo any Giallo function takes precedence over Cowboy handlers.\n\nIndex action\n------------\n\n`index_/4` is a special action that can be implemented and will handle\nresource listings, i.e. `http://my.server/path/`. Any handler mapped to\n`/path/` will have it's `index_` function executed. `index_` functions\nbehave the same as any other function and can thus use templating, etc.\n\n```erlang\nindex_(\u003c\u003c\"GET\"\u003e\u003e, [], _Extra, _Req) -\u003e\n    {output, \u003c\u003c\"Index listing\"\u003e\u003e}.\n\n```\n\nTemplating\n----------\n\nGiallo uses [ErlyDTL](https://github.com/evanmiller/erlydtl) for\nstandard templating. To dispatch a request from a Giallo controller you\nreturn `ok`, `{ok, Variables}` or `{ok, Variables, Headers}`. Giallo\nwill then render the template associated with that controller and\naction. Giallo compounds the template name as `\u003ccontroller\u003e_\u003caction\u003e`.\n\nYou control how you compile your ErlyDtl templates through rebar. Using\nthe `erlydtl_opts` directive you can specify where to find your\ntemplates:\n\n```erlang\n{erlydtl_opts, [\n    {doc_root, \"templates\"}, % Where to find your templates\n    {source_ext, \".html\"} % Extension on your uncomplied templates\n]}.\n\n```\n\nWith these ErlyDTL options you would create your templates such as\n`controller_action.html`\n\nSession Management\n------------------\n\nIf you need Session Management you'll have to include the [Giallo\nSession Backend](https://github.com/kivra/giallo_session).\n\nbefore_ function\n----------------\n\nThere's a special function which can be implemented called before_/2\nwhich can be used to preprocess any request before dispatching to any\naction. This is especially useful when implementing an authentication\nscheme.\n\nThe function header looks like:\n\n```erlang\nbefore_(_Action, _Req) -\u003e\n    {ok, []}.\n\n```\n\nThe first parameter is the Action that is to be performed after\n`before_` has been complete, it's supplied as an atom, i.e. `action_name`.\nThe second parameter is the standard Req object.\n\nPossible return values are:\n\n#### `{ok, Extra}` ####\nExtra will get passed as the third argument to the action and as a\nvariable called `_before` to any template\n\n#### `{redirect, Location}` ####\nRedirect to the `Location` effectively bypassing the Action\n\nReturn values\n-------------\n\nHere's a list of possible return values from a Giallo controller.\n\nAll return values can take an optional `Req :: cowboy_req:req()` as the last\nparameter. This is especially useful if you need to set anything special\nto the response, like cookies, sessions, etc.\n\n#### `ok` ####\nContinue and render the template for the corresponding action\n\n#### `{ok, Variables::proplist()}` ####\nSame as above but pass `Variables` to the template. Variables can then be outputted in\nthe template as `{{ variable_name }}`\n\n#### `{ok, Variables::proplist(), Headers::proplist()}` ###\nSame as above but also set additional HTTP Headers\n\n#### `{redirect, Location::binary()` ###\nSend a 302 redirect to the `Location`\n\n#### `{redirect, Location::binary(), Headers::proplist()}` ###\nSame as above but also set additional HTTP Headers\n\n#### `{moved, Location::binary()}` ###\nSend a 301 redirect to the `Location`\n\n#### `{moved, Location::binary(), Headers::proplist()}` ###\nSame as above but also set additional HTTP Headers\n\n#### `{action_other, Location::proplist()}` ###\nPossible values for `Location` are `[{action, your_action}, {controller, your_handler}]`.\nIf `controller` is ommitted it will assume the current handler.\n\n#### `{action_other, Location::proplist(), Variables::proplist()}` ###\nSame as above but pass `Variables` that can be retrieved from the\ncontroller.\n\n#### `{render_other,  Location::proplist()}` ###\nRender the view associated with the Action at `Location`. Possible values\nfor `Location` are `[{action, your_action}, {controller, your_handler}]`.\nIf `controller` is ommitted it will assume the current handler.\n\n#### `{render_other,  Location::proplist(), Variables::proplist()}` ###\nSame as above but pass `Variables` that can be retrieved in the\ntemplate. Possible values for `Location` are\n`[{action, your_action}, {controller, your_handler}]`.\nIf `controller` is ommitted it will assume the current handler.\n\n#### `{output, Output::binary()}` ###\nprint out the `Output`\n\n#### `{output, Output::binary(), Headers::proplist()}` ###\nSame as above but also set additional HTTP Headers\n\n#### `{stream, Generator::function(), Acc0::any()}` ###\nStream a response to the client using HTTP chunked encoding. For each chunk,\nthe Generator function is passed an accumulator (initally Acc0) and should\nreturn either {output, Data, Acc1} or done. I.e:\n\n```erlang\n\nstream(\u003c\u003c\"GET\"\u003e\u003e, _Pathinfo, _Extra, _Req) -\u003e\n    F = fun(Acc) -\u003e\n            case Acc =:= 3 of\n                true  -\u003e done;\n                false -\u003e {output, \u003c\u003c\"Hello\\n\"\u003e\u003e, Acc+1}\n            end\n    end,\n    {stream, F, 0}.\n\n```\n\n#### `{stream, Generator::function(), Acc::any(), Headers::proplist()}` ###\nSame as above but also set additional HTTP Headers\n\n#### `{json, Data::proplist()}` ###\nEncode the `Data` as json and output\n\n#### `{json, Data::proplist(), Headers::proplist()}` ###\nSame as above but also set additional HTTP Headers\n\n#### `{jsonp, Callback::string(), Data::proplist()}` ###\nEncode the `Data` as valid jsonp using the `Callback`\n\n#### `{jsonp, Callback::string(), Data::proplist(), Headers::proplist()}` ###\nSame as above but also set additional HTTP Headers\n\n#### `not_found` ###\nRespond with a 404\n\n#### `{error, Status::integer()}` ###\nRespond with the given error Status Code\n\nRequest processing\n-------------\n\nThere is some conventience-functions for working with headers,\nquerystrings, multipart-data, etc. Please generate and look at the docs:\n```\n\nmake doc\n\n```\n\n## License\nIt's the [MIT license](http://en.wikipedia.org/wiki/MIT_License). So go ahead\nand do what you want!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkivra%2Fgiallo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkivra%2Fgiallo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkivra%2Fgiallo/lists"}