adva-blog 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ class Admin::BlogsController < Admin::SectionsController
2
+ purges :create, :update, :destroy
3
+
4
+ def show
5
+ # TODO needs to be here because the admin top section drop down menu links to section#show.
6
+ # might want to invent a concept of default_action for a section type or something else.
7
+ internal_redirect_to 'admin/posts#index', params.merge(:blog_id => params.delete(:id))
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ class Admin::PostsController < Admin::BaseController
2
+ nested_belongs_to :site, :blog
3
+ purges :create, :update, :destroy
4
+ end
@@ -0,0 +1,20 @@
1
+ class PostsController < BaseController
2
+ nested_belongs_to :blog
3
+ before_filter :set_id, :only => :show
4
+
5
+ filtered_attributes :post if Adva.engine?(:markup) # FIXME move to adva-markup?
6
+
7
+ protected
8
+
9
+ def collection
10
+ # FIXME only here for reference tracking. how can we remove this?
11
+ @_references << [blog, :posts] if @_references
12
+ super
13
+ end
14
+
15
+ def set_id
16
+ blog = site.blogs.find(params[:blog_id])
17
+ permalink = params.values_at(:year, :month, :day, :slug)
18
+ params[:id] = blog.posts.by_permalink(*permalink).first.try(:id)
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ class Blog < Section
2
+ has_many :posts, :foreign_key => 'section_id', :dependent => :destroy, :order => 'created_at DESC'
3
+ # has_option :posts_per_page, :default => 15
4
+
5
+ accepts_nested_attributes_for :posts
6
+ end
@@ -0,0 +1,28 @@
1
+ class Post < Content
2
+ has_slug :scope => :section_id
3
+
4
+ validates_presence_of :title
5
+
6
+ class << self
7
+ def by_permalink(year, month, day, slug)
8
+ by_archive(year, month, day).where(:slug => slug)
9
+ end
10
+
11
+ def by_archive(*args)
12
+ where("DATE(contents.created_at) = ?", Date.new(*args.map(&:to_i)).to_formatted_s(:db))
13
+ end
14
+ end
15
+
16
+ # FIXME should be in adva-markup, shouldn't it?
17
+ def filter
18
+ read_attribute(:filter) || (section.respond_to?(:default_filter) ? section.default_filter : nil)
19
+ end
20
+
21
+ def permalink
22
+ "#{created_at.year}/#{created_at.month}/#{created_at.day}/#{slug}"
23
+ end
24
+
25
+ def to_param(name)
26
+ name == :permalink ? permalink : super()
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ Site.class_eval do
2
+ has_many :blogs
3
+ end
@@ -0,0 +1,17 @@
1
+ class Admin::Blogs::Form < Adva::View::Form
2
+ include do
3
+ def fields
4
+ form.hidden_field :type
5
+
6
+ fieldset do
7
+ column do
8
+ form.input :name
9
+ end
10
+
11
+ column do
12
+ form.input :slug
13
+ end unless params[:action] == 'new'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ class Admin::Blogs::Menu < Adva::View::Menu::Admin::Actions
2
+ include do
3
+ def main
4
+ if persisted?
5
+ label(resource.name)
6
+ item(:'.show', index_path(:posts))
7
+ item(:'.edit', edit_path)
8
+ item(:'.categories', index_path(:categories)) if Adva.engine?(:categories)
9
+ else
10
+ item(:'.sections', index_path)
11
+ end
12
+ end
13
+
14
+ def right
15
+ if persisted?
16
+ item(:'.new_item', new_path(:post))
17
+ item(:'.destroy', resource_path, :method => :delete, :confirm => t(:'.confirm_destroy', :model_name => resource.class.model_name.human))
18
+ else
19
+ item(:'.new', new_path)
20
+ end
21
+ end
22
+
23
+ protected
24
+
25
+ def active?(url, options)
26
+ # hmmm ...
27
+ types = Section.types.map { |type| type.underscore.pluralize }.join('|')
28
+ return false if url =~ %r(/admin/sites/\d+/#{types}/\d+$) && request.path != url
29
+ super
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ class Admin::Blogs::Edit < Minimal::Template
2
+ include do
3
+ def to_html
4
+ h2 :'.title'
5
+ render :partial => 'form'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ class Admin::Blogs::New < Minimal::Template
2
+ include do
3
+ def to_html
4
+ h2 :'.title'
5
+ render 'admin/sections/select_type'
6
+ render :partial => 'form'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,41 @@
1
+ class Admin::Blogs::Show < Minimal::Template
2
+ include do
3
+ def to_html
4
+ table_for resource.posts do |t|
5
+ t.column :post, :comments, :published, :author, :actions
6
+
7
+ t.row do |r, post|
8
+ r.cell link_to_post(post)
9
+ r.cell ''.html_safe # post.accept_comments? && post.comments.present? ? link_to(post.comments.size, admin_comments_path) : t(:"adva.common.none")
10
+ r.cell ''.html_safe # published_at_formatted(post)
11
+ r.cell link_to_author(post)
12
+ r.cell links_to_actions([:view, :edit, :destroy], post)
13
+ end
14
+
15
+ t.foot.row do |r|
16
+ # r.cell will_paginate(@posts), :class => :pagination, :colspan => :all
17
+ end
18
+
19
+ t.empty :p, :class => 'posts list empty' do
20
+ self.t(:'.empty', :link => capture { link_to(:'.create_item', new_path(:post)) }).html_safe
21
+ end
22
+ end
23
+ end
24
+
25
+ def link_to_post(post)
26
+ status(post) + capture { link_to_edit(post.title, post) } # , :class => post.state
27
+ end
28
+
29
+ def link_to_author(post)
30
+ ''.html_safe # link_to(post.author_name, admin_site_user_path(@site, post.author))
31
+ end
32
+
33
+ def link_to_view(post)
34
+ capture { link_to(options[:text] || :'.view', public_url_for([post.section, post]), :class => :view) }
35
+ end
36
+
37
+ def status(post)
38
+ capture { span(t(:'.published'), :title => t(:'.published'), :class => 'status published') }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ class Admin::Posts::Form < Adva::View::Form
2
+ include do
3
+ def fields
4
+ fieldset do
5
+ form.input :title
6
+ form.input :body
7
+ end
8
+ end
9
+
10
+ def sidebar
11
+ if Adva.engine?(:categories) && blog.categories.present?
12
+ # TODO extract to Adva::View::Form#categorizable_tab or something
13
+ tab :categories do
14
+ fieldset do
15
+ form.has_many_through_collection_check_boxes(:categorizations, blog.categories, :name)
16
+ end
17
+ end
18
+ end
19
+
20
+ tab :options do
21
+ form.input :slug
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ class Admin::Posts::Menu < Adva::View::Menu::Admin::Actions
2
+ include do
3
+ def main
4
+ label(resource.section.name)
5
+ item(:'.show', index_path)
6
+ item(:'.edit_parent', edit_parent_path)
7
+ end
8
+
9
+ def right
10
+ item(:'.new', new_path)
11
+ if persisted?
12
+ item(:'.view', public_url)
13
+ item(:'.edit', edit_path)
14
+ item(:'.destroy', resource_path, :method => :delete, :confirm => t(:'.confirm_destroy', :model_name => resource.class.model_name.human))
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ class Admin::Posts::Edit < Minimal::Template
2
+ include do
3
+ def to_html
4
+ h2 :'.title'
5
+ render :partial => 'form'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,42 @@
1
+ class Admin::Posts::Index < Minimal::Template
2
+ include do
3
+ def to_html
4
+ table_for collection do |t|
5
+ t.column :post, :comments, :published, :author, :actions
6
+
7
+ t.row do |r, post|
8
+ r.cell link_to_post(post)
9
+ r.cell ''.html_safe # post.accept_comments? && post.comments.present? ? link_to(post.comments.size, admin_comments_path) : t(:"adva.common.none")
10
+ r.cell ''.html_safe # published_at_formatted(post)
11
+ r.cell link_to_author(post)
12
+ r.cell links_to_actions([:view, :edit, :destroy], post)
13
+ end
14
+
15
+ t.foot.row do |r|
16
+ # r.cell will_paginate(@posts), :class => :pagination, :colspan => :all
17
+ end
18
+
19
+ t.empty :p, :class => 'posts list empty' do
20
+ self.t(:'.empty', :link => capture { link_to(:'.create_item', new_path) }).html_safe
21
+ end
22
+ end
23
+ end
24
+
25
+ def link_to_post(post)
26
+ status(post) + capture { link_to_edit(post.title, post) } # , :class => post.state
27
+ end
28
+
29
+ def link_to_author(post)
30
+ ''.html_safe # link_to(post.author_name, admin_site_user_path(@site, post.author))
31
+ end
32
+
33
+ def link_to_view(post)
34
+ capture { link_to(options[:text] || :'.view', public_url_for([blog, post]), :class => :view) }
35
+ end
36
+
37
+ def status(post)
38
+ capture { span(t(:'.published'), :title => t(:'.published'), :class => 'status published') }
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,8 @@
1
+ class Admin::Posts::New < Minimal::Template
2
+ include do
3
+ def to_html
4
+ h2 :'.title'
5
+ render :partial => 'form'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ class Posts::Meta < Minimal::Template
2
+ include do
3
+ def to_html
4
+ div :class => :meta do
5
+ self << t(:'.info', :date => date, :author => nil).html_safe # TODO
6
+ end
7
+ end
8
+
9
+ def date
10
+ capture do
11
+ content_tag(:abbr, :title => post.created_at, :class => 'updated') do
12
+ self << l(post.created_at, :format => :post)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ class Posts::Index < Minimal::Template
2
+ include do
3
+ def to_html
4
+ ul :class => 'blog posts' do
5
+ collection.each do |post|
6
+ li :class => 'post hentry' do
7
+ h2 do
8
+ link_to(post.title, [post.section, post], :class => 'entry-title', :rel => 'bookmark')
9
+ end
10
+ render :partial => 'posts/meta', :locals => { :post => post }
11
+ div truncate_html(post.body, :length => 500, :omission => ' …'), :class => 'entry-content'
12
+ p do
13
+ link_to(:'.continue', [post.section, post], :class => :continue)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+
@@ -0,0 +1,11 @@
1
+ class Posts::Show < Minimal::Template
2
+ include do
3
+ def to_html
4
+ div :class => resource.class.name.underscore do
5
+ h2 { link_to(resource.title, resources, :class => 'entry-title', :rel => 'bookmark') }
6
+ render :partial => 'posts/meta', :locals => { :post => resource }
7
+ self << resource.body.html_safe
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,59 @@
1
+ en:
2
+ time:
3
+ formats:
4
+ post: "%a, %d %b %Y"
5
+ section:
6
+ types:
7
+ blog: Blog
8
+ layouts:
9
+ blog:
10
+ made_with: "Made with <a href=\"http://github.com/svenfuchs/adva-cms2\">adva cms 2</a>"
11
+ feed: Atom Feed
12
+ posts:
13
+ index:
14
+ continue: Read the rest of this post
15
+ meta:
16
+ info: "posted on %{date}"
17
+ columns:
18
+ post: Post
19
+ comments: Comments
20
+ published: Published
21
+ author: Author
22
+ actions: ""
23
+ admin:
24
+ blogs:
25
+ new:
26
+ title: Create a New Section
27
+ edit:
28
+ title: Settings
29
+ menu:
30
+ sections: Sections
31
+ categories: Categories
32
+ show: Posts
33
+ new: New
34
+ edit: Settings
35
+ destroy: Delete
36
+ new_item: New Post
37
+ confirm_destroy: "Do you really want to delete this %{model_name}?"
38
+ posts:
39
+ index:
40
+ view: View
41
+ edit: Edit
42
+ destroy: Delete
43
+ published: Published
44
+ empty: "There are no posts. %{link}"
45
+ create_item: "Create one now &raquo;"
46
+ confirm_destroy: "Do you really want to delete this %{model_name}?"
47
+ new:
48
+ title: Write a new blog post
49
+ edit:
50
+ title: Edit Post
51
+ delete: Delete
52
+ menu:
53
+ show: Posts
54
+ edit_parent: Settings
55
+ new: New Post
56
+ view: View
57
+ edit: Edit
58
+ destroy: Delete
59
+ confirm_destroy: "Do you really want to delete this %{model_name}?"
@@ -0,0 +1,6 @@
1
+ Adva::Registry.set :redirect, {
2
+ 'admin/blogs#update' => lambda { |c| c.edit_url },
3
+ 'admin/posts#create' => lambda { |c| c.edit_url },
4
+ 'admin/posts#update' => lambda { |c| c.edit_url },
5
+ 'admin/posts#destroy' => lambda { |c| c.show_parent_url }
6
+ }
data/config/routes.rb ADDED
@@ -0,0 +1,18 @@
1
+ Rails.application.routes.draw do
2
+ namespace :admin do
3
+ resources :sites do
4
+ resources :blogs do
5
+ resources :posts
6
+ end
7
+ end
8
+ end
9
+
10
+ constraints :year => /\d{4}/, :month => /\d{1,2}/, :day => /\d{1,2}/ do
11
+ match 'blogs/:blog_id(/:year(/:month(/:day)))', :to => 'posts#index', :as => :blog
12
+ match 'blogs/:blog_id/:year/:month/:day/:slug', :to => 'posts#show'
13
+ end
14
+
15
+ # this is just here so we get the named url helper and can use url_for(blog, post)
16
+ # TODO how can we improve this?
17
+ match 'blogs/:blog_id/*permalink', :to => "posts#internal", :as => :blog_post
18
+ end
data/lib/adva/blog.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'adva/core'
2
+ require 'adva/engine'
3
+
4
+ require 'routing_filter'
5
+ require 'adva/routing_filters/section_root'
6
+
7
+ require 'action_controller' # really should be in truncate_html
8
+ require 'truncate_html'
9
+
10
+ module Adva
11
+ class Blog < ::Rails::Engine
12
+ include Adva::Engine
13
+
14
+ initializer 'adva-blog.require_section_types' do
15
+ config.to_prepare { require_dependency 'blog' }
16
+ end
17
+
18
+ initializer 'adva-blog.configure_routing_filters' do
19
+ RoutingFilter::SectionRoot.anchors << '\d{4}'
20
+ end
21
+ end
22
+ end
23
+
data/lib/adva-blog.rb ADDED
@@ -0,0 +1 @@
1
+ require 'adva/blog'
@@ -0,0 +1,9 @@
1
+ Factory.define :blog do |f|
2
+ f.name 'Blog'
3
+ end
4
+
5
+ Factory.define :post do |f|
6
+ f.section Blog.first
7
+ f.title 'Title'
8
+ f.body 'Body'
9
+ end
@@ -0,0 +1,19 @@
1
+ module Adva::Blog::Paths
2
+ def path_to(page)
3
+ case page
4
+
5
+ when /^the admin posts list page of the "([^"]*)" blog$/
6
+ section = Blog.find_by_name($1) || raise("could not find blog #{$1.inspect}")
7
+ polymorphic_path([:admin, section.site, section])
8
+
9
+ when /^the admin edit post page for the post "([^"]*)"$/
10
+ post = Post.find_by_title($1) || raise("could not find post #{$1.inspect}")
11
+ polymorphic_path([:edit, :admin, post.section.site, post.section, post])
12
+
13
+ else
14
+ super
15
+ end
16
+ end
17
+ end
18
+
19
+ World(Adva::Blog::Paths)
File without changes
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adva-blog
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ingo Weiss
14
+ - Sven Fuchs
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-10-29 00:00:00 +02:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: adva-core
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: truncate_html
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ description: "[description]"
51
+ email: nobody@adva-cms.org
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - app/controllers/posts_controller.rb
60
+ - app/controllers/admin/blogs_controller.rb
61
+ - app/controllers/admin/posts_controller.rb
62
+ - app/views/admin/blogs/show.html.rb
63
+ - app/views/admin/blogs/edit.html.rb
64
+ - app/views/admin/blogs/new.html.rb
65
+ - app/views/admin/blogs/_form.html.rb
66
+ - app/views/admin/blogs/_menu.html.rb
67
+ - app/views/admin/posts/index.html.rb
68
+ - app/views/admin/posts/edit.html.rb
69
+ - app/views/admin/posts/new.html.rb
70
+ - app/views/admin/posts/_form.html.rb
71
+ - app/views/admin/posts/_menu.html.rb
72
+ - app/views/posts/index.html.rb
73
+ - app/views/posts/show.html.rb
74
+ - app/views/posts/_meta.html.rb
75
+ - app/models/post.rb
76
+ - app/models/site_slice.rb
77
+ - app/models/blog.rb
78
+ - config/redirects.rb
79
+ - config/routes.rb
80
+ - config/locales/en.yml
81
+ - lib/adva/blog.rb
82
+ - lib/testing/factories.rb
83
+ - lib/testing/paths.rb
84
+ - lib/adva-blog.rb
85
+ - public/stylesheets/default/blog.css
86
+ has_rdoc: true
87
+ homepage: http://github.com/svenfuchs/adva-cms2
88
+ licenses: []
89
+
90
+ post_install_message:
91
+ rdoc_options: []
92
+
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 3
110
+ segments:
111
+ - 0
112
+ version: "0"
113
+ requirements: []
114
+
115
+ rubyforge_project: "[none]"
116
+ rubygems_version: 1.3.7
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: "[summary]"
120
+ test_files: []
121
+