staticpress 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/.gitignore +9 -0
  2. data/.rbenv-version +1 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +3 -0
  5. data/Rakefile +21 -0
  6. data/bin/staticpress +6 -0
  7. data/lib/skeleton/Gemfile +10 -0
  8. data/lib/skeleton/README.markdown +21 -0
  9. data/lib/skeleton/config.rb +14 -0
  10. data/lib/skeleton/config.ru +8 -0
  11. data/lib/skeleton/config.yml +63 -0
  12. data/lib/staticpress/booter.rb +7 -0
  13. data/lib/staticpress/cli.rb +123 -0
  14. data/lib/staticpress/configuration.rb +24 -0
  15. data/lib/staticpress/content/base.rb +122 -0
  16. data/lib/staticpress/content/category.rb +34 -0
  17. data/lib/staticpress/content/collection_content.rb +13 -0
  18. data/lib/staticpress/content/index.rb +20 -0
  19. data/lib/staticpress/content/page.rb +64 -0
  20. data/lib/staticpress/content/post.rb +88 -0
  21. data/lib/staticpress/content/resource_content.rb +28 -0
  22. data/lib/staticpress/content/static_content.rb +24 -0
  23. data/lib/staticpress/content/tag.rb +34 -0
  24. data/lib/staticpress/content/theme.rb +48 -0
  25. data/lib/staticpress/error.rb +4 -0
  26. data/lib/staticpress/helpers.rb +57 -0
  27. data/lib/staticpress/js_object.rb +51 -0
  28. data/lib/staticpress/metadata.rb +24 -0
  29. data/lib/staticpress/plugin.rb +33 -0
  30. data/lib/staticpress/plugins/blockquote.rb +6 -0
  31. data/lib/staticpress/plugins/gist.rb +6 -0
  32. data/lib/staticpress/plugins/titlecase.rb +6 -0
  33. data/lib/staticpress/plugins.rb +6 -0
  34. data/lib/staticpress/route.rb +123 -0
  35. data/lib/staticpress/server.rb +21 -0
  36. data/lib/staticpress/site.rb +57 -0
  37. data/lib/staticpress/theme.rb +43 -0
  38. data/lib/staticpress/version.rb +12 -0
  39. data/lib/staticpress/view_helpers.rb +35 -0
  40. data/lib/staticpress.rb +15 -0
  41. data/lib/themes/classic/assets/scripts/application.js +4 -0
  42. data/lib/themes/classic/assets/styles/all.sass +0 -0
  43. data/lib/themes/classic/includes/list_posts.haml +3 -0
  44. data/lib/themes/classic/layouts/archive.haml +0 -0
  45. data/lib/themes/classic/layouts/atom.haml +0 -0
  46. data/lib/themes/classic/layouts/default.haml +5 -0
  47. data/lib/themes/classic/layouts/index.haml +0 -0
  48. data/lib/themes/classic/layouts/post_index.haml +5 -0
  49. data/lib/themes/classic/views/default.haml +5 -0
  50. data/staticpress.gemspec +33 -0
  51. data/tests/lib/staticpress/cli_test.rb +65 -0
  52. data/tests/lib/staticpress/configuration_test.rb +4 -0
  53. data/tests/lib/staticpress/content/base_test.rb +9 -0
  54. data/tests/lib/staticpress/content/category_test.rb +62 -0
  55. data/tests/lib/staticpress/content/index_test.rb +45 -0
  56. data/tests/lib/staticpress/content/page_test.rb +133 -0
  57. data/tests/lib/staticpress/content/post_test.rb +81 -0
  58. data/tests/lib/staticpress/content/tag_test.rb +60 -0
  59. data/tests/lib/staticpress/content/theme_test.rb +103 -0
  60. data/tests/lib/staticpress/helpers_test.rb +57 -0
  61. data/tests/lib/staticpress/js_object_test.rb +45 -0
  62. data/tests/lib/staticpress/metadata_test.rb +19 -0
  63. data/tests/lib/staticpress/plugin_test.rb +4 -0
  64. data/tests/lib/staticpress/route_test.rb +210 -0
  65. data/tests/lib/staticpress/server_test.rb +4 -0
  66. data/tests/lib/staticpress/site_test.rb +25 -0
  67. data/tests/lib/staticpress/theme_test.rb +68 -0
  68. data/tests/lib/staticpress/view_helpers_test.rb +32 -0
  69. data/tests/lib/staticpress_test.rb +15 -0
  70. data/tests/sample_sites/test_blog/Gemfile +10 -0
  71. data/tests/sample_sites/test_blog/README.markdown +21 -0
  72. data/tests/sample_sites/test_blog/config.rb +14 -0
  73. data/tests/sample_sites/test_blog/config.ru +8 -0
  74. data/tests/sample_sites/test_blog/config.yml +4 -0
  75. data/tests/sample_sites/test_blog/content/_posts/2011-07-20-hello.markdown +5 -0
  76. data/tests/sample_sites/test_blog/content/_posts/2011-08-01-announcing-staticpress.markdown +7 -0
  77. data/tests/sample_sites/test_blog/content/_posts/2011-08-02-staticpress.markdown +7 -0
  78. data/tests/sample_sites/test_blog/content/_posts/2011-08-06-blogging-with-staticpress.markdown +7 -0
  79. data/tests/sample_sites/test_blog/content/_posts/2011-08-06-conferences.markdown +5 -0
  80. data/tests/sample_sites/test_blog/content/_posts/2011-08-06-in-charlotte.markdown +9 -0
  81. data/tests/sample_sites/test_blog/content/_posts/2011-08-20-forever.markdown +1 -0
  82. data/tests/sample_sites/test_blog/content/about.markdown +1 -0
  83. data/tests/sample_sites/test_blog/content/contact.markdown +3 -0
  84. data/tests/sample_sites/test_blog/content/foo/bar/baz.markdown +1 -0
  85. data/tests/sample_sites/test_blog/content/plain.txt +1 -0
  86. data/tests/sample_sites/test_blog/content/ruby.png +0 -0
  87. data/tests/sample_sites/test_blog/content/style1.css +3 -0
  88. data/tests/sample_sites/test_blog/content/style2.css.sass +2 -0
  89. data/tests/sample_sites/test_blog/content/style3.sass +2 -0
  90. data/tests/test_helper.rb +17 -0
  91. data.tar.gz.sig +0 -0
  92. metadata +255 -0
  93. metadata.gz.sig +3 -0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ .bundle
