owl-cms 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/Gemfile +23 -0
  4. data/Gemfile.lock +87 -0
  5. data/README.md +3 -0
  6. data/Rakefile +8 -0
  7. data/bin/owl +88 -0
  8. data/config.ru +3 -0
  9. data/core/app.rb +21 -0
  10. data/core/assets/stylesheets/style.css +1 -0
  11. data/core/classes/cached.rb +36 -0
  12. data/core/classes/checker.rb +37 -0
  13. data/core/classes/error.rb +9 -0
  14. data/core/classes/other.rb +13 -0
  15. data/core/classes/page.rb +128 -0
  16. data/core/classes/partial.rb +13 -0
  17. data/core/classes/path.rb +35 -0
  18. data/core/classes/settings.rb +19 -0
  19. data/core/classes/theme.rb +48 -0
  20. data/core/helpers/base.rb +37 -0
  21. data/core/helpers/render.rb +26 -0
  22. data/core/helpers/truncate.rb +17 -0
  23. data/core/routes/admin.rb +13 -0
  24. data/core/routes/base.rb +18 -0
  25. data/core/routes/bootstrap.rb +30 -0
  26. data/core/routes/cache.rb +36 -0
  27. data/owl-cms.gemspec +25 -0
  28. data/sample/.cabi-data +0 -0
  29. data/sample/data/home/index.haml +21 -0
  30. data/sample/data/other/nav/links.yml +4 -0
  31. data/sample/data/page/about/index.haml +14 -0
  32. data/sample/data/page/contact-us/index.haml +11 -0
  33. data/sample/data/page/dynamic-page/index.haml +14 -0
  34. data/sample/data/page/no-front-matter/index.haml +7 -0
  35. data/sample/data/page/not-found/index.haml +7 -0
  36. data/sample/data/page/static-page/index.haml +14 -0
  37. data/sample/data/post/about-life/index.haml +8 -0
  38. data/sample/data/post/sample-post/index.haml +12 -0
  39. data/sample/data/post/technology/index.haml +9 -0
  40. data/sample/data/post/the-40-hour-workweek/index.haml +9 -0
  41. data/sample/data/post/things-are-changing/index.haml +9 -0
  42. data/sample/data/post/yet-another-post/index.haml +11 -0
  43. data/sample/plugins/my-plugin/plugin.rb +15 -0
  44. data/sample/settings.yml +7 -0
  45. data/sample/themes/base/assets/config.rb +26 -0
  46. data/sample/themes/base/assets/images/owl.svg +20 -0
  47. data/sample/themes/base/assets/javascripts/app/views/main.js +13 -0
  48. data/sample/themes/base/assets/javascripts/main.js +31 -0
  49. data/sample/themes/base/assets/javascripts/vendor/backbone.js +4 -0
  50. data/sample/themes/base/assets/javascripts/vendor/jquery.js +6 -0
  51. data/sample/themes/base/assets/javascripts/vendor/lodash.underscore.js +38 -0
  52. data/sample/themes/base/assets/javascripts/vendor/require.js +36 -0
  53. data/sample/themes/base/assets/scss/main.scss +19 -0
  54. data/sample/themes/base/assets/scss/modules/_all.scss +7 -0
  55. data/sample/themes/base/assets/scss/modules/_colors.scss +5 -0
  56. data/sample/themes/base/assets/scss/modules/_extensions.scss +11 -0
  57. data/sample/themes/base/assets/scss/modules/_mixins.scss +2 -0
  58. data/sample/themes/base/assets/scss/modules/_susy.scss +6 -0
  59. data/sample/themes/base/assets/scss/partials/_base.scss +26 -0
  60. data/sample/themes/base/assets/scss/partials/_buttons.scss +0 -0
  61. data/sample/themes/base/assets/scss/partials/_links.scss +15 -0
  62. data/sample/themes/base/assets/scss/partials/_main.scss +37 -0
  63. data/sample/themes/base/assets/scss/partials/_typography.scss +16 -0
  64. data/sample/themes/base/assets/scss/sections/_footer.scss +24 -0
  65. data/sample/themes/base/assets/scss/sections/_header.scss +18 -0
  66. data/sample/themes/base/assets/scss/sections/_home.scss +13 -0
  67. data/sample/themes/base/assets/scss/vendor/_normalize.scss +406 -0
  68. data/sample/themes/base/assets/stylesheets/main.css +587 -0
  69. data/sample/themes/base/layouts/default.haml +11 -0
  70. data/sample/themes/base/layouts/post.haml +17 -0
  71. data/sample/themes/base/partials/_footer.haml +11 -0
  72. data/sample/themes/base/partials/_ga.haml +10 -0
  73. data/sample/themes/base/partials/_head.haml +20 -0
  74. data/sample/themes/base/partials/_header.haml +7 -0
  75. data/sample/themes/base/settings.yml +4 -0
  76. data/test/test_basics.rb +50 -0
  77. data/test/test_data.rb +14 -0
  78. data/test/test_includes.rb +43 -0
  79. data/test/test_page.rb +47 -0
  80. metadata +612 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5e252eecd1ef4b780e2e8b6fc4c86473f132bedb
