allegro 0.0.0pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ Allegro
2
+ =======
3
+ (tryin' to improve cloudhead's toto)
4
+ -------------------------------------
5
+ 0. Install the gem.
6
+ 1. run:
7
+ allegro new myblog
8
+ 2. enjoy
9
+
10
+
11
+ -------------------------------------
12
+ _...of this astounding life down here_
13
+ _and of the strange clowns in control of it_
14
+
15
+ _**Lawrence Ferlinghetti**_
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/ruby -w
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'allegro'
6
+ require 'optparse'
7
+
8
+ case ARGV.first
9
+ when 'new', 'n'
10
+ # stub out the project
11
+ Allegro.stub(ARGV[1])
12
+ end
13
+
@@ -0,0 +1,53 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ LIBDIR = File.dirname(__FILE__)
3
+
4
+ require 'yaml'
5
+ require 'date'
6
+ require 'erb'
7
+ require 'rack'
8
+ require 'digest'
9
+ require 'open-uri'
10
+ require 'rdiscount'
11
+ require 'builder'
12
+ require 'fileutils'
13
+
14
+ require 'allegro/ext/ext'
15
+ require 'allegro/version'
16
+ require 'allegro/template'
17
+ require 'allegro/site'
18
+ require 'allegro/repo'
19
+ require 'allegro/context'
20
+ require 'allegro/archives'
21
+ require 'allegro/article'
22
+ require 'allegro/server'
23
+
24
+ module Allegro
25
+ Paths = {
26
+ :templates => "templates",
27
+ :pages => "templates/pages",
28
+ :articles => "articles"
29
+ }
30
+
31
+ def self.env
32
+ ENV['RACK_ENV'] || 'production'
33
+ end
34
+
35
+ def self.env= env
36
+ ENV['RACK_ENV'] = env
37
+ end
38
+
39
+ def self.stub(blog)
40
+ puts "\nAllegro is...\n - \033[32mCreating\033[0m your blog '#{blog}'"
41
+ Dir.mkdir blog
42
+
43
+ puts " - \033[32mCopying\033[0m blog template"
44
+ FileUtils.cp_r( Dir.glob(File.join(LIBDIR, 'template/*')), blog )
45
+
46
+ puts "\n \033[32mCongratulations, '#{blog}' is ready to go!\033[0m"
47
+ rescue Errno::EEXIST
48
+ puts "\n \033[31muh oh, directory '#{blog}' already exists...\033[0m"
49
+ exit
50
+ end
51
+
52
+ end
53
+
@@ -0,0 +1,21 @@
1
+ module Allegro
2
+ class Archives < Array
3
+ include Template
4
+
5
+ def initialize articles, config
6
+ self.replace articles
7
+ @config = config
8
+ end
9
+
10
+ def [] a
11
+ a.is_a?(Range) ? self.class.new(self.slice(a) || [], @config) : super
12
+ end
13
+
14
+ def to_html
15
+ super(:archives, @config)
16
+ end
17
+ alias :to_s to_html
18
+ alias :archive archives
19
+ end
20
+ end
21
+
@@ -0,0 +1,103 @@
1
+ module Allegro
2
+
3
+ class Article < Hash
4
+ include Template
5
+
6
+ def initialize obj, config = {}
7
+ @obj, @config = obj, config
8
+ self.load if obj.is_a? Hash
9
+ end
10
+
11
+ def load
12
+ data = if @obj.is_a? String
13
+ meta, self[:body] = File.read(@obj).split(/\n\n/, 2)
14
+
15
+ # use the date from the filename, or else allegro won't find the article
16
+ @obj =~ /\/(\d{4}-\d{2}-\d{2})[^\/]*$/
17
+ ($1 ? {:date => $1} : {}).merge(YAML.load(meta))
18
+ elsif @obj.is_a? Hash
19
+ @obj
20
+ end.inject({}) {|h, (k,v)| h.merge(k.to_sym => v) }
21
+
22
+ self.taint
23
+ self.update data
24
+ self[:date] = Date.parse(self[:date].gsub('/', '-')) rescue Date.today
25
+ self
26
+ end
27
+
28
+ def [] key
29
+ self.load unless self.tainted?
30
+ super
31
+ end
32
+
33
+ def slug
34
+ self[:slug] || self[:title].slugize
35
+ end
36
+
37
+ def summary length = nil
38
+ config = @config[:summary]
39
+ sum = if self[:body] =~ config[:delim]
40
+ self[:body].split(config[:delim]).first
41
+ else
42
+ self[:body].match(/(.{1,#{length || config[:length] || config[:max]}}.*?)(\n|\Z)/m).to_s
43
+ end
44
+ markdown(sum.length == self[:body].length ? sum : sum.strip.sub(/\.\Z/, '&hellip;'))
45
+ end
46
+
47
+ def url
48
+ "http://#{(@config[:url].sub("http://", '') + self.path).squeeze('/')}"
49
+ end
50
+ alias :permalink url
51
+
52
+ def body
53
+ markdown self[:body].sub(@config[:summary][:delim], '') rescue markdown self[:body]
54
+ end
55
+
56
+ def path
57
+ "/#{@config[:prefix]}#{self[:date].strftime("/%Y/%m/%d/#{slug}/")}".squeeze('/')
58
+ end
59
+
60
+ def title() self[:title] || "an article" end
61
+ def date() @config[:date].call(self[:date]) end
62
+ def author() self[:author] || @config[:author] end
63
+ def to_html() self.load; super(:article, @config) end
64
+ alias :to_s to_html
65
+ end
66
+
67
+ class Config < Hash
68
+ Defaults = {
69
+ :author => ENV['USER'], # blog author
70
+ :title => Dir.pwd.split('/').last, # site title
71
+ :root => "index", # site index
72
+ :url => "http://127.0.0.1", # root URL of the site
73
+ :prefix => "", # common path prefix for the blog
74
+ :date => lambda {|now| now.strftime("%d/%m/%Y") }, # date function
75
+ :markdown => :smart, # use markdown
76
+ :disqus => false, # disqus name
77
+ :summary => {:max => 150, :delim => /~\n/}, # length of summary and delimiter
78
+ :ext => 'txt', # extension for articles
79
+ :cache => 28800, # cache duration (seconds)
80
+ :github => {:user => "", :repos => [], :ext => 'md'}, # Github username and list of repos
81
+ :to_html => lambda {|path, page, ctx| # returns an html, from a path & context
82
+ ERB.new(File.read("#{path}/#{page}.rhtml")).result(ctx)
83
+ },
84
+ :error => lambda {|code| # The HTML for your error page
85
+ "<font style='font-size:300%'>allegro, we're not in Kansas anymore (#{code})</font>"
86
+ }
87
+ }
88
+ def initialize obj
89
+ self.update Defaults
90
+ self.update obj
91
+ end
92
+
93
+ def set key, val = nil, &blk
94
+ if val.is_a? Hash
95
+ self[key].update val
96
+ else
97
+ self[key] = block_given?? blk : val
98
+ end
99
+ end
100
+ end
101
+
102
+ end
103
+
@@ -0,0 +1,45 @@
1
+ module Allegro
2
+
3
+ class Site
4
+
5
+ class Context
6
+ include Template
7
+ attr_reader :env
8
+
9
+ def initialize ctx = {}, config = {}, path = "/", env = {}
10
+ @config, @context, @path, @env = config, ctx, path, env
11
+ @articles = Site.articles(@config[:ext]).reverse.map do |a|
12
+ Article.new(a, @config)
13
+ end
14
+
15
+ ctx.each do |k, v|
16
+ meta_def(k) { ctx.instance_of?(Hash) ? v : ctx.send(k) }
17
+ end
18
+ end
19
+
20
+ def title
21
+ @config[:title]
22
+ end
23
+
24
+ def render page, type
25
+ if type == :html
26
+ content = to_html page, @config
27
+ to_html(:layout, @config, &Proc.new { content })
28
+ else
29
+ send(:"to_#{type}", page)
30
+ end
31
+ end
32
+
33
+ def to_xml page
34
+ xml = Builder::XmlMarkup.new(:indent => 2)
35
+ instance_eval File.read("#{Paths[:templates]}/#{page}.builder")
36
+ end
37
+ alias :to_atom to_xml
38
+
39
+ def method_missing m, *args, &blk
40
+ @context.respond_to?(m) ? @context.send(m, *args, &blk) : super
41
+ end
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,46 @@
1
+ class Object
2
+ def meta_def name, &blk
3
+ (class << self; self; end).instance_eval do
4
+ define_method(name, &blk)
5
+ end
6
+ end
7
+ end
8
+
9
+ class String
10
+ def slugize
11
+ self.downcase.gsub(/&/, 'and').gsub(/\s+/, '-').gsub(/[^a-z0-9-]/, '')
12
+ end
13
+
14
+ def humanize
15
+ self.capitalize.gsub(/[-_]+/, ' ')
16
+ end
17
+ end
18
+
19
+ class Fixnum
20
+ def ordinal
21
+ # 1 => 1st
22
+ # 2 => 2nd
23
+ # 3 => 3rd
24
+ # ...
25
+ case self % 100
26
+ when 11..13; "#{self}th"
27
+ else
28
+ case self % 10
29
+ when 1; "#{self}st"
30
+ when 2; "#{self}nd"
31
+ when 3; "#{self}rd"
32
+ else "#{self}th"
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ class Date
39
+ # This check is for people running Toto with ActiveSupport, avoid a collision
40
+ unless respond_to? :iso8601
41
+ # Return the date as a String formatted according to ISO 8601.
42
+ def iso8601
43
+ ::Time.utc(year, month, day, 0, 0, 0, 0).iso8601
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ module Allegro
2
+
3
+ class Repo < Hash
4
+ include Template
5
+
6
+ README = "http://github.com/%s/%s/raw/master/README.%s"
7
+
8
+ def initialize name, config
9
+ self[:name], @config = name, config
10
+ end
11
+
12
+ def readme
13
+ markdown open(README %
14
+ [@config[:github][:user], self[:name], @config[:github][:ext]]).read
15
+ rescue Timeout::Error, OpenURI::HTTPError => e
16
+ "This page isn't available."
17
+ end
18
+ alias :content readme
19
+ end
20
+ end
21
+
@@ -0,0 +1,42 @@
1
+ module Allegro
2
+
3
+ class Server
4
+ attr_reader :config, :site
5
+
6
+ def initialize config = {}, &blk
7
+ @config = config.is_a?(Config) ? config : Config.new(config)
8
+ @config.instance_eval(&blk) if block_given?
9
+ @site = Allegro::Site.new(@config)
10
+ end
11
+
12
+ def call env
13
+ @request = Rack::Request.new env
14
+ @response = Rack::Response.new
15
+
16
+ return [400, {}, []] unless @request.get?
17
+
18
+ path, mime = @request.path_info.split('.')
19
+ route = (path || '/').split('/').reject {|i| i.empty? }
20
+
21
+ response = @site.go(route, *(mime ? mime : []), env)
22
+
23
+ @response.body = [response[:body]]
24
+ @response['Content-Length'] = response[:body].length.to_s unless response[:body].empty?
25
+ @response['Content-Type'] = Rack::Mime.mime_type(".#{response[:type]}")
26
+
27
+ # Set http cache headers
28
+ @response['Cache-Control'] = if Allegro.env == 'production'
29
+ "public, max-age=#{@config[:cache]}"
30
+ else
31
+ "no-cache, must-revalidate"
32
+ end
33
+
34
+ @response['ETag'] = %("#{Digest::SHA1.hexdigest(response[:body])}")
35
+
36
+ @response.status = response[:status]
37
+ @response.finish
38
+ end
39
+ end
40
+
41
+ end
42
+
@@ -0,0 +1,94 @@
1
+ module Allegro
2
+
3
+ class Site
4
+ def initialize config
5
+ @config = config
6
+ end
7
+
8
+ def [] *args
9
+ @config[*args]
10
+ end
11
+
12
+ def []= key, value
13
+ @config.set key, value
14
+ end
15
+
16
+ def index type = :html
17
+ articles = type == :html ? self.articles.reverse : self.articles
18
+ {:articles => articles.map do |article|
19
+ Article.new article, @config
20
+ end}.merge archives
21
+ end
22
+
23
+ def archives filter = ""
24
+ entries = ! self.articles.empty??
25
+ self.articles.select do |a|
26
+ filter !~ /^\d{4}/ || File.basename(a) =~ /^#{filter}/
27
+ end.reverse.map do |article|
28
+ Article.new article, @config
29
+ end : []
30
+
31
+ return :archives => Archives.new(entries, @config)
32
+ end
33
+
34
+ def article route
35
+ Article.new("#{Paths[:articles]}/#{route.join('-')}.#{self[:ext]}", @config).load
36
+ end
37
+
38
+ def /
39
+ self[:root]
40
+ end
41
+
42
+ def go route, type = :html, env
43
+ route << self./ if route.empty?
44
+ type, path = type =~ /html|xml|json/ ? type.to_sym : :html, route.join('/')
45
+ context = lambda do |data, page|
46
+ Context.new(data, @config, path, env).render(page, type)
47
+ end
48
+
49
+ body, status = if Context.new.respond_to?(:"to_#{type}")
50
+ if route.first =~ /\d{4}/
51
+ case route.size
52
+ when 1..3
53
+ context[archives(route * '-'), :archives]
54
+ when 4
55
+ context[article(route), :article]
56
+ else http 400
57
+ end
58
+ elsif respond_to?(path)
59
+ context[send(path, type), path.to_sym]
60
+ elsif (repo = @config[:github][:repos].grep(/#{path}/).first) &&
61
+ !@config[:github][:user].empty?
62
+ context[Repo.new(repo, @config), :repo]
63
+ else
64
+ context[{}, path.to_sym]
65
+ end
66
+ else
67
+ http 400
68
+ end
69
+
70
+ rescue Errno::ENOENT => e
71
+ return :body => http(404).first, :type => :html, :status => 404
72
+ else
73
+ return :body => body || "", :type => type, :status => status || 200
74
+ end
75
+
76
+ protected
77
+
78
+ def http code
79
+ [@config[:error].call(code), code]
80
+ end
81
+
82
+ def articles
83
+ self.class.articles self[:ext]
84
+ end
85
+
86
+ def self.articles ext
87
+ Dir["#{Paths[:articles]}/*.#{ext}"].sort_by {|entry| File.basename(entry) }
88
+ end
89
+
90
+
91
+ end
92
+
93
+ end
94
+
@@ -0,0 +1,30 @@
1
+ module Allegro
2
+
3
+ module Template
4
+ def to_html page, config, &blk
5
+ path = ([:layout, :repo].include?(page) ? Paths[:templates] : Paths[:pages])
6
+ config[:to_html].call(path, page, binding)
7
+ end
8
+
9
+ def markdown text
10
+ if (options = @config[:markdown])
11
+ Markdown.new(text.to_s.strip, *(options.eql?(true) ? [] : options)).to_html
12
+ else
13
+ text.strip
14
+ end
15
+ end
16
+
17
+ def method_missing m, *args, &blk
18
+ self.keys.include?(m) ? self[m] : super
19
+ end
20
+
21
+ def self.included obj
22
+ obj.class_eval do
23
+ define_method(obj.to_s.split('::').last.downcase) { self }
24
+ end
25
+ end
26
+ end
27
+
28
+
29
+ end
30
+
@@ -0,0 +1,3 @@
1
+ module Allegro
2
+ Version = VERSION = '0.0.0pre'
3
+ end
@@ -0,0 +1,4 @@
1
+ dorothy
2
+ =======
3
+
4
+ A wonderful template for [toto](http://cloudhead.io/toto), the blogging engine.
@@ -0,0 +1,42 @@
1
+ require 'toto'
2
+
3
+ @config = Toto::Config::Defaults
4
+
5
+ task :default => :new
6
+
7
+ desc "Create a new article."
8
+ task :new do
9
+ title = ask('Title: ')
10
+ slug = title.empty?? nil : title.strip.slugize
11
+
12
+ article = {'title' => title, 'date' => Time.now.strftime("%d/%m/%Y")}.to_yaml
13
+ article << "\n"
14
+ article << "Once upon a time...\n\n"
15
+
16
+ path = "#{Toto::Paths[:articles]}/#{Time.now.strftime("%Y-%m-%d")}#{'-' + slug if slug}.#{@config[:ext]}"
17
+
18
+ unless File.exist? path
19
+ File.open(path, "w") do |file|
20
+ file.write article
21
+ end
22
+ toto "an article was created for you at #{path}."
23
+ else
24
+ toto "I can't create the article, #{path} already exists."
25
+ end
26
+ end
27
+
28
+ desc "Publish my blog."
29
+ task :publish do
30
+ toto "publishing your article(s)..."
31
+ `git push heroku master`
32
+ end
33
+
34
+ def toto msg
35
+ puts "\n toto ~ #{msg}\n\n"
36
+ end
37
+
38
+ def ask message
39
+ print message
40
+ STDIN.gets.chomp
41
+ end
42
+
@@ -0,0 +1,7 @@
1
+ title: The Wonderful Wizard of Oz
2
+ author: Lyman Frank Baum
3
+ date: 1900/05/17
4
+
5
+ Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry,
6
+ who was a farmer, and Aunt Em, who was the farmer's wife.
7
+
@@ -0,0 +1,35 @@
1
+
2
+ require 'allegro'
3
+
4
+ # Rack config
5
+ use Rack::Static, :urls => ['/css', '/js', '/images', '/favicon.ico'], :root => 'public'
6
+ use Rack::CommonLogger
7
+
8
+ if ENV['RACK_ENV'] == 'development'
9
+ use Rack::ShowExceptions
10
+ end
11
+
12
+ #
13
+ # Create and configure a toto instance
14
+ #
15
+ allegro = Allegro::Server.new do
16
+ #
17
+ # Add your settings here
18
+ # set [:setting], [value]
19
+ #
20
+ # set :author, ENV['USER'] # blog author
21
+ # set :title, Dir.pwd.split('/').last # site title
22
+ # set :root, "index" # page to load on /
23
+ # set :date, lambda {|now| now.strftime("%d/%m/%Y") } # date format for articles
24
+ # set :markdown, :smart # use markdown + smart-mode
25
+ # set :disqus, false # disqus id, or false
26
+ # set :summary, :max => 150, :delim => /~/ # length of article summary and delimiter
27
+ # set :ext, 'txt' # file extension for articles
28
+ # set :cache, 28800 # cache duration, in seconds
29
+
30
+ set :date, lambda {|now| now.strftime("%B #{now.day.ordinal} %Y") }
31
+ end
32
+
33
+ run allegro
34
+
35
+
@@ -0,0 +1,110 @@
1
+ html { margin: 20px }
2
+ body {
3
+ margin: 0 auto;
4
+ font-family: 'Baskerville', Georgia, Times, serif;
5
+ font-size: 20px;
6
+ line-height: 30px;
7
+ padding: 15px;
8
+ width: 720px;
9
+
10
+ }
11
+ header, footer, section, article {
12
+ display: block;
13
+ }
14
+ #content {
15
+ }
16
+ #by {
17
+ font-style: italic;
18
+ margin-right: 5px;
19
+ font-size: 28px;
20
+ }
21
+ #caption {
22
+ position: absolute;
23
+ font-size: 24px;
24
+ margin: -135px 0 0 70px;
25
+ }
26
+ #path {
27
+ color: #b53131;
28
+ }
29
+ .date {
30
+ font-style: italic;
31
+ float: right;
32
+ line-height: 43px;
33
+ margin-right: 30px;
34
+ }
35
+ a {
36
+ color: #b83000;
37
+ }
38
+ h1 a {
39
+ color: black;
40
+ text-decoration: none;
41
+ }
42
+ a:hover {
43
+ text-decoration: underline;
44
+ }
45
+ body > header > h1 {
46
+ border-left: 30px solid black;
47
+ padding-left: 30px;
48
+ font-size: 201px;
49
+ margin: 100px 0 15px 0;
50
+ font-weight: normal;
51
+ }
52
+ .post header {
53
+ margin-bottom: 10px;
54
+ }
55
+ .post .body p:first-child {
56
+ margin-top: 0;
57
+ }
58
+ .post .body p:last-child {
59
+ margin-bottom: 0;
60
+ }
61
+ .post {
62
+ margin-bottom: 30px;
63
+ }
64
+ .post:last-child {
65
+ margin-bottom: 10px;
66
+ }
67
+ .post p {
68
+ margin: 10px 0;
69
+ }
70
+ .post .more {
71
+ margin-top: -10px;
72
+ margin-right: 30px;
73
+ font-style: italic;
74
+ text-align: right;
75
+ }
76
+ .more a {
77
+ text-decoration: none;
78
+ }
79
+ .more a:hover { text-decoration: underline }
80
+ body > header {
81
+ display: block;
82
+ padding-top: 30px;
83
+ line-height: 180px;
84
+ margin-bottom: 20px;
85
+ }
86
+ h1, h2, h3, h4 {
87
+ display: inline;
88
+ margin: 0;
89
+ font-weight: 600;
90
+ }
91
+ ul, li {
92
+ list-style-type: none;
93
+ }
94
+ code {
95
+ font-family: 'Anonymous Pro', 'Bitstream Vera Sans', 'Monaco', Courier, mono;
96
+ }
97
+ pre {
98
+ padding: 20px;
99
+ }
100
+ blockquote {
101
+ font-style: italic;
102
+ }
103
+
104
+ body > footer {
105
+ text-align: left;
106
+ margin-left: 10px;
107
+ font-style: italic;
108
+ font-size: 18px;
109
+ color: #888;
110
+ }
@@ -0,0 +1,21 @@
1
+ xml.instruct!
2
+ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
3
+ xml.title @config[:title]
4
+ xml.id @config[:url]
5
+ xml.updated articles.first[:date].iso8601 unless articles.empty?
6
+ xml.author { xml.name @config[:author] }
7
+
8
+ articles.reverse[0...10].each do |article|
9
+ xml.entry do
10
+ xml.title article.title
11
+ xml.link "rel" => "alternate", "href" => article.url
12
+ xml.id article.url
13
+ xml.published article[:date].iso8601
14
+ xml.updated article[:date].iso8601
15
+ xml.author { xml.name @config[:author] }
16
+ xml.summary article.summary, "type" => "html"
17
+ xml.content article.body, "type" => "html"
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,18 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" type="text/css" href="/css/main.css">
5
+ <link rel="alternate" type="application/atom+xml" title="<%= title %> - feed" href="/index.xml" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
7
+ <title><%= title %></title>
8
+ </head>
9
+ <body>
10
+ <section>
11
+ <%= yield %>
12
+ </section>
13
+ <footer>
14
+ powered by <a href="http://cloudhead.io/toto">toto</a>
15
+ </footer>
16
+ </body>
17
+ </html>
18
+
@@ -0,0 +1,11 @@
1
+ <h1><%= @path %></h1>
2
+ <ul>
3
+ <% if archives.length > 0 %>
4
+ <% for entry in archives %>
5
+ <li>
6
+ <a href="<%= entry.path %>"><%= entry.title %></a>
7
+ </li>
8
+ <% end %>
9
+ <% end %>
10
+ </ul>
11
+
@@ -0,0 +1,20 @@
1
+ <article class="post">
2
+ <header>
3
+ <h1><%= title %></h1>
4
+ <span class="date"><%= date %></span>
5
+ </header>
6
+
7
+ <section class="content">
8
+ <%= body %>
9
+ </section>
10
+
11
+ <section class="comments">
12
+ <% if @config[:disqus] %>
13
+ <div id="disqus_thread"></div>
14
+ <script type="text/javascript" src="http://disqus.com/forums/<%= @config[:disqus] %>/embed.js"> </script>
15
+ <noscript><a href="http://<%= @config[:disqus] %>.disqus.com/?url=ref">View the discussion thread.</a></noscript>
16
+ <a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
17
+ <% end %>
18
+ </section>
19
+ </article>
20
+
@@ -0,0 +1,20 @@
1
+ <section id="articles">
2
+ <% for article in articles[0...3] %>
3
+ <article class="post">
4
+ <header>
5
+ <h1><a href="<%= article.path %>"><%= article.title %></a></h1>
6
+ <span class="date"><%= article.date %></span>
7
+ </header>
8
+
9
+ <section class="content">
10
+ <%= article.summary %>
11
+ </section>
12
+ <div class="more"><a href="<%= article.path %>">read on &raquo;</a></div>
13
+ </article>
14
+ <% end %>
15
+ </section>
16
+
17
+ <section id="archives">
18
+ <%= archives[3..-1] %>
19
+ </section>
20
+
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: allegro
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: true
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 0pre
9
+ version: 0.0.0pre
10
+ platform: ruby
11
+ authors:
12
+ - Ermenegildo Fiorito
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-09-23 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: a pure ruby blog system based on cloudhead's toto
22
+ email: fiorito.g@gmail.com
23
+ executables:
24
+ - allegro
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - README.md
31
+ - lib/template/public/css/main.css
32
+ - lib/template/Rakefile
33
+ - lib/template/articles/1900-05-17-the-wonderful-wizard-of-oz.txt
34
+ - lib/template/templates/pages/article.rhtml
35
+ - lib/template/templates/pages/archives.rhtml
36
+ - lib/template/templates/pages/index.rhtml
37
+ - lib/template/templates/pages/about.rhtml
38
+ - lib/template/templates/index.builder
39
+ - lib/template/templates/layout.rhtml
40
+ - lib/template/config.ru
41
+ - lib/template/README
42
+ - lib/allegro.rb
43
+ - lib/allegro/version.rb
44
+ - lib/allegro/template.rb
45
+ - lib/allegro/site.rb
46
+ - lib/allegro/ext/ext.rb
47
+ - lib/allegro/context.rb
48
+ - lib/allegro/article.rb
49
+ - lib/allegro/archives.rb
50
+ - lib/allegro/server.rb
51
+ - lib/allegro/repo.rb
52
+ - bin/allegro
53
+ has_rdoc: true
54
+ homepage: http://github.com/fyskij/allegro
55
+ licenses: []
56
+
57
+ post_install_message: " \n \n ...of this astounding life down here\n and of the strange clowns in control of it\n\n -L. F.\n \n \n"
58
+ rdoc_options: []
59
+
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">"
74
+ - !ruby/object:Gem::Version
75
+ segments:
76
+ - 1
77
+ - 3
78
+ - 1
79
+ version: 1.3.1
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.7
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: enjoy blogging
87
+ test_files: []
88
+