├── .gitignore ├── Gemfile ├── Gemfile.lock ├── LICENSE.md ├── Procfile ├── README.md ├── bootstrap.rb ├── config.ru ├── controllers ├── css.rb └── main.rb ├── helpers └── helper.rb ├── public └── js │ ├── jquery.js │ └── main.js ├── sample.config.yml └── views ├── index.haml ├── layout.haml └── main.scss /.gitignore: -------------------------------------------------------------------------------- 1 | *.tmp 2 | *~ 3 | *#* 4 | vendor 5 | .sass-cache 6 | .bundle 7 | config.yml 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'foreman' 4 | gem 'rack' 5 | gem 'sinatra' 6 | gem 'thin' 7 | gem 'sinatra-contrib' 8 | gem 'json' 9 | gem 'haml' 10 | gem 'sass' 11 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | backports (3.3.1) 5 | daemons (1.1.9) 6 | dotenv (0.7.0) 7 | eventmachine (1.0.3) 8 | foreman (0.63.0) 9 | dotenv (>= 0.7) 10 | thor (>= 0.13.6) 11 | haml (4.0.3) 12 | tilt 13 | json (1.8.0) 14 | rack (1.5.2) 15 | rack-protection (1.5.0) 16 | rack 17 | rack-test (0.6.2) 18 | rack (>= 1.0) 19 | sass (3.2.9) 20 | sinatra (1.4.2) 21 | rack (~> 1.5, >= 1.5.2) 22 | rack-protection (~> 1.4) 23 | tilt (~> 1.3, >= 1.3.4) 24 | sinatra-contrib (1.4.0) 25 | backports (>= 2.0) 26 | eventmachine 27 | rack-protection 28 | rack-test 29 | sinatra (~> 1.4.2) 30 | tilt (~> 1.3) 31 | thin (1.5.1) 32 | daemons (>= 1.0.9) 33 | eventmachine (>= 0.12.6) 34 | rack (>= 1.0.0) 35 | thor (0.18.1) 36 | tilt (1.4.1) 37 | 38 | PLATFORMS 39 | ruby 40 | 41 | DEPENDENCIES 42 | foreman 43 | haml 44 | json 45 | rack 46 | sass 47 | sinatra 48 | sinatra-contrib 49 | thin 50 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | LICENSE 2 | ======= 3 | (The MIT License) 4 | 5 | Copyright (c) 2012-2013 Sho Hashimoto 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | 'Software'), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec rackup config.ru -p $PORT 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sinatra Template (Omikuji) 2 | ========================== 3 | Web App Template. 4 | 5 | * Ruby 1.8.7+ 6 | * Sinatra 1.3+ 7 | * Haml 8 | * sass(scss) 9 | * jQuery 10 | 11 | 12 | Want to Use DB? 13 | --------------- 14 | if you want to use MongoDB or MySQL, checkout branch. 15 | 16 | * https://github.com/shokai/sinatra-template/tree/mongoid 17 | * https://github.com/shokai/sinatra-template/tree/dm-mysql 18 | 19 | 20 | Clone 21 | ----- 22 | 23 | % git clone git://github.com/shokai/sinatra-template.git 24 | % cd sinatra-template 25 | 26 | 27 | Install Dependencies 28 | -------------------- 29 | 30 | % gem install bundler foreman 31 | % bundle install 32 | 33 | 34 | Config 35 | ------ 36 | 37 | % cp sample.config.yml config.yml 38 | 39 | edit it. 40 | 41 | 42 | Run 43 | --- 44 | 45 | % foreman start 46 | 47 | open http://localhost:5000 48 | 49 | 50 | Deploy 51 | ------ 52 | use Passenger with "config.ru" 53 | -------------------------------------------------------------------------------- /bootstrap.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | 3 | class Bootstrap 4 | def self.default 5 | [] 6 | end 7 | 8 | def self.init(*inits) 9 | [default, inits].flatten.uniq.each do |cat| 10 | Dir.glob("#{File.dirname(__FILE__)}/#{cat}/*.rb").each do |rb| 11 | puts "load #{rb}" 12 | require rb 13 | end 14 | end 15 | end 16 | end 17 | 18 | class Conf 19 | def self.[](key) 20 | ENV[key] || conf[key] 21 | end 22 | 23 | def self.[]=(key,value) 24 | conf[key] = value 25 | end 26 | 27 | def self.file 28 | @@file ||= File.dirname(__FILE__)+'/config.yml' 29 | end 30 | 31 | def self.file=(name) 32 | @@file = name 33 | end 34 | 35 | def self.conf 36 | begin 37 | @@conf ||= YAML::load self.open.read 38 | rescue => e 39 | STDERR.puts e 40 | STDERR.puts "config.yml load error!!" 41 | exit 1 42 | end 43 | end 44 | 45 | def self.open(opt=nil, &block) 46 | if block_given? 47 | yield File.open(self.file, opt) 48 | else 49 | return File.open(self.file, opt) 50 | end 51 | end 52 | 53 | def self.save 54 | self.open 'w+' do |f| 55 | f.write self.to_yaml 56 | end 57 | end 58 | 59 | def self.to_yaml 60 | self.conf.to_yaml 61 | end 62 | 63 | def self.to_json 64 | self.conf.to_json 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler/setup' 3 | require 'rack' 4 | require 'sinatra' 5 | $stdout.sync = true if development? 6 | require 'sinatra/reloader' if development? 7 | require 'sinatra/content_for' 8 | require 'yaml' 9 | require 'json' 10 | require 'haml' 11 | require 'sass' 12 | require File.dirname(__FILE__)+'/bootstrap' 13 | Bootstrap.init :helpers, :controllers 14 | 15 | set :haml, :escape_html => true 16 | 17 | run Sinatra::Application 18 | -------------------------------------------------------------------------------- /controllers/css.rb: -------------------------------------------------------------------------------- 1 | get '/:source.css' do 2 | scss params[:source].to_sym 3 | end 4 | -------------------------------------------------------------------------------- /controllers/main.rb: -------------------------------------------------------------------------------- 1 | before '/*.json' do 2 | content_type 'application/json' 3 | end 4 | 5 | before '/*' do 6 | @title = Conf['title'] 7 | end 8 | 9 | get '/' do 10 | haml :index 11 | end 12 | 13 | get '/omikuji.json' do 14 | @mes = { 15 | :result => Conf['omikuji'].sample, 16 | :time => Time.now.to_s 17 | }.to_json 18 | end 19 | -------------------------------------------------------------------------------- /helpers/helper.rb: -------------------------------------------------------------------------------- 1 | helpers do 2 | def app_root 3 | "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{env['SCRIPT_NAME']}" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /public/js/jquery.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v1.9.0 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license */(function(e,t){"use strict";function n(e){var t=e.length,n=st.type(e);return st.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e){var t=Tt[e]={};return st.each(e.match(lt)||[],function(e,n){t[n]=!0}),t}function i(e,n,r,i){if(st.acceptData(e)){var o,a,s=st.expando,u="string"==typeof n,l=e.nodeType,c=l?st.cache:e,f=l?e[s]:e[s]&&s;if(f&&c[f]&&(i||c[f].data)||!u||r!==t)return f||(l?e[s]=f=K.pop()||st.guid++:f=s),c[f]||(c[f]={},l||(c[f].toJSON=st.noop)),("object"==typeof n||"function"==typeof n)&&(i?c[f]=st.extend(c[f],n):c[f].data=st.extend(c[f].data,n)),o=c[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[st.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[st.camelCase(n)])):a=o,a}}function o(e,t,n){if(st.acceptData(e)){var r,i,o,a=e.nodeType,u=a?st.cache:e,l=a?e[st.expando]:st.expando;if(u[l]){if(t&&(r=n?u[l]:u[l].data)){st.isArray(t)?t=t.concat(st.map(t,st.camelCase)):t in r?t=[t]:(t=st.camelCase(t),t=t in r?[t]:t.split(" "));for(i=0,o=t.length;o>i;i++)delete r[t[i]];if(!(n?s:st.isEmptyObject)(r))return}(n||(delete u[l].data,s(u[l])))&&(a?st.cleanData([e],!0):st.support.deleteExpando||u!=u.window?delete u[l]:u[l]=null)}}}function a(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(Nt,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:wt.test(r)?st.parseJSON(r):r}catch(o){}st.data(e,n,r)}else r=t}return r}function s(e){var t;for(t in e)if(("data"!==t||!st.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function u(){return!0}function l(){return!1}function c(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function f(e,t,n){if(t=t||0,st.isFunction(t))return st.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return st.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=st.grep(e,function(e){return 1===e.nodeType});if(Wt.test(t))return st.filter(t,r,!n);t=st.filter(t,r)}return st.grep(e,function(e){return st.inArray(e,t)>=0===n})}function p(e){var t=zt.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function d(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function h(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function g(e){var t=nn.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function m(e,t){for(var n,r=0;null!=(n=e[r]);r++)st._data(n,"globalEval",!t||st._data(t[r],"globalEval"))}function y(e,t){if(1===t.nodeType&&st.hasData(e)){var n,r,i,o=st._data(e),a=st._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)st.event.add(t,n,s[n][r])}a.data&&(a.data=st.extend({},a.data))}}function v(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!st.support.noCloneEvent&&t[st.expando]){r=st._data(t);for(i in r.events)st.removeEvent(t,i,r.handle);t.removeAttribute(st.expando)}"script"===n&&t.text!==e.text?(h(t).text=e.text,g(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),st.support.html5Clone&&e.innerHTML&&!st.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Zt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function b(e,n){var r,i,o=0,a=e.getElementsByTagName!==t?e.getElementsByTagName(n||"*"):e.querySelectorAll!==t?e.querySelectorAll(n||"*"):t;if(!a)for(a=[],r=e.childNodes||e;null!=(i=r[o]);o++)!n||st.nodeName(i,n)?a.push(i):st.merge(a,b(i,n));return n===t||n&&st.nodeName(e,n)?st.merge([e],a):a}function x(e){Zt.test(e.type)&&(e.defaultChecked=e.checked)}function T(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Nn.length;i--;)if(t=Nn[i]+n,t in e)return t;return r}function w(e,t){return e=t||e,"none"===st.css(e,"display")||!st.contains(e.ownerDocument,e)}function N(e,t){for(var n,r=[],i=0,o=e.length;o>i;i++)n=e[i],n.style&&(r[i]=st._data(n,"olddisplay"),t?(r[i]||"none"!==n.style.display||(n.style.display=""),""===n.style.display&&w(n)&&(r[i]=st._data(n,"olddisplay",S(n.nodeName)))):r[i]||w(n)||st._data(n,"olddisplay",st.css(n,"display")));for(i=0;o>i;i++)n=e[i],n.style&&(t&&"none"!==n.style.display&&""!==n.style.display||(n.style.display=t?r[i]||"":"none"));return e}function C(e,t,n){var r=mn.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function k(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;4>o;o+=2)"margin"===n&&(a+=st.css(e,n+wn[o],!0,i)),r?("content"===n&&(a-=st.css(e,"padding"+wn[o],!0,i)),"margin"!==n&&(a-=st.css(e,"border"+wn[o]+"Width",!0,i))):(a+=st.css(e,"padding"+wn[o],!0,i),"padding"!==n&&(a+=st.css(e,"border"+wn[o]+"Width",!0,i)));return a}function E(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=ln(e),a=st.support.boxSizing&&"border-box"===st.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=un(e,t,o),(0>i||null==i)&&(i=e.style[t]),yn.test(i))return i;r=a&&(st.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+k(e,t,n||(a?"border":"content"),r,o)+"px"}function S(e){var t=V,n=bn[e];return n||(n=A(e,t),"none"!==n&&n||(cn=(cn||st("