4
+ data.tar.gz: cdc046025f41f5a95ad11e70542115863eb35e36
5
+ SHA512:
6
+ metadata.gz: 7ef2300235c154f7f05d11c86e8cf157faeeae3ffe3a95c442a4e8dafa4fdc5b9071f34a1ca75982643b5318292f9a5c4f01bd4144ba22b031b0a57e3203a1a7
7
+ data.tar.gz: 3e8b017ff3bbe7c842efb1dc652fcfe1205bc0470e0dca0773a5ec14e33f5a1c236d142ff380d553a01d02426ae82d10eb4a2a999264d620c4a82148f80762ea
@@ -0,0 +1,6 @@
1
+
2
+ .cache
3
+ .DS_Store
4
+ .sass-cache
5
+
6
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+
2
+ source 'http://rubygems.org'
3
+
4
+ # Sinatra & Rack
5
+ gem 'sinatra', '1.4.3', :require => 'sinatra/base'
6
+ gem 'sinatra-contrib', '1.4.1', :require => 'sinatra/contrib/all'
7
+ gem 'rack-cache', '1.2', :require => 'rack/cache'
8
+ gem 'rack-funky-cache', '0.0.6', :require => 'rack/funky-cache'
9
+ gem 'rack-session-file', '0.5.0', :require => 'rack-session-file'
10
+ gem 'thin', '1.5.1', :require => 'thin'
11
+ gem 'rerun', '0.8.1', :require => 'rerun'
12
+
13
+ # Frontend
14
+ gem 'haml', '4.0.3', :require => 'haml'
15
+ gem 'sass', '3.2.10', :require => 'sass'
16
+ gem 'compass', '0.12.2', :require => 'compass'
17
+ gem 'susy', '1.0.9', :require => 'susy'
18
+ gem 'maruku', '0.6.1', :require => 'maruku'
19
+ gem 'html_truncator', '0.3.1', :require => 'html_truncator'
20
+
21
+
22
+ # Datastore
23
+ gem 'cabi', '0.1.5', :require => 'cabi'
@@ -0,0 +1,87 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ backports (3.3.4)
5
+ cabi (0.1.5)
6
+ thor (~> 0.18, >= 0.18.1)
7
+ chunky_png (1.2.8)
8
+ compass (0.12.2)
9
+ chunky_png (~> 1.2)
10
+ fssm (>= 0.2.7)
11
+ sass (~> 3.1)
12
+ daemons (1.1.9)
13
+ eventmachine (1.0.3)
14
+ ffi (1.9.0)
15
+ fssm (0.2.10)
16
+ haml (4.0.3)
17
+ tilt
18
+ html_truncator (0.3.1)
19
+ nokogiri (~> 1.5)
20
+ listen (1.3.1)
21
+ rb-fsevent (>= 0.9.3)
22
+ rb-inotify (>= 0.9)
23
+ rb-kqueue (>= 0.2)
24
+ maruku (0.6.1)
25
+ syntax (>= 1.0.0)
26
+ mini_portile (0.5.1)
27
+ multi_json (1.8.0)
28
+ nokogiri (1.6.0)
29
+ mini_portile (~> 0.5.0)
30
+ rack (1.5.2)
31
+ rack-cache (1.2)
32
+ rack (>= 0.4)
33
+ rack-funky-cache (0.0.6)
34
+ rack-protection (1.5.0)
35
+ rack
36
+ rack-session-file (0.5.0)
37
+ rack (>= 1.1.0)
38
+ rack-test (0.6.2)
39
+ rack (>= 1.0)
40
+ rb-fsevent (0.9.3)
41
+ rb-inotify (0.9.2)
42
+ ffi (>= 0.5.0)
43
+ rb-kqueue (0.2.0)
44
+ ffi (>= 0.5.0)
45
+ rerun (0.8.1)
46
+ listen (>= 1.0.3)
47
+ sass (3.2.10)
48
+ sinatra (1.4.3)
49
+ rack (~> 1.4)
50
+ rack-protection (~> 1.4)
51
+ tilt (~> 1.3, >= 1.3.4)
52
+ sinatra-contrib (1.4.1)
53
+ backports (>= 2.0)
54
+ multi_json
55
+ rack-protection
56
+ rack-test
57
+ sinatra (~> 1.4.0)
58
+ tilt (~> 1.3)
59
+ susy (1.0.9)
60
+ compass (>= 0.12.2)
61
+ sass (>= 3.2.0)
62
+ syntax (1.0.0)
63
+ thin (1.5.1)
64
+ daemons (>= 1.0.9)
65
+ eventmachine (>= 0.12.6)
66
+ rack (>= 1.0.0)
67
+ thor (0.18.1)
68
+ tilt (1.4.1)
69
+
70
+ PLATFORMS
71
+ ruby
72
+
73
+ DEPENDENCIES
74
+ cabi (= 0.1.5)
75
+ compass (= 0.12.2)
76
+ haml (= 4.0.3)
77
+ html_truncator (= 0.3.1)
78
+ maruku (= 0.6.1)
79
+ rack-cache (= 1.2)
80
+ rack-funky-cache (= 0.0.6)
81
+ rack-session-file (= 0.5.0)
82
+ rerun (= 0.8.1)
83
+ sass (= 3.2.10)
84
+ sinatra (= 1.4.3)
85
+ sinatra-contrib (= 1.4.1)
86
+ susy (= 1.0.9)
87
+ thin (= 1.5.1)
@@ -0,0 +1,3 @@
1
+ # <img src="http://s.cdpn.io/4629/owl.svg" width=30 style="margin-right: 10px"> OwlCMS
2
+
3
+ A work in progress -- bear with me.
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
data/bin/owl ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+ require "thor"
3
+ require "fileutils"
4
+
5
+ ROOT = File.expand_path("../..", __FILE__)
6
+ CONFIG_RU = File.join( ROOT, "config.ru")
7
+ SAMPLE_DIR = File.join( ROOT, "sample")
8
+ GEMFILE = File.join( ROOT, "Gemfile")
9
+
10
+ class OwlCLI < Thor
11
+
12
+ # -----------------------------------------------------------------------------------------------------------
13
+ # Serve Task
14
+ # -----------------------------------------------------------------------------------------------------------
15
+ desc "start", "Startup Owl server for local viewing. (use --port to specify your own port)"
16
+ method_options port: :integer, rerun: true
17
+ def start
18
+ port = options[:port] || 3000
19
+ no_reload = options[:rerun]
20
+ thin_string = "BUNDLE_GEMFILE='#{GEMFILE}' thin start -R #{CONFIG_RU} --port #{port}"
21
+
22
+ puts "\n** Starting OwlCMS\n"
23
+
24
+ if options[:rerun]
25
+ puts "** (rerun enabled)"
26
+ system "rerun '#{thin_string}' --no-growl"
27
+ else
28
+ puts "** (rerun disabled)"
29
+ system "#{thin_string}"
30
+ end
31
+ end
32
+
33
+ # -----------------------------------------------------------------------------------------------------------
34
+ # Init Task
35
+ # -----------------------------------------------------------------------------------------------------------
36
+ desc "init", "Initialize new Owl project"
37
+ method_options :port => :integer
38
+ def init
39
+ puts "\n** Creating new OwlCMS instance"
40
+
41
+ found = []
42
+ Dir.foreach( SAMPLE_DIR ).each do |file|
43
+ next if ['.', '..', '.DS_Store'].include? file
44
+ found << file if File.exists? file
45
+ end
46
+
47
+ raise "** Cannot continue! The following files would be deleted: #{found.join(',')}\n\n" if !found.empty?
48
+
49
+ # Copy all of the files.
50
+ puts "** Copying files"
51
+ system "cp -r #{SAMPLE_DIR}/.cabi-data ."
52
+ system "cp -r #{SAMPLE_DIR}/* ."
53
+
54
+ puts "** Success!"
55
+ end
56
+
57
+ # -----------------------------------------------------------------------------------------------------------
58
+ # Clean Task
59
+ # -----------------------------------------------------------------------------------------------------------
60
+ desc "clean", "Clean current directory of Owl-related files & directories"
61
+ method_options :force => :false
62
+ def clean
63
+ puts "\n** Cleaning: #{Dir.pwd}."
64
+
65
+ if options[:force]
66
+ puts "** About to destroy..."
67
+ Dir.foreach( SAMPLE_DIR ).each do |file|
68
+ next if ['.', '..', '.DS_Store'].include? file
69
+ FileUtils.rm_rf(File.basename(file)) if File.exists?(file)
70
+ end
71
+ else
72
+ puts "** Ooops! Not cleaning without --force. Files & dirs **will** be harmed."
73
+ end
74
+
75
+ end
76
+
77
+ # -----------------------------------------------------------------------------------------------------------
78
+ # Theme Task
79
+ # -----------------------------------------------------------------------------------------------------------
80
+ desc "theme", "Install base theme or theme from git"
81
+ def theme
82
+ # install base theme or install
83
+ # theme from
84
+ end
85
+
86
+ end
87
+
88
+ OwlCLI.start
@@ -0,0 +1,3 @@
1
+
2
+ require File.expand_path('../core/app', __FILE__)
3
+ run Owl::CMS::App
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+
5
+ # Base requires.
6
+ Bundler.require(:default)
7
+
8
+ module Owl
9
+
10
+ ROOT = File.expand_path '../..', __FILE__
11
+ CORE = File.join(Owl::ROOT, 'core')
12
+ require Owl::CORE + '/routes/bootstrap'
13
+
14
+ module CMS
15
+
16
+ class App < Sinatra::Base
17
+ register Owl::CMS::Bootstrap
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1 @@
1
+ body{ color: blue; }
@@ -0,0 +1,36 @@
1
+
2
+ require 'fileutils'
3
+
4
+ module Owl
5
+ module Lib
6
+ class CachedFile
7
+
8
+
9
+ def self.find(request)
10
+ path = Rack::Utils.unescape(request.path_info)
11
+
12
+ file_to_return = false
13
+ self.possible_paths(path).each do |file|
14
+ break if file_to_return
15
+ file_to_return = file if File.exists?(file)
16
+ end
17
+
18
+ file_to_return
19
+ end
20
+
21
+ def self.possible_paths(path)
22
+ [
23
+ File.expand_path("#{Owl::CMS::Cache::CACHE_STORE}#{path}.html" ),
24
+ File.expand_path("#{Owl::CMS::Cache::CACHE_STORE}#{path}/index.html" ),
25
+ File.expand_path("#{Owl::CMS::Cache::CACHE_STORE}#{path}index.html" )
26
+ ]
27
+ end
28
+
29
+ def self.clear
30
+ puts "** Removing OwlCMS cache **"
31
+ FileUtils.rm_rf Owl::CMS::Cache::CACHE_STORE
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,37 @@
1
+
2
+ require Owl::CORE + '/classes/error'
3
+
4
+ module Owl
5
+
6
+ DEFAULT_THEME_DIR = 'themes'
7
+ DEFAULT_DATA_DIR = 'data'
8
+ REQUIRED_DATA_SUB_DIRS = ['post', 'page', 'home']
9
+
10
+ module Lib
11
+ class Checker
12
+
13
+ def self.check!
14
+ unless self.base_dirs? and self.sub_dirs?
15
+ raise Owl::Error.new('Directory structure is not correct! Have you run the `owl new` command?')
16
+ end
17
+ end
18
+
19
+ def self.base_dirs?
20
+ Cabi.file(DEFAULT_DATA_DIR) and
21
+ Cabi.file(DEFAULT_THEME_DIR)
22
+ end
23
+
24
+ def self.sub_dirs?
25
+ ok = nil
26
+ REQUIRED_DATA_SUB_DIRS.each do |dir|
27
+ ok = Cabi.file( [DEFAULT_DATA_DIR, dir].join(':') )
28
+ break if not ok
29
+ end
30
+ ok
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+
37
+ Owl::Lib::Checker.check!
@@ -0,0 +1,9 @@
1
+
2
+ module Owl
3
+ class Error < StandardError
4
+ def initialize(msg = "An error has occurred.")
5
+ super( [" ** OwlCMS", msg].join(' - ') )
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,13 @@
1
+ module Owl
2
+ module Lib
3
+ class OtherData
4
+
5
+ OTHER_PATH = 'other'
6
+
7
+ def self.read(key)
8
+ Cabi.read [ Owl::Lib::Path::DATA_PATH, OTHER_PATH, key].join(':')
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,128 @@
1
+
2
+ require 'digest/sha1'
3
+ require 'date'
4
+
5
+ module Owl
6
+ module Lib
7
+ class Page
8
+
9
+ DEFAULT_PAGE_LAYOUT = "default.haml"
10
+ FRONT_MATTER_RE = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
11
+
12
+ attr_accessor :raw
13
+ attr_accessor :haml
14
+ attr_accessor :html
15
+ attr_accessor :front_matter
16
+ attr_accessor :path
17
+
18
+ def initialize(path, current_scope=self, quiet=false)
19
+
20
+ read(path)
21
+ @path = path
22
+
23
+ raise Sinatra::NotFound if (@raw.nil? and !quiet)
24
+
25
+ @scope = current_scope
26
+ @scope.instance_variable_set :@page, self
27
+ parse_haml
28
+ parse_front_matter
29
+ render
30
+ end
31
+
32
+ def read(path)
33
+ @raw ||= Cabi.read( Owl::Lib::Path.path(path) ) || Cabi.read( Owl::Lib::Path.page_path(path) )
34
+ end
35
+
36
+ def parse_haml
37
+ @haml ||= raw.gsub FRONT_MATTER_RE, ''
38
+ end
39
+
40
+ def parse_front_matter
41
+ @front_matter ||= begin
42
+ raise unless raw.index(FRONT_MATTER_RE)
43
+ YAML.load(@raw) || Hash.new
44
+ rescue Exception => e
45
+ Hash.new
46
+ end
47
+ end
48
+
49
+ def render
50
+ @html = Haml::Engine.new( layout ).render( @scope, front_matter ) do
51
+ Haml::Engine.new( @haml ).render( @scope, front_matter )
52
+ end
53
+ end
54
+
55
+ def content
56
+ # This is the page without the content.
57
+ @content ||= Haml::Engine.new( @haml ).render( @scope, front_matter )
58
+ end
59
+
60
+ def setting(key)
61
+ @front_matter[key]
62
+ end
63
+
64
+ def haml_opts
65
+ opts = front_matter
66
+ opts[:layout] = layout
67
+ opts
68
+ end
69
+
70
+ def layout
71
+ user_layout = setting('layout')
72
+ Owl::Lib::Theme.instance.layout( user_layout )
73
+ end
74
+
75
+ def type
76
+ post? ? 'post' : 'page'
77
+ end
78
+
79
+ def page?
80
+ !post?
81
+ end
82
+
83
+ def post?
84
+ path.index("/post") == 0
85
+ end
86
+
87
+ def cache?
88
+ if @front_matter.has_key?('cache')
89
+ setting('cache')
90
+ else
91
+ true
92
+ end
93
+ end
94
+
95
+ def publish?
96
+ setting('publish')
97
+ end
98
+
99
+ def age
100
+ begin
101
+ Date.parse(date).to_time.to_i
102
+ rescue Exception => e
103
+ 0
104
+ end
105
+ end
106
+
107
+ def sha1
108
+ Digest::SHA1.hexdigest @raw
109
+ end
110
+
111
+ def self.all_posts(current_scope=self, opts)
112
+ files = Cabi.file( Owl::Lib::Path.all_posts_path )
113
+
114
+ posts = []
115
+ files.each do |path|
116
+ path = '/' + path.gsub(Cabi::data_dir, '')[1..-1].split('/')[1..-2].join('/')
117
+ post = Owl::Lib::Page.new( path, current_scope, true)
118
+ posts << post if post.publish? or opts[:include_unpublished]
119
+ end
120
+
121
+ posts.sort! {|a,b| a.age <=> b.age }
122
+ posts.reverse!
123
+ posts
124
+ end
125
+
126
+ end
127
+ end
128
+ end