3
+ .DS_Store
4
+ .sass-cache
5
+ .gist_cache
6
+ _cache
7
+ Gemfile.lock
8
+ pkg/*
9
+ public
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.2-p290
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2@development
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'pathname'
3
+
4
+ task :default => [ :tests ]
5
+
6
+ desc 'Run all tests in path specified (defaults to tests). Tell Rake to start at a specific path with `rake tests[\'tests/lib/staticpress/content\']`'
7
+ task :tests, :path do |t, args|
8
+ args.with_defaults(:path => 'tests')
9
+
10
+ run_recursively = lambda do |dir|
11
+ Pathname.new(dir).expand_path.children.each do |dir_or_test|
12
+ if dir_or_test.directory?
13
+ run_recursively.call dir_or_test
14
+ elsif dir_or_test.to_s.end_with? '_test.rb'
15
+ require_relative dir_or_test
16
+ end
17
+ end
18
+ end
19
+
20
+ run_recursively.call args[:path]
21
+ end
data/bin/staticpress ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'staticpress/booter'
4
+ require 'staticpress/cli'
5
+
6
+ Staticpress::CLI.start
@@ -0,0 +1,10 @@
1
+ source :rubygems
2
+
3
+ gem 'staticpress'
4
+
5
+ gem 'compass'
6
+ gem 'haml'
7
+ gem 'rdiscount'
8
+ gem 'rubypants'
9
+ gem 'RedCloth'
10
+ gem 'sass'
@@ -0,0 +1,21 @@
1
+ * copies lib/skeletons/new to <path-to-blog>
2
+ * this should edit the blog's config.yml to include [name-of-blog] (prompt for [name-of-blog] if blank)
3
+ $ staticpress new <path-to-blog> [name-of-blog]
4
+ $ cd <path-to-blog>
5
+
6
+ * copies <plugin-name> into <path-to-blog>/plugins/
7
+ $ staticpress fork_plugin <plugin-name>
8
+
9
+ * setting the theme is done in the main config file, this command is optional and
10
+ * just copies the theme's file into <path-to-blog>/themes/[theme-name] for customizations
11
+ * if [theme-name] is blank, default to the currently configured theme
12
+ $ staticpress fork_theme [theme-name]
13
+
14
+ * turn on local server for development
15
+ $ staticpress serve
16
+
17
+ * prepare blog for deployment
18
+ $ staticpress package
19
+
20
+ * deploy blog
21
+ $ staticpress deploy
@@ -0,0 +1,14 @@
1
+ # Require any additional compass plugins here.
2
+ project_type = :stand_alone
3
+
4
+ # Set this to the root of your project when deployed:
5
+ http_path = '/'
6
+ css_dir = 'public/stylesheets'
7
+ sass_dir = 'sass'
8
+ images_dir = 'source/images'
9
+ http_images_dir = 'images'
10
+ fonts_dir = 'source/fonts'
11
+ http_fonts_dir = 'fonts'
12
+
13
+ line_comments = false
14
+ output_style = :compressed
@@ -0,0 +1,8 @@
1
+ require 'staticpress/booter'
2
+ require 'staticpress/server'
3
+
4
+ use Rack::ShowStatus
5
+ use Rack::ShowExceptions
6
+
7
+ # TODO run on configured port
8
+ run Staticpress::Server.new
@@ -0,0 +1,63 @@
1
+ ---
2
+ :source: content
3
+ :posts_source: content/_posts
4
+ :plugins: []
5
+ :plugins_path: plugins
6
+ :destination: public
7
+ :index_file: index.html
8
+ :markup_templates:
9
+ - builder
10
+ - creole
11
+ - erb
12
+ - erubis
13
+ - haml
14
+ - liquid
15
+ - mab
16
+ - markdown
17
+ - md
18
+ - mediawiki
19
+ - mkd
20
+ - mw
21
+ - nokogiri
22
+ - radius
23
+ - rdoc
24
+ - rhtml
25
+ - str
26
+ - textile
27
+ - wiki
28
+ :code_dir: downloads/code
29
+ :port: 4000
30
+ :url: http://yoursite.com
31
+ :preferred_format: markdown
32
+ :routes:
33
+ :index: '/(page/:number)?'
34
+ :category: '/category/:name(/page/:number)?'
35
+ :tag: '/tag/:name(/page/:number)?'
36
+ :page: '/:slug'
37
+ :post: '/:year/:month/:day/:title'
38
+ :theme: '/assets/:theme/:asset_type/:slug'
39
+ :title: My Staticpress Blog
40
+ :subtitle: A blogging framework for hackers.
41
+ :author: Your Name
42
+ :subscribe_rss: /atom.xml
43
+ :subscribe_email:
44
+ :posts_per_page: 10
45
+ :markdown: rdiscount
46
+ :pygments: true
47
+ :paginate: 5
48
+ :recent_posts: 5
49
+ :simple_search: http://google.com/search
50
+ :email:
51
+ :theme: classic
52
+ :twitter_user:
53
+ :twitter_tweet_count: 4
54
+ :twitter_show_replies: false
55
+ :twitter_follow_button: true
56
+ :twitter_show_follower_count: false
57
+ :twitter_tweet_button: true
58
+ :pinboard_user:
59
+ :pinboard_count: 3
60
+ :delicious_user:
61
+ :delicious_count: 3
62
+ :disqus_short_name:
63
+ :google_analytics_tracking_id:
@@ -0,0 +1,7 @@
1
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('./Gemfile')
2
+
3
+ if File.exists?(ENV['BUNDLE_GEMFILE']) && !defined? Bundler
4
+ require 'bundler'
5
+
6
+ Bundler.require
7
+ end
@@ -0,0 +1,123 @@
1
+ # http://practicingruby.com/articles/shared/ozkzbsdmagcm
2
+
3
+ require 'fileutils'
4
+ require 'pathname'
5
+ require 'rack'
6
+ require 'thor'
7
+
8
+ require 'staticpress'
9
+ require 'staticpress/error'
10
+ require 'staticpress/helpers'
11
+ require 'staticpress/plugin'
12
+ require 'staticpress/site'
13
+ require 'staticpress/version'
14
+
15
+ module Staticpress
16
+ class CLI < Thor
17
+ include Thor::Actions
18
+ include Staticpress::Helpers
19
+
20
+ default_task :help
21
+
22
+ desc 'help [task]', 'Describe available tasks or one specific task'
23
+ def help(*args)
24
+ general_usage = <<-USAGE
25
+ Usage:
26
+ staticpress <task> <required-argument> [option-argument]
27
+
28
+ USAGE
29
+ puts general_usage if args.empty?
30
+ super
31
+ end
32
+
33
+ desc 'new <path-to-blog> [name-of-blog]', 'Creates a new blog in <path-to-blog>'
34
+ long_desc <<-DESCRIPTION
35
+ Creates a new blog in <path-to-blog>. <path-to-blog> will be created if it does
36
+ not exist, and files will be overwritten if they do exist
37
+ DESCRIPTION
38
+ def new(destination, name = nil)
39
+ Staticpress.blog_path = destination
40
+
41
+ FileUtils.mkdir_p Staticpress.blog_path
42
+ FileUtils.cp_r((Staticpress.root + 'skeleton').children, Staticpress.blog_path)
43
+
44
+ config.title = if name.to_s.empty?
45
+ Staticpress.blog_path.basename.to_s.split('_').map(&:capitalize).join(' ')
46
+ else
47
+ name
48
+ end
49
+
50
+ config.save
51
+ end
52
+
53
+ desc 'create <title>', 'Create a new blog post'
54
+ def create(title)
55
+ Staticpress::Content::Post.create config.preferred_format, title
56
+ end
57
+
58
+ desc 'create_page <title> [path-in-content]', 'Create a new page in [path-in-content]'
59
+ def create_page(title, path = nil)
60
+ Staticpress::Content::Page.create config.preferred_format, title, path
61
+ end
62
+
63
+ desc 'fork_plugin <plugin-name> [new-plugin-name]', 'Copies <plugin-name> into <path-to-blog>/plugins/'
64
+ long_desc <<-DESCRIPTION
65
+ Copies <plugin-name> into <path-to-blog>/plugins/. If [new-plugin-name] is
66
+ given, rename plugin in the destination. Be sure to activate the plugin
67
+ in config.yml
68
+ DESCRIPTION
69
+ def fork_plugin(name, new_name = nil)
70
+ source = Staticpress::Plugin.find name
71
+
72
+ destination_name = new_name ? (new_name.end_with?('.rb') ? new_name : "#{new_name}.rb") : source.basename
73
+ destination = Staticpress.blog_path + (config.plugins_path || 'plugins') + destination_name
74
+
75
+ FileUtils.mkdir_p destination.dirname
76
+ FileUtils.cp source, destination
77
+ end
78
+
79
+ desc 'fork_theme [theme-name]', 'Copies [theme-name]\'s files into <path-to-blog>/themes/[theme-name]'
80
+ long_desc <<-DESCRIPTION
81
+ Copies [theme-name]'s files into <path-to-blog>/themes/[theme-name] for
82
+ customizations. If [theme-name] is blank, copies the currently configured theme
83
+ DESCRIPTION
84
+ def fork_theme(name = nil)
85
+ theme_name = name ? name : config.theme
86
+ source = Staticpress.root + 'themes' + theme_name
87
+ destination = Staticpress.blog_path + 'themes' + theme_name
88
+
89
+ FileUtils.mkdir_p destination
90
+ FileUtils.cp_r source.children, destination
91
+ end
92
+
93
+ desc 'list [method]', 'Send [method] to every content and output the result, or list all content if [method] is not present'
94
+ def list(method = nil)
95
+ all_content = Staticpress::Site.new.all_content
96
+ puts(method ? all_content.map(&method.to_sym) : all_content)
97
+ end
98
+
99
+ desc 'build', 'Prepare blog for deployment'
100
+ def build
101
+ Staticpress::Site.new.save
102
+ end
103
+
104
+ desc 'serve', 'Turn on local server for development'
105
+ def serve
106
+ Rack::Server.new(:config => (Staticpress.blog_path + 'config.ru').to_s, :Port => config.port).start
107
+ end
108
+
109
+ desc 'push', 'Push blog to configured server'
110
+ def push
111
+ end
112
+
113
+ desc 'deploy', 'Build blog and push in one step'
114
+ def deploy
115
+ build and push
116
+ end
117
+
118
+ desc 'version', 'Display version'
119
+ def version
120
+ puts "Staticpress #{Staticpress::Version}"
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,24 @@
1
+ require 'yaml'
2
+
3
+ require 'staticpress'
4
+ require 'staticpress/js_object'
5
+
6
+ module Staticpress
7
+ # IDEA look into configatron https://github.com/markbates/configatron
8
+ class Configuration < JSObject
9
+ def save
10
+ (Staticpress.blog_path + 'config.yml').open('w') do |f|
11
+ custom_values = self - self.class.default
12
+ YAML.dump(custom_values.to_hash, f)
13
+ end
14
+ end
15
+
16
+ def self.default
17
+ @default ||= new(YAML.load_file(Staticpress.root + 'skeleton' + 'config.yml'))
18
+ end
19
+
20
+ def self.instance
21
+ @config ||= new(default.to_hash.merge(YAML.load_file(Staticpress.blog_path + 'config.yml')))
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,122 @@
1
+ require 'fileutils'
2
+ require 'tilt'
3
+ require 'yaml'
4
+
5
+ require 'staticpress'
6
+ require 'staticpress/metadata'
7
+ require 'staticpress/theme'
8
+ require 'staticpress/view_helpers'
9
+
10
+ module Staticpress::Content
11
+ class Base
12
+ extend Staticpress::Helpers
13
+ include Staticpress::Helpers
14
+
15
+ attr_reader :route, :template_path
16
+
17
+ def initialize(route, template_path)
18
+ @route = route
19
+ @template_path = template_path
20
+ end
21
+
22
+ def ==(other)
23
+ other.respond_to?(:route) && (route == other.route)
24
+ end
25
+
26
+ def content
27
+ return @content if @content
28
+
29
+ regex_frontmatter = /^-{3}${1}(?<frontmatter>.*)^-{3}${1}/m
30
+ regex_text = /(?<text>.*)/m
31
+ regex = /#{regex_frontmatter}#{regex_text}/
32
+
33
+ c = template_path_content
34
+ @content = c.match(regex_frontmatter) ? c.match(regex) : c.match(regex_text)
35
+ end
36
+
37
+ def exist?
38
+ template_path.file?
39
+ end
40
+
41
+ def inspect
42
+ parts = [ "url_path=#{route.url_path}" ]
43
+
44
+ "#<#{self.class} #{parts.join ', '}>"
45
+ end
46
+ alias to_s inspect
47
+
48
+ def layout
49
+ if meta.layout || config.markup_templates.include?(template_path.extname[1..-1])
50
+ layout_name = meta.layout || :default
51
+ Tilt.new theme.layout_for(layout_name).to_s
52
+ end
53
+ end
54
+
55
+ def meta
56
+ Staticpress::Metadata.new(content.names.include?('frontmatter') ? YAML.load(content[:frontmatter]) : {})
57
+ end
58
+
59
+ def output_path
60
+ base = Staticpress.blog_path + config.destination + route.url_path.sub(/^\//, '')
61
+ (config.index_file && config.markup_templates.include?(template_path.extname[1..-1])) ? base + config.index_file : base
62
+ end
63
+
64
+ def raw
65
+ content[:text].strip
66
+ end
67
+
68
+ def render(locals = {})
69
+ if l = layout
70
+ l.render template_context, locals do
71
+ render_partial locals
72
+ end
73
+ else
74
+ render_partial locals
75
+ end
76
+ end
77
+
78
+ def render_partial(locals = {})
79
+ template = Tilt[template_path].new { raw }
80
+ template.render template_context, locals
81
+ end
82
+
83
+ def save
84
+ FileUtils.mkdir_p output_path.dirname
85
+ output_path.open('w') { |f| f.write render }
86
+ end
87
+
88
+ def template_context
89
+ Staticpress::ViewHelpers.new self
90
+ end
91
+
92
+ def template_path_content
93
+ exist? ? template_path.read : ''
94
+ end
95
+
96
+ def theme
97
+ self.class.theme
98
+ end
99
+
100
+ def title
101
+ if meta.title
102
+ meta.title
103
+ else
104
+ route.url_path.split(/\/-/).map do |word|
105
+ word.capitalize
106
+ end.join ' '
107
+ end
108
+ end
109
+
110
+ def self.supported_extensions
111
+ Tilt.mappings.keys.map &:to_sym
112
+ end
113
+
114
+ def self.theme
115
+ Staticpress::Theme.theme
116
+ end
117
+
118
+ def self.type
119
+ name.split('::').last.downcase
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,34 @@
1
+ require 'staticpress'
2
+ require 'staticpress/content/base'
3
+ require 'staticpress/content/collection_content'
4
+ require 'staticpress/route'
5
+
6
+ module Staticpress::Content
7
+ class Category < Base
8
+ extend CollectionContent
9
+
10
+ def sub_content
11
+ paginate(self.class.content_by_category[route.params[:name]].sort)[(Integer route.params[:number]) - 1]
12
+ end
13
+
14
+ def self.all
15
+ categories.map do |category|
16
+ find_by_route Staticpress::Route.new(:content_type => self, :name => category, :number => '1')
17
+ end
18
+ end
19
+
20
+ def self.categories
21
+ content_by_category.keys
22
+ end
23
+
24
+ def self.content_by_category
25
+ reply = {}
26
+ Staticpress::Content::Post.all.each do |post|
27
+ (post.meta.categories || []).each do |category|
28
+ (reply[category] ||= []) << post
29
+ end
30
+ end
31
+ reply
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,13 @@
1
+ require 'staticpress'
2
+
3
+ module Staticpress::Content
4
+ module CollectionContent
5
+ def find_by_route(route)
6
+ new(route, template_path)
7
+ end
8
+
9
+ def template_path
10
+ theme.view_for(type) || theme.view_for(:default)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ require 'staticpress'
2
+ require 'staticpress/content/base'
3
+ require 'staticpress/content/collection_content'
4
+ require 'staticpress/route'
5
+
6
+ module Staticpress::Content
7
+ class Index < Base
8
+ extend CollectionContent
9
+
10
+ def sub_content
11
+ paginate(Staticpress::Content::Post.all)[(Integer route.params[:number]) - 1]
12
+ end
13
+
14
+ def self.all
15
+ [
16
+ (find_by_route Staticpress::Route.new(:content_type => self, :number => '1'))
17
+ ]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,64 @@
1
+ require 'staticpress'
2
+ require 'staticpress/content/base'
3
+ require 'staticpress/content/resource_content'
4
+ require 'staticpress/content/static_content'
5
+ require 'staticpress/route'
6
+
7
+ module Staticpress::Content
8
+ class Page < Base
9
+ include StaticContent
10
+ extend ResourceContent
11
+ extend StaticContent
12
+
13
+ def static?
14
+ (Staticpress.blog_path + config.source + route.params[:slug]).file?
15
+ end
16
+
17
+ def self.all
18
+ all_but_posts = if (posts_dir = Staticpress.blog_path + config.posts_source).directory?
19
+ (Staticpress.blog_path + config.source).children - [ posts_dir ]
20
+ else
21
+ (Staticpress.blog_path + config.source).children
22
+ end
23
+
24
+ gather_resources_from all_but_posts
25
+ end
26
+
27
+ def self.create(format, title, path = nil)
28
+ name = title.gsub(/ /, '-').downcase
29
+
30
+ filename = "#{name}.#{format}"
31
+ destination = Staticpress.blog_path + config.source + (path ? path : '').sub(/^\//, '') + filename
32
+
33
+ FileUtils.mkdir_p destination.dirname
34
+ destination.open('w') { |f| f.write template }
35
+ end
36
+
37
+ def self.find_by_path(path)
38
+ if path.file?
39
+ params = {
40
+ :content_type => self,
41
+ :slug => parse_slug(path, (Staticpress.blog_path + config.source))
42
+ }
43
+
44
+ find_by_route Staticpress::Route.new(params)
45
+ end
46
+ end
47
+
48
+ def self.find_by_route(route)
49
+ return nil unless route
50
+
51
+ base = Staticpress.blog_path + config.source
52
+ path = base + route.params[:slug]
53
+ return new(route, path) if path.file?
54
+
55
+ load_resource route, base, route.params[:slug]
56
+ end
57
+
58
+ def self.template
59
+ <<-TEMPLATE
60
+ in page
61
+ TEMPLATE
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,88 @@
1
+ require 'staticpress'
2
+ require 'staticpress/content/base'
3
+ require 'staticpress/content/resource_content'
4
+ require 'staticpress/route'
5
+
6
+ module Staticpress::Content
7
+ class Post < Base
8
+ extend ResourceContent
9
+
10
+ def <=>(other)
11
+ other.respond_to?(:created_at) ? (created_at <=> other.created_at) : super
12
+ end
13
+
14
+ def created_at
15
+ meta.created_at ? meta.created_at : created_on
16
+ end
17
+
18
+ def created_on
19
+ date = route.params
20
+ Time.utc date[:year], date[:month], date[:day]
21
+ end
22
+
23
+ def self.all
24
+ if (posts_dir = Staticpress.blog_path + config.posts_source).directory?
25
+ posts_dir.children.map { |post| find_by_path post }
26
+ else
27
+ []
28
+ end
29
+ end
30
+
31
+ def self.create(format, title)
32
+ now = Time.now.utc
33
+ created_on = "#{now.year}-#{'%02d' % now.month}-#{'%02d' % now.day}"
34
+ name = title.gsub(/ /, '-').downcase
35
+
36
+ filename = "#{created_on}-#{name}.#{format}"
37
+ destination = Staticpress.blog_path + config.posts_source + filename
38
+
39
+ FileUtils.mkdir_p destination.dirname
40
+ destination.open('w') { |f| f.write template }
41
+ end
42
+
43
+ def self.find_by_path(path)
44
+ if path.file?
45
+ stubs = Staticpress::Route::REGEX_STUBS
46
+ regex = /#{stubs[:year].regex}-#{stubs[:month].regex}-#{stubs[:day].regex}-#{stubs[:title].regex}/
47
+
48
+ if filename_parts = path.basename.to_s.match(regex)
49
+ params = {
50
+ :content_type => self,
51
+ :year => filename_parts[:year],
52
+ :month => filename_parts[:month],
53
+ :day => filename_parts[:day],
54
+ :title => filename_parts[:title]
55
+ }
56
+ find_by_route Staticpress::Route.new(params)
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.find_by_route(route)
62
+ return nil unless route
63
+
64
+ base = Staticpress.blog_path + config.posts_source
65
+ parts = route.params
66
+ stub = [
67
+ parts[:year],
68
+ parts[:month],
69
+ parts[:day],
70
+ parts[:title]
71
+ ].join '-'
72
+
73
+ load_resource route, base, stub
74
+ end
75
+
76
+ def self.template
77
+ now = Time.now.utc
78
+
79
+ <<-TEMPLATE
80
+ ---
81
+ created_at: #{now}
82
+ ---
83
+
84
+ in post
85
+ TEMPLATE
86
+ end
87
+ end
88
+ end