semi_static 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/README.md +3 -0
  4. data/Rakefile +6 -0
  5. data/app/controllers/semi_static/news_controller.rb +9 -0
  6. data/app/controllers/semi_static/page_controller.rb +14 -0
  7. data/app/views/semi_static/news/index.atom.builder +10 -0
  8. data/app/views/semi_static/news/index.html.erb +7 -0
  9. data/app/views/semi_static/news/show.html.erb +5 -0
  10. data/app/views/semi_static/page/index.html.erb +6 -0
  11. data/app/views/semi_static/page/show.html.erb +4 -0
  12. data/lib/semi_static.rb +26 -0
  13. data/lib/semi_static/backend.rb +20 -0
  14. data/lib/semi_static/news.rb +19 -0
  15. data/lib/semi_static/page.rb +34 -0
  16. data/lib/semi_static/page/with_locale.rb +12 -0
  17. data/lib/semi_static/rails.rb +6 -0
  18. data/lib/semi_static/rails/routes.rb +16 -0
  19. data/lib/semi_static/version.rb +3 -0
  20. data/semi_static.gemspec +28 -0
  21. data/spec/acceptance/acceptance_helper.rb +8 -0
  22. data/spec/acceptance/fake/app.rb +17 -0
  23. data/spec/acceptance/fake/app/models/event_planning_tip.rb +3 -0
  24. data/spec/acceptance/fake/app/models/news.rb +6 -0
  25. data/spec/acceptance/fake/app/views/application.html.erb +10 -0
  26. data/spec/acceptance/fake/semi_static_pages/event_planning_tips/manner.md +18 -0
  27. data/spec/acceptance/fake/semi_static_pages/news/2011-07-26-replaced-download.md +8 -0
  28. data/spec/acceptance/news_spec.rb +24 -0
  29. data/spec/acceptance/page_spec.rb +17 -0
  30. data/spec/backend_spec.rb +24 -0
  31. data/spec/news_spec.rb +12 -0
  32. data/spec/page_spec.rb +17 -0
  33. data/spec/semi_static_pages/news/2011-07-26-replaced-download.md +8 -0
  34. data/spec/spec_helper.rb +3 -0
  35. metadata +159 -0
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in semi_static.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # SemiStatic: A simple text-file based CMS for Rails
2
+
3
+ In our internal projects, such as [請求書.jp](https://www.seikyusho.jp/) and [Doorkeeper](http://www.doorkeeper.jp/), we have had the need to generate lots of text content, such as news entries or FAQ pages. SemiStatic provides you with an easy way to manage such content.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ task :default => :spec
6
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,9 @@
1
+ class SemiStatic::NewsController < SemiStatic::PageController
2
+ def index
3
+ super
4
+ respond_to do |f|
5
+ f.html
6
+ f.atom { render :layout => false }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ class SemiStatic::PageController < ApplicationController
2
+ def index
3
+ @articles = resource.all
4
+ end
5
+
6
+ def show
7
+ @article = resource.find(params[:id])
8
+ raise ActionController::RoutingError.new(url_for(:id => params[:id], :only_path => true)) unless @article
9
+ end
10
+
11
+ def resource
12
+ env["semi_static.mapping"]
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ atom_feed do |feed|
2
+ feed.title controller.resource.feed_title
3
+ feed.updated @articles.first.published_at
4
+ @articles.each do |article|
5
+ feed.entry(article) do |entry|
6
+ entry.title(article.title)
7
+ entry.content(article.body.render(self).html_safe, :type => "html")
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ <% @articles.each do |article| %>
2
+ <article>
3
+ <h1><%= link_to article, article %></h1>
4
+ <date><%= l(article.published_at, :format => :long) %></date>
5
+ <section><%= article.body.render(self).html_safe %></section>
6
+ </article>
7
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <article>
2
+ <h1><%= @article.title %></h1>
3
+ <date><%= l(@article.published_at, :format => :long) %></date>
4
+ <section><%= @article.body.render(self).html_safe %></section>
5
+ </article>
@@ -0,0 +1,6 @@
1
+ <% @articles.each do |article| %>
2
+ <article>
3
+ <h1><%= link_to article, article %></h1>
4
+ <section><%= article.body.render(self).html_safe %></section>
5
+ </article>
6
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <article>
2
+ <h1><%= @article.title %></h1>
3
+ <section><%= @article.body.render(self).html_safe %></section>
4
+ </article>
@@ -0,0 +1,26 @@
1
+ require 'active_model/naming'
2
+ require 'active_support/core_ext/module/delegation.rb'
3
+ require 'active_support/core_ext/string/output_safety'
4
+ require 'babosa'
5
+ require 'rails'
6
+ require 'rdiscount'
7
+ require 'tilt'
8
+ require 'yaml'
9
+
10
+ require "semi_static/version"
11
+
12
+ module SemiStatic
13
+ autoload :News, "semi_static/news"
14
+ autoload :Article, "semi_static/article"
15
+ autoload :Page, "semi_static/page"
16
+ autoload :Backend, "semi_static/backend"
17
+
18
+ class << self
19
+ attr_writer :backend
20
+ def backend
21
+ @backend ||= Backend.new(Rails.root.join("semi_static_pages"))
22
+ end
23
+ end
24
+ end
25
+
26
+ require "semi_static/rails"
@@ -0,0 +1,20 @@
1
+ class SemiStatic::Backend < SemiStatic::Page
2
+
3
+ def initialize(root)
4
+ @root = root
5
+ @cache = {}
6
+ end
7
+
8
+ def all(page_type)
9
+ unless @cache.key?(page_type)
10
+ path = File.join(@root,ActiveModel::Naming.plural(page_type), "*")
11
+ @cache[page_type] = Dir.glob(path).map do |f|
12
+ yaml, body = File.read(f).split("\n...\n", 2)
13
+ h = YAML.load(yaml)
14
+ template = Tilt.new(f) {|template| body }
15
+ page_type.new(template, h)
16
+ end
17
+ end
18
+ @cache[page_type]
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ class SemiStatic::News < SemiStatic::Page
4
+ attr_accessor :published_at
5
+ delegate :year, :month, :day, :to => :published_at
6
+
7
+ def self.all
8
+ super.sort_by(&:published_at).reverse
9
+ end
10
+
11
+ # used for atom feed
12
+ def id
13
+ Digest::MD5.hexdigest to_param
14
+ end
15
+
16
+ def to_param
17
+ "#{year}/#{month}/#{day}/#{super}"
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ class SemiStatic::Page
2
+ autoload :WithLocale, "semi_static/page/with_locale"
3
+
4
+ extend ActiveModel::Naming
5
+ attr_accessor :title, :body
6
+
7
+ def self.all
8
+ SemiStatic.backend.all(self)
9
+ end
10
+
11
+ def self.first
12
+ all.first
13
+ end
14
+
15
+ def self.find(param)
16
+ all.find {|a| a.to_param == param }
17
+ end
18
+
19
+ def initialize(body, args)
20
+ @body = body
21
+ args.each_pair do |k,v|
22
+ send("#{k}=", v)
23
+ end
24
+ end
25
+
26
+ def to_param
27
+ title.to_slug.normalize.to_s
28
+ end
29
+
30
+ def to_s
31
+ title.to_s
32
+ end
33
+
34
+ end
@@ -0,0 +1,12 @@
1
+ module SemiStatic::Page::WithLocale
2
+ def self.included(klass)
3
+ klass.send :attr_accessor, :locale
4
+ klass.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def all
9
+ super.find_all {|a| a.locale.to_sym == I18n.locale }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ require 'semi_static/rails/routes'
2
+
3
+ module SemiStatic
4
+ class Engine < ::Rails::Engine
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ module ActionDispatch::Routing
2
+ class Mapper
3
+ def semi_static_for(resource, args = {})
4
+ resource_as_class = resource.to_s.classify.constantize
5
+ c = lambda {|r| r.env["semi_static.mapping"] = resource_as_class ; true }
6
+ defaults = { :only => [ :index, :show ]}
7
+ if resource_as_class < SemiStatic::News
8
+ defaults[:id] = /([0-9]+\/){3}.+/
9
+ defaults[:controller] = "semi_static/news"
10
+ else
11
+ defaults[:controller] = "semi_static/page"
12
+ end
13
+ constraints(c) { resources(resource, defaults.merge(args)) }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module SemiStatic
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "semi_static/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "semi_static"
7
+ s.version = SemiStatic::VERSION
8
+ s.authors = ["Paul McMahon"]
9
+ s.email = ["paul@mobalean.com"]
10
+ s.homepage = "http://www.mobalean.com"
11
+ s.summary = %q{Text file based CMS for Rails}
12
+ s.description = %q{Easily create content for your Rails apps using just textfiles}
13
+
14
+ s.rubyforge_project = "semi_static"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'rails', '~> 3.0'
22
+ s.add_dependency 'rdiscount'
23
+ s.add_dependency 'babosa'
24
+ s.add_dependency 'tilt'
25
+
26
+ s.add_development_dependency 'rspec', '~> 2.5.0'
27
+ s.add_development_dependency 'steak'
28
+ end
@@ -0,0 +1,8 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require File.expand_path(File.dirname(__FILE__) + "/fake/app")
3
+ require "steak"
4
+ require 'capybara/rspec'
5
+
6
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
7
+
8
+ require 'rspec/rails'
@@ -0,0 +1,17 @@
1
+ require 'rails'
2
+ require 'action_controller/railtie'
3
+ require 'action_view/railtie'
4
+
5
+ # config
6
+ app = Class.new(Rails::Application)
7
+ app.config.root = File.dirname(__FILE__)
8
+ app.config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
9
+ app.config.session_store :cookie_store, :key => "_myapp_session"
10
+ app.config.active_support.deprecation = :log
11
+ app.initialize!
12
+
13
+ app.routes.draw do
14
+ semi_static_for :news
15
+ semi_static_for :event_planning_tips
16
+ end
17
+ class ApplicationController < ActionController::Base; end
@@ -0,0 +1,3 @@
1
+ # encoding: UTF-8
2
+ class EventPlanningTip < SemiStatic::Page
3
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: UTF-8
2
+ class News < SemiStatic::News
3
+ def self.feed_title
4
+ "請求書.jp"
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ <?xml version='1.0' encoding='utf-8' ?>
2
+ <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">
3
+ <html>
4
+ <head>
5
+ <meta content='application/xhtml+xml;charset=UTF-8' http-equiv='Content-Type' />
6
+ </head>
7
+ <body>
8
+ <%= yield %>
9
+ </body>
10
+ </html>
@@ -0,0 +1,18 @@
1
+ title: イベント時に気をつけたいマナー
2
+ ...
3
+ ## 1. 無断に写真や動画の撮影、公開しない
4
+
5
+ 写真や動画の撮影、Ustreamなどを用いた生放送等により、本人の知らない間にインターネット上で公開され問題になるケースがあります。そのようなことを避けるためにも事前に撮影の許可、どこかに掲載する場合には、掲載しても問題がないかの許可を取るべきです。イベントの申込時やチケットの購入時の条件に撮影許可等について記載しておくのがいいかもしれません。
6
+
7
+ ## 2. 飲食やゴミの分別の注意喚起
8
+
9
+ イベントを開催する場所によっては、飲食の禁止や制限があり、ゴミは各自で持ち帰っていただくこともあれば、専用のゴミ箱を使用してもいい場合もあります。開催場所の利用規約をきちんと把握し、参加者に伝え、それを徹底させることが大切です。特に配布資料等がある場合は、ゴミ箱を利用せず、会場や路上での放置があるかもしれまんせので、気をつけましょう。
10
+
11
+ ## 3. 騒音問題
12
+
13
+ イベントが盛り上がってくると、次第に大声で話したり、高笑いをするようなことが見受けられます。ある程度は致し方ないことかもしれませんが、近隣の住人の方々には迷惑をかけないよう心がけましょう。
14
+
15
+ ## Doorkeeperでマナーあるイベントを!
16
+ ### 注意事項の告知や急な仕様変更も、参加者へのメール一斉送信ができますので、簡単に通知できます。Doorkeeperは、メール通知等で、メンバー間のコミュニケーションや情報の共有をサポートします。
17
+
18
+ #### [Doorkeeperでマナーあるイベント開催を♪まずはご登録を!](http://manage.doorkeeper.jp/locale?locale=ja&return_to=%2Fadmins%2Fsign_up)
@@ -0,0 +1,8 @@
1
+ title: 請求書のダウンロードが可能になりました
2
+ published_at: 2011-07-26
3
+ ...
4
+
5
+ <p>各請求書のページに「ダウンロード」ボタンを設置し、作成した請求書をPDFファイルとしてダウンロードできるようになりました。</p>
6
+ <p>これにより、今まで「印刷」ボタンから印刷していた際に発生していた、ブラウザ間の動作の違いを意識することなく、簡単に印刷できるかと思います。</p>
7
+ <br>
8
+ <p>※ 今回の変更に伴い、「印刷」ボタンが「ダウンロード」ボタンに変更になりました。</p>
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper')
3
+
4
+ feature 'news' do
5
+ scenario "index" do
6
+ visit news_index_path
7
+ page.find("h1 a").text.should == "請求書のダウンロードが可能になりました"
8
+ page.find("date").text.should == "July 26, 2011"
9
+ page.find("p").text.should == "各請求書のページに「ダウンロード」ボタンを設置し、作成した請求書をPDFファイルとしてダウンロードできるようになりました。"
10
+ end
11
+
12
+ scenario 'show markdown page' do
13
+ visit "/news/2011/7/26/#{CGI.escape("請求書のダウンロードが可能になりました")}"
14
+ page.find("h1").text.should == "請求書のダウンロードが可能になりました"
15
+ page.find("date").text.should == "July 26, 2011"
16
+ page.find("p").text.should == "各請求書のページに「ダウンロード」ボタンを設置し、作成した請求書をPDFファイルとしてダウンロードできるようになりました。"
17
+ end
18
+
19
+ scenario 'show non-existant page' do
20
+ visit "/news/1999/1/23/foo"
21
+ page.find("h1").text.should == "Routing Error"
22
+ page.find("pre").text.should == "/news/1999/1/23/foo"
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper')
3
+
4
+ feature 'page' do
5
+ scenario "index" do
6
+ visit '/event_planning_tips'
7
+ page.find("h1 a").text.should == "イベント時に気をつけたいマナー"
8
+ page.find("section h2").text.should == "1. 無断に写真や動画の撮影、公開しない"
9
+ end
10
+
11
+ scenario 'show markdown page' do
12
+ visit "/event_planning_tips/#{CGI.escape("イベント時に気をつけたいマナー")}"
13
+ page.find("h1").text.should == "イベント時に気をつけたいマナー"
14
+ page.find("section h2").text.should == "1. 無断に写真や動画の撮影、公開しない"
15
+ end
16
+
17
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ class News < SemiStatic::News
5
+ end
6
+
7
+ describe SemiStatic::Backend do
8
+ before do
9
+ root = File.join(File.dirname(__FILE__), 'semi_static_pages')
10
+ @backend = described_class.new(root)
11
+ end
12
+
13
+ context "all" do
14
+ before { @all = @backend.all(News) }
15
+ it { @all.size.should == 1 }
16
+
17
+ context "item" do
18
+ before { @item = @all.first }
19
+ it { @item.title.should == "請求書のダウンロードが可能になりました" }
20
+ it { @item.published_at.should == Date.parse("2011-07-26") }
21
+ it { @item.body.should be_instance_of Tilt::RDiscountTemplate }
22
+ end
23
+ end
24
+ end
data/spec/news_spec.rb ADDED
@@ -0,0 +1,12 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe SemiStatic::News do
5
+ before do
6
+ @page = described_class.new("body", :title => "ほげ", :published_at => Date.parse("2001-01-31"))
7
+ SemiStatic.backend = mock(:all => [ @page ])
8
+ end
9
+
10
+ it { @page.to_param.should == "2001/1/31/ほげ" }
11
+ it { News.find("2001/1/31/ほげ").should == @page }
12
+ end
data/spec/page_spec.rb ADDED
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe SemiStatic::Page do
5
+ before do
6
+ @japanese_page = described_class.new("body", :title => "ほげ")
7
+ @english_page = described_class.new("body", :title => "foo bar")
8
+ SemiStatic.backend = mock(:all => [ @japanese_page, @english_page ])
9
+ end
10
+
11
+ it { @japanese_page.to_param.should == "ほげ" }
12
+ it { @japanese_page.to_s.should == "ほげ" }
13
+ it { @english_page.to_param.should == "foo-bar" }
14
+ it { @english_page.to_s.should == "foo bar" }
15
+ it { described_class.new(nil, {}).to_s.should == "" }
16
+ it { SemiStatic::Page.find("foo-bar").should == @english_page }
17
+ end
@@ -0,0 +1,8 @@
1
+ title: 請求書のダウンロードが可能になりました
2
+ published_at: 2011-07-26
3
+ ...
4
+
5
+ <p>各請求書のページに「ダウンロード」ボタンを設置し、作成した請求書をPDFファイルとしてダウンロードできるようになりました。</p>
6
+ <p>これにより、今まで「印刷」ボタンから印刷していた際に発生していた、ブラウザ間の動作の違いを意識することなく、簡単に印刷できるかと思います。</p>
7
+ <br>
8
+ <p>※ 今回の変更に伴い、「印刷」ボタンが「ダウンロード」ボタンに変更になりました。</p>
@@ -0,0 +1,3 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'semi_static'
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: semi_static
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paul McMahon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-20 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &2155975900 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2155975900
25
+ - !ruby/object:Gem::Dependency
26
+ name: rdiscount
27
+ requirement: &2155975480 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2155975480
36
+ - !ruby/object:Gem::Dependency
37
+ name: babosa
38
+ requirement: &2155975020 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *2155975020
47
+ - !ruby/object:Gem::Dependency
48
+ name: tilt
49
+ requirement: &2155974600 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *2155974600
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &2155974100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 2.5.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2155974100
69
+ - !ruby/object:Gem::Dependency
70
+ name: steak
71
+ requirement: &2155973680 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2155973680
80
+ description: Easily create content for your Rails apps using just textfiles
81
+ email:
82
+ - paul@mobalean.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - .gitignore
88
+ - Gemfile
89
+ - README.md
90
+ - Rakefile
91
+ - app/controllers/semi_static/news_controller.rb
92
+ - app/controllers/semi_static/page_controller.rb
93
+ - app/views/semi_static/news/index.atom.builder
94
+ - app/views/semi_static/news/index.html.erb
95
+ - app/views/semi_static/news/show.html.erb
96
+ - app/views/semi_static/page/index.html.erb
97
+ - app/views/semi_static/page/show.html.erb
98
+ - lib/semi_static.rb
99
+ - lib/semi_static/backend.rb
100
+ - lib/semi_static/news.rb
101
+ - lib/semi_static/page.rb
102
+ - lib/semi_static/page/with_locale.rb
103
+ - lib/semi_static/rails.rb
104
+ - lib/semi_static/rails/routes.rb
105
+ - lib/semi_static/version.rb
106
+ - semi_static.gemspec
107
+ - spec/acceptance/acceptance_helper.rb
108
+ - spec/acceptance/fake/app.rb
109
+ - spec/acceptance/fake/app/models/event_planning_tip.rb
110
+ - spec/acceptance/fake/app/models/news.rb
111
+ - spec/acceptance/fake/app/views/application.html.erb
112
+ - spec/acceptance/fake/semi_static_pages/event_planning_tips/manner.md
113
+ - spec/acceptance/fake/semi_static_pages/news/2011-07-26-replaced-download.md
114
+ - spec/acceptance/news_spec.rb
115
+ - spec/acceptance/page_spec.rb
116
+ - spec/backend_spec.rb
117
+ - spec/news_spec.rb
118
+ - spec/page_spec.rb
119
+ - spec/semi_static_pages/news/2011-07-26-replaced-download.md
120
+ - spec/spec_helper.rb
121
+ homepage: http://www.mobalean.com
122
+ licenses: []
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project: semi_static
141
+ rubygems_version: 1.8.6
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: Text file based CMS for Rails
145
+ test_files:
146
+ - spec/acceptance/acceptance_helper.rb
147
+ - spec/acceptance/fake/app.rb
148
+ - spec/acceptance/fake/app/models/event_planning_tip.rb
149
+ - spec/acceptance/fake/app/models/news.rb
150
+ - spec/acceptance/fake/app/views/application.html.erb
151
+ - spec/acceptance/fake/semi_static_pages/event_planning_tips/manner.md
152
+ - spec/acceptance/fake/semi_static_pages/news/2011-07-26-replaced-download.md
153
+ - spec/acceptance/news_spec.rb
154
+ - spec/acceptance/page_spec.rb
155
+ - spec/backend_spec.rb
156
+ - spec/news_spec.rb
157
+ - spec/page_spec.rb
158
+ - spec/semi_static_pages/news/2011-07-26-replaced-download.md
159
+ - spec/spec_helper.rb