owl-cms 0.1.0

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 (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,13 @@
1
+ module Owl
2
+ module Lib
3
+ class Partial
4
+
5
+ attr_accessor :raw
6
+
7
+ def initialize(path)
8
+ @raw = Cabi.read( Owl::Lib::Path.partial_cabi_id(path) )
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module Owl
2
+ module Lib
3
+ class Path
4
+
5
+ DATA_PATH = 'data'
6
+ INDEX_PATH = 'index'
7
+ NOT_FOUND_PATH = 'not-found'
8
+ POST_PATH = "post"
9
+ PAGE_PATH = "page"
10
+
11
+ def self.cabi_id(p, opts={})
12
+ p = p[1..-1]
13
+ [DATA_PATH, p.gsub('/', ':'), INDEX_PATH].compact.join(':')
14
+ end
15
+
16
+ def self.path(p)
17
+ self.cabi_id(p)
18
+ end
19
+
20
+ def self.page_path(p)
21
+ self.cabi_id( ['/', PAGE_PATH, p].join('/') )
22
+ end
23
+
24
+ def self.partial_cabi_id(p)
25
+ p = "_" + p
26
+ [Owl::Lib::Theme.instance.path, Owl::Lib::Theme::PARTIALS_PATH, p].join(':')
27
+ end
28
+
29
+ def self.all_posts_path
30
+ [DATA_PATH, POST_PATH, "**/#{INDEX_PATH}.*"].join(':')
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+
2
+ require 'singleton'
3
+ require Owl::CORE + '/classes/theme'
4
+
5
+ module Owl
6
+ module Lib
7
+ class Settings
8
+ include Singleton
9
+
10
+ SETTINGS_PATH = 'settings.yml'
11
+ THEME_SETTINGS_PATH = [Owl::Lib::Theme::THEMES_PATH, SETTINGS_PATH].join(':')
12
+
13
+ def settings
14
+ Cabi.read(SETTINGS_PATH)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,48 @@
1
+
2
+ require 'singleton'
3
+
4
+ module Owl
5
+
6
+ module Lib
7
+ class Theme
8
+ include Singleton
9
+
10
+ THEMES_PATH = 'themes'
11
+ LAYOUTS_PATH = 'layouts'
12
+ PARTIALS_PATH = 'partials'
13
+ ASSETS_PATH = 'assets'
14
+ DEFAULT_THEME = 'base'
15
+ DEFAULT_PAGE_LAYOUT = 'default'
16
+
17
+ def current
18
+ Owl::Lib::Settings.instance.settings['theme'] || DEFAULT_THEME
19
+ end
20
+
21
+ def layout(layout)
22
+ layout = DEFAULT_PAGE_LAYOUT if layout.nil?
23
+
24
+ Cabi.read([ path, LAYOUTS_PATH, layout ].join(':')) ||
25
+ Cabi.read([ path, LAYOUTS_PATH, DEFAULT_PAGE_LAYOUT ].join(':')) ||
26
+ "= yield"
27
+ end
28
+
29
+ def file_path
30
+ Cabi.file( path )
31
+ end
32
+
33
+ def path
34
+ [ THEMES_PATH, current ].join(':')
35
+ end
36
+
37
+ def theme_path
38
+ Cabi.file( [path, ASSETS_PATH].join(':') )
39
+ end
40
+
41
+ def settings
42
+ Cabi.read([ path, Owl::Lib::Settings::SETTINGS_PATH ].join(':'))
43
+ end
44
+
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,37 @@
1
+
2
+ module Owl
3
+ module CMS
4
+ module Helpers
5
+ include Sinatra
6
+
7
+ module Base
8
+
9
+ def site_setting(key)
10
+ Owl::CMS::App.settings.site_settings[key]
11
+ end
12
+
13
+ def theme_setting(key)
14
+ Owl::CMS::App.settings.theme_settings[key]
15
+ end
16
+
17
+ def posts(include_unpublished=false)
18
+ Owl::Lib::Page.all_posts(self, { include_unpublished: include_unpublished })
19
+ end
20
+
21
+ def data(key)
22
+ Owl::Lib::OtherData.read key
23
+ end
24
+
25
+ def page_path
26
+ @page.path
27
+ end
28
+
29
+ def page_type
30
+ @page.type
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+
2
+ require 'digest/md5'
3
+
4
+ module Owl
5
+ module CMS
6
+ module Helpers
7
+ include Sinatra
8
+
9
+ module Render
10
+
11
+ def render_page(path)
12
+ # Grab the page & render it.
13
+ page = Owl::Lib::Page.new(path, self)
14
+ page.html
15
+ end
16
+
17
+ def partial(path, locals={})
18
+ partial = Owl::Lib::Partial.new(path)
19
+ haml(partial.raw, {}, locals)
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module Owl
3
+ module CMS
4
+ module Helpers
5
+ include Sinatra
6
+
7
+ module Truncate
8
+
9
+ def truncate(content, length=250)
10
+ HTML_Truncator.truncate(content, length)
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+
2
+ module Owl
3
+ module CMS
4
+ module Admin
5
+ extend Sinatra::Extension
6
+
7
+ get '/admin' do
8
+ 'please login'
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module Owl
3
+ module CMS
4
+ module Base
5
+ extend Sinatra::Extension
6
+
7
+ not_found do
8
+ # => If 404, let's look for the page somewhere else.
9
+ end
10
+
11
+ get '*' do |path|
12
+ path = "/home" if path == '/'
13
+ render_page(path)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+
2
+ # Require Owl's libs.
3
+ Dir[Owl::CORE + "/**/*.rb"].each {|file| require file }
4
+
5
+ # Require user plugins.
6
+ Cabi.file('plugins:**/*.rb').each{ |file| require file }
7
+
8
+ module Owl
9
+ module CMS
10
+ module Bootstrap
11
+ extend Sinatra::Extension
12
+
13
+ register Owl::CMS::Admin
14
+ register Owl::CMS::Cache
15
+ register Owl::CMS::Base
16
+
17
+ helpers Owl::CMS::Helpers::Base
18
+ helpers Owl::CMS::Helpers::Render
19
+ helpers Owl::CMS::Helpers::Truncate
20
+
21
+ configure do
22
+ set :static, true
23
+ set :public_folder, Owl::Lib::Theme.instance.theme_path
24
+ set :site_settings, Owl::Lib::Settings.instance.settings
25
+ set :theme_settings, Owl::Lib::Theme.instance.settings
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,36 @@
1
+
2
+ module Owl
3
+
4
+ module CMS
5
+ module Cache
6
+ extend Sinatra::Extension
7
+
8
+ CACHE_ROOT = "#{Dir.pwd}"
9
+ CACHE_PATH = ".cache"
10
+ CACHE_STORE = File.join(CACHE_ROOT, CACHE_PATH)
11
+ METASTORE_URI = "file:#{CACHE_STORE}"
12
+ ENTITYSTORE_URI = "file:#{CACHE_STORE}"
13
+
14
+ use Rack::Cache do
15
+ set :verbose, true
16
+ set :metastore, METASTORE_URI
17
+ set :entitystore, ENTITYSTORE_URI
18
+ end
19
+
20
+ use Rack::FunkyCache, :root => CACHE_ROOT, :path => CACHE_PATH
21
+
22
+ before do
23
+
24
+ if env['HTTP_PRAGMA'] != 'no-cache'
25
+ file = Owl::Lib::CachedFile.find(request)
26
+ if file
27
+ last_modified File.mtime(file)
28
+ send_file(file)
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+
2
+ require 'bundler'
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'owl-cms'
6
+ gem.version = '0.1.0'
7
+ gem.summary = 'A ruby CMS.'
8
+
9
+ gem.description = 'A ruby CMS...'
10
+ gem.authors = ["Brian Gonzalez"]
11
+ gem.email = 'me@briangonzalez.org'
12
+ gem.homepage = 'http://github.com/briangonzalez/owl-cms-gem'
13
+ gem.license = 'MIT'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables << 'owl'
17
+
18
+ # CLI
19
+ gem.add_dependency 'thor', '~> 0.18'
20
+
21
+ # From gemfile.
22
+ Bundler.definition.specs.each{ |r| gem.add_dependency r.name, r.version }
23
+
24
+ gem.required_ruby_version = '>= 1.9.3'
25
+ end
File without changes
@@ -0,0 +1,21 @@
1
+ ---
2
+ title: Home
3
+ publish: true
4
+ date: April 19, 1775
5
+ ---
6
+
7
+ .posts
8
+ - posts.each do |p|
9
+
10
+ %article
11
+ / The title
12
+ %h2= p.setting('title') || "Untitled"
13
+
14
+ / The content
15
+ = truncate p.content, 100
16
+
17
+ %h4
18
+ %a{ href: p.path }= "Read more"
19
+
20
+ / The date
21
+ %small= p.setting('date') || "No date given"
@@ -0,0 +1,4 @@
1
+
2
+ Home: "/"
3
+ About: "/about"
4
+ Contact: "/contact-us"
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: About Us
3
+ layout: foo # this layout is missing (by design), will use default.
4
+ ---
5
+
6
+ %h1= @page.setting('title')
7
+
8
+ %p
9
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ullamcorper justo sem. Fusce ac sem est. Aenean dignissim feugiat auctor. Vestibulum in ante sem. Ut sit amet erat arcu, eget fringilla odio. Aenean a nibh est. Cras metus urna, vulputate non feugiat vel, condimentum sit amet purus.
10
+
11
+ %p
12
+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec dictum egestas lorem. Vestibulum tempus, ante a adipiscing tempus, eros lectus mollis tellus, id viverra arcu purus vitae sapien. Suspendisse sed quam leo. Suspendisse volutpat nunc sit amet nulla venenatis ultrices. Quisque bibendum, purus pulvinar lacinia euismod, dolor tortor cursus enim, tempus porttitor magna neque in nibh. Quisque vel turpis sit amet mi semper venenatis in et arcu. Mauris mattis hendrerit turpis, tristique bibendum felis dictum et. Mauris elit turpis, suscipit eget sollicitudin id, congue sed erat. Mauris fringilla semper magna eget vulputate. Fusce ut ligula a velit ultricies condimentum at hendrerit lectus.
13
+
14
+ - puts "Test"
@@ -0,0 +1,11 @@
1
+ ---
2
+ title: Contact Us
3
+ ---
4
+
5
+ %h1= @page.setting('title')
6
+
7
+ %p
8
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ullamcorper justo sem. Fusce ac sem est. Aenean dignissim feugiat auctor. Vestibulum in ante sem. Ut sit amet erat arcu, eget fringilla odio. Aenean a nibh est. Cras metus urna, vulputate non feugiat vel, condimentum sit amet purus.
9
+
10
+ %p
11
+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec dictum egestas lorem. Vestibulum tempus, ante a adipiscing tempus, eros lectus mollis tellus, id viverra arcu purus vitae sapien. Suspendisse sed quam leo. Suspendisse volutpat nunc sit amet nulla venenatis ultrices. Quisque bibendum, purus pulvinar lacinia euismod, dolor tortor cursus enim, tempus porttitor magna neque in nibh. Quisque vel turpis sit amet mi semper venenatis in et arcu. Mauris mattis hendrerit turpis, tristique bibendum felis dictum et. Mauris elit turpis, suscipit eget sollicitudin id, congue sed erat. Mauris fringilla semper magna eget vulputate. Fusce ut ligula a velit ultricies condimentum at hendrerit lectus.
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: Some page title!
3
+ publish: true
4
+ layout: foo
5
+ cache: false
6
+ ---
7
+
8
+ %h1 Dynamic Page!
9
+
10
+ %h2 The following time should be correct because this page is generated on every request.
11
+
12
+ %h3 Current Time:
13
+ %p
14
+ = Time.now
@@ -0,0 +1,7 @@
1
+ ---
2
+ # no front matter
3
+ ---
4
+
5
+ %h2 No front matter
6
+
7
+ This is my page.
@@ -0,0 +1,7 @@
1
+ %h1 Contact Us
2
+
3
+ %p
4
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ullamcorper justo sem. Fusce ac sem est. Aenean dignissim feugiat auctor. Vestibulum in ante sem. Ut sit amet erat arcu, eget fringilla odio. Aenean a nibh est. Cras metus urna, vulputate non feugiat vel, condimentum sit amet purus.
5
+
6
+ %p
7
+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec dictum egestas lorem. Vestibulum tempus, ante a adipiscing tempus, eros lectus mollis tellus, id viverra arcu purus vitae sapien. Suspendisse sed quam leo. Suspendisse volutpat nunc sit amet nulla venenatis ultrices. Quisque bibendum, purus pulvinar lacinia euismod, dolor tortor cursus enim, tempus porttitor magna neque in nibh. Quisque vel turpis sit amet mi semper venenatis in et arcu. Mauris mattis hendrerit turpis, tristique bibendum felis dictum et. Mauris elit turpis, suscipit eget sollicitudin id, congue sed erat. Mauris fringilla semper magna eget vulputate. Fusce ut ligula a velit ultricies condimentum at hendrerit lectus.
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: Some page title!
3
+ publish: true
4
+ layout: foo
5
+ cache: true # true by default.
6
+ ---
7
+
8
+ %h1 Static Page!
9
+
10
+ %h2 The following time should not be correct because this page is cached.
11
+
12
+ %h3 Current Time:
13
+ %p
14
+ = Time.now
@@ -0,0 +1,8 @@
1
+ ---
2
+ title: Life
3
+ publish: true
4
+ layout: post
5
+ ---
6
+
7
+ %p
8
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ullamcorper justo sem. Fusce ac sem est. Aenean dignissim feugiat auctor. Vestibulum in ante sem. Ut sit amet erat arcu, eget fringilla odio. Aenean a nibh est. Cras metus urna, vulputate non feugiat vel, condimentum sit amet purus.