├── app ├── views │ ├── .gitkeep │ └── refinery │ │ ├── blog │ │ ├── admin │ │ │ ├── comments │ │ │ │ ├── approve.html.erb │ │ │ │ ├── _sortable_list.html.erb │ │ │ │ ├── index.html.erb │ │ │ │ ├── _comment.html.erb │ │ │ │ └── show.html.erb │ │ │ ├── posts │ │ │ │ ├── new.html.erb │ │ │ │ ├── edit.html.erb │ │ │ │ ├── _form_part.html.erb │ │ │ │ ├── _sortable_list.html.erb │ │ │ │ ├── _teaser_part.html.erb │ │ │ │ ├── uncategorized.html.erb │ │ │ │ ├── index.html.erb │ │ │ │ ├── _post.html.erb │ │ │ │ └── _form.html.erb │ │ │ ├── categories │ │ │ │ ├── new.html.erb │ │ │ │ ├── edit.html.erb │ │ │ │ ├── _sortable_list.html.erb │ │ │ │ ├── _form.html.erb │ │ │ │ ├── index.html.erb │ │ │ │ └── _category.html.erb │ │ │ ├── shared │ │ │ │ └── _locale_picker.html.erb │ │ │ ├── settings │ │ │ │ └── notification_recipients.html.erb │ │ │ └── _submenu.html.erb │ │ ├── shared │ │ │ ├── _rss_feed.html.erb │ │ │ ├── _posts.html.erb │ │ │ ├── _tags.html.erb │ │ │ ├── _body_content_right.html.erb │ │ │ ├── _categories.html.erb │ │ │ └── _post.html.erb │ │ ├── widgets │ │ │ └── _blog_archive.html.erb │ │ ├── posts │ │ │ ├── index.rss.builder │ │ │ ├── _comment.html.erb │ │ │ ├── _nav.html.erb │ │ │ ├── archive.html.erb │ │ │ ├── tagged.html.erb │ │ │ ├── show.html.erb │ │ │ ├── index.html.erb │ │ │ ├── _comments.html.erb │ │ │ └── _post.html.erb │ │ ├── categories │ │ │ └── show.html.erb │ │ └── comment_mailer │ │ │ └── notification.html.erb │ │ └── shared │ │ └── admin │ │ └── _autocomplete.html.erb ├── helpers │ ├── .gitkeep │ └── refinery │ │ └── blog │ │ ├── controller_helper.rb │ │ └── posts_helper.rb ├── models │ ├── .gitkeep │ └── refinery │ │ ├── categorization.rb │ │ └── blog │ │ ├── category.rb │ │ ├── comment.rb │ │ └── post.rb ├── controllers │ ├── .gitkeep │ └── refinery │ │ └── blog │ │ ├── admin │ │ ├── categories_controller.rb │ │ ├── comments_controller.rb │ │ ├── settings_controller.rb │ │ └── posts_controller.rb │ │ ├── categories_controller.rb │ │ ├── blog_controller.rb │ │ └── posts_controller.rb ├── assets │ ├── images │ │ └── refinery │ │ │ └── blog │ │ │ ├── icons │ │ │ ├── cog.png │ │ │ ├── down.gif │ │ │ ├── page.png │ │ │ ├── up.gif │ │ │ ├── folder.png │ │ │ ├── comment.png │ │ │ ├── comments.png │ │ │ ├── page_add.png │ │ │ ├── page_copy.png │ │ │ ├── folder_add.png │ │ │ ├── folder_edit.png │ │ │ ├── comment_cross.png │ │ │ └── comment_tick.png │ │ │ └── rss-feed.png │ ├── stylesheets │ │ └── refinery │ │ │ └── blog │ │ │ ├── ui-lightness │ │ │ └── images │ │ │ │ ├── ui-icons_222222_256x240.png │ │ │ │ ├── ui-icons_228ef1_256x240.png │ │ │ │ ├── ui-icons_ef8c08_256x240.png │ │ │ │ ├── ui-icons_ffd27a_256x240.png │ │ │ │ ├── ui-icons_ffffff_256x240.png │ │ │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ │ │ └── ui-bg_highlight-soft_75_ffe45c_1x100.png │ │ │ ├── backend.css.scss │ │ │ └── frontend.css.scss │ └── javascripts │ │ └── refinery │ │ └── blog │ │ ├── frontend.js │ │ └── backend.js └── mailers │ └── refinery │ └── blog │ └── comment_mailer.rb ├── .rspec ├── lib ├── refinerycms-blog.rb ├── refinery │ ├── blog │ │ ├── version.rb │ │ ├── configuration.rb │ │ ├── tabs.rb │ │ └── engine.rb │ └── blog.rb └── generators │ └── refinery │ └── blog │ ├── templates │ └── config │ │ └── initializers │ │ └── refinery │ │ └── blog.rb.erb │ └── blog_generator.rb ├── tasks └── rspec.rake ├── todo.md ├── spec ├── factories │ ├── blog_categories.rb │ ├── blog_posts.rb │ └── blog_comments.rb ├── requests │ └── refinery │ │ └── blog │ │ ├── admin │ │ ├── menu_spec.rb │ │ ├── categories_spec.rb │ │ └── comments_spec.rb │ │ ├── categories_spec.rb │ │ └── posts_spec.rb ├── models │ └── refinery │ │ └── blog │ │ ├── comment_spec.rb │ │ └── category_spec.rb ├── lib │ └── refinery │ │ └── blog │ │ └── engine_spec.rb ├── spec_helper.rb ├── controllers │ └── refinery │ │ └── blog │ │ └── admin │ │ └── comments_controller_spec.rb └── helpers │ └── refinery │ └── blog │ └── posts_helper_spec.rb ├── db ├── migrate │ ├── 20110803223523_add_user_id_to_blog_posts.rb │ ├── 20110803223527_add_custom_url_field_to_blog_posts.rb │ ├── 20110803223528_add_custom_teaser_field_to_blog_posts.rb │ ├── 20120531113632_delete_cached_slugs.rb │ ├── 20110803223526_add_cached_slugs.rb │ ├── 20120103055909_add_source_url_to_blog_posts.rb │ ├── 20120223022021_add_access_count_to_posts.rb │ ├── 20120227022021_add_slug_to_posts_and_categories.rb │ ├── 20120601151114_create_category_translations.rb │ ├── 20110803223529_add_primary_key_to_categorizations.rb │ ├── 20120530102901_create_blog_translations.rb │ ├── 20110803223524_acts_as_taggable_on_migration.rb │ └── 20110803223522_create_blog_structure.rb └── seeds.rb ├── script └── rails ├── .travis.yml ├── Rakefile ├── .gitignore ├── Guardfile ├── refinerycms-blog.gemspec ├── config ├── locales │ ├── nb.yml │ ├── zh-CN.yml │ ├── cs.yml │ ├── ja.yml │ ├── ru.yml │ ├── pl.yml │ ├── es.yml │ ├── pt-BR.yml │ ├── nl.yml │ ├── fr.yml │ ├── bg.yml │ ├── de.yml │ ├── it.yml │ └── sv.yml ├── routes.rb └── initializers │ └── url_validator.rb ├── readme.md ├── Gemfile └── changelog.md /app/views/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --colour 2 | -------------------------------------------------------------------------------- /app/helpers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/refinerycms-blog.rb: -------------------------------------------------------------------------------- 1 | require 'refinery/blog' 2 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/comments/approve.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "form" %> 2 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/categories/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "form" %> 2 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "form" %> 2 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/categories/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "form" %> 2 | -------------------------------------------------------------------------------- /tasks/rspec.rake: -------------------------------------------------------------------------------- 1 | require 'rspec/core/rake_task' 2 | 3 | desc "Run specs" 4 | RSpec::Core::RakeTask.new 5 | -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/cog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/cog.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/down.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/down.gif -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/page.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/up.gif -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/rss-feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/rss-feed.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/folder.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/comment.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/comments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/comments.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/page_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/page_add.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/page_copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/page_copy.png -------------------------------------------------------------------------------- /app/views/refinery/shared/admin/_autocomplete.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :stylesheets, stylesheet_link_tag("refinery/blog/ui-lightness/jquery-ui-1.8.13.custom") %> 2 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | ## Why not, let's get this list going, eh? 2 | 3 | * Replace comments with disqus? 4 | * Facebook/twitter login for comments? 5 | * What else? Add your ideas... -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/folder_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/folder_add.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/folder_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/folder_edit.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/comment_cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/comment_cross.png -------------------------------------------------------------------------------- /app/assets/images/refinery/blog/icons/comment_tick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/images/refinery/blog/icons/comment_tick.png -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/_form_part.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.text_area :body, :rows => 20, :class => 'wymeditor widest' -%> 3 |
4 | -------------------------------------------------------------------------------- /spec/factories/blog_categories.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :blog_category, :class => Refinery::Blog::Category do 3 | sequence(:title) { |n| "Shopping #{n}" } 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20110803223523_add_user_id_to_blog_posts.rb: -------------------------------------------------------------------------------- 1 | class AddUserIdToBlogPosts < ActiveRecord::Migration 2 | 3 | def change 4 | add_column Refinery::Blog::Post.table_name, :user_id, :integer 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /db/migrate/20110803223527_add_custom_url_field_to_blog_posts.rb: -------------------------------------------------------------------------------- 1 | class AddCustomUrlFieldToBlogPosts < ActiveRecord::Migration 2 | def change 3 | add_column Refinery::Blog::Post.table_name, :custom_url, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /db/migrate/20110803223528_add_custom_teaser_field_to_blog_posts.rb: -------------------------------------------------------------------------------- 1 | class AddCustomTeaserFieldToBlogPosts < ActiveRecord::Migration 2 | def change 3 | add_column Refinery::Blog::Post.table_name, :custom_teaser, :text 4 | end 5 | end 6 | 7 | -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/progressbar/refinerycms-blog/master/app/assets/stylesheets/refinery/blog/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /db/migrate/20120531113632_delete_cached_slugs.rb: -------------------------------------------------------------------------------- 1 | class DeleteCachedSlugs < ActiveRecord::Migration 2 | def change 3 | remove_column Refinery::Blog::Category.table_name, :cached_slug 4 | remove_column Refinery::Blog::Post.table_name, :cached_slug 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20110803223526_add_cached_slugs.rb: -------------------------------------------------------------------------------- 1 | class AddCachedSlugs < ActiveRecord::Migration 2 | def change 3 | add_column Refinery::Blog::Category.table_name, :cached_slug, :string 4 | add_column Refinery::Blog::Post.table_name, :cached_slug, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/views/refinery/blog/shared/_rss_feed.html.erb: -------------------------------------------------------------------------------- 1 |

<%= t('.title') %>

2 | <%= link_to t('.subscribe'), refinery.blog_rss_feed_path, :id => "rss_feed_subscribe"%> 3 | 4 | <% content_for :meta, auto_discovery_link_tag(:atom, refinery.blog_rss_feed_url, :title => 'RSS Feed') -%> 5 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/_sortable_list.html.erb: -------------------------------------------------------------------------------- 1 | 4 | <%= render "/refinery/admin/sortable_list", 5 | :continue_reordering => (defined?(continue_reordering) ? continue_reordering : true) %> 6 | -------------------------------------------------------------------------------- /db/migrate/20120103055909_add_source_url_to_blog_posts.rb: -------------------------------------------------------------------------------- 1 | class AddSourceUrlToBlogPosts < ActiveRecord::Migration 2 | def change 3 | add_column Refinery::Blog::Post.table_name, :source_url, :string 4 | add_column Refinery::Blog::Post.table_name, :source_url_title, :string 5 | 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20120223022021_add_access_count_to_posts.rb: -------------------------------------------------------------------------------- 1 | class AddAccessCountToPosts < ActiveRecord::Migration 2 | def change 3 | add_column Refinery::Blog::Post.table_name, :access_count, :integer, :default => 0 4 | 5 | add_index Refinery::Blog::Post.table_name, :access_count 6 | 7 | end 8 | end -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/comments/_sortable_list.html.erb: -------------------------------------------------------------------------------- 1 | 4 | <%= render "/refinery/admin/sortable_list", 5 | :continue_reordering => (defined?(continue_reordering) ? continue_reordering : true) %> 6 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | #!/usr/bin/env ruby 3 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 4 | 5 | ENGINE_PATH = File.expand_path('../..', __FILE__) 6 | load File.expand_path('../../spec/dummy/script/rails', __FILE__) 7 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/categories/_sortable_list.html.erb: -------------------------------------------------------------------------------- 1 | 4 | <%= render "/refinery/admin/sortable_list", 5 | :continue_reordering => (defined?(continue_reordering) ? continue_reordering : true) %> 6 | -------------------------------------------------------------------------------- /app/views/refinery/blog/widgets/_blog_archive.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= t('archives', :scope => 'refinery.blog.shared') %>

3 | 10 |
11 | -------------------------------------------------------------------------------- /app/controllers/refinery/blog/admin/categories_controller.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | module Admin 4 | class CategoriesController < ::Refinery::AdminController 5 | 6 | crudify :'refinery/blog/category', 7 | :order => 'title ASC' 8 | 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/refinery/blog/shared/_posts.html.erb: -------------------------------------------------------------------------------- 1 | <% if @posts.many? %> 2 |

<%= t('.other') %>

3 | 10 | <% end %> -------------------------------------------------------------------------------- /app/views/refinery/blog/shared/_tags.html.erb: -------------------------------------------------------------------------------- 1 | <% if @tags.any? %> 2 |

<%= t('.title') %>

3 | 8 | <% end %> -------------------------------------------------------------------------------- /spec/requests/refinery/blog/admin/menu_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "Blog menu entry" do 4 | refinery_login_with :refinery_user 5 | 6 | it "is highlighted when managing the blog" do 7 | visit refinery.admin_root_path 8 | 9 | within("#menu") { click_link "Blog" } 10 | 11 | page.should have_css("a.active", :text => "Blog") 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/controllers/refinery/blog/categories_controller.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class CategoriesController < BlogController 4 | 5 | def show 6 | @category = Refinery::Blog::Category.find(params[:id]) 7 | @posts = @category.posts.live.includes(:comments, :categories).with_globalize.page(params[:page]) 8 | end 9 | 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20120227022021_add_slug_to_posts_and_categories.rb: -------------------------------------------------------------------------------- 1 | class AddSlugToPostsAndCategories < ActiveRecord::Migration 2 | def change 3 | add_column Refinery::Blog::Post.table_name, :slug, :string 4 | add_index Refinery::Blog::Post.table_name, :slug 5 | 6 | add_column Refinery::Blog::Category.table_name, :slug, :string 7 | add_index Refinery::Blog::Category.table_name, :slug 8 | end 9 | end -------------------------------------------------------------------------------- /lib/refinery/blog/version.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class Version 4 | @major = 2 5 | @minor = 1 6 | @tiny = 0 7 | @build = 'dev' 8 | 9 | class << self 10 | attr_reader :major, :minor, :tiny, :build 11 | 12 | def to_s 13 | [@major, @minor, @tiny, @build].compact.join('.') 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/views/refinery/blog/shared/_body_content_right.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :side_body do %> 2 | <%= yield(:side_body_prepend) %> 3 | <%= render "/refinery/blog/shared/rss_feed" %> 4 | <%= render "/refinery/blog/shared/categories" %> 5 | <%= render "/refinery/blog/shared/tags" %> 6 | <%= render "/refinery/blog/shared/posts" %> 7 | <%= blog_archive_widget %> 8 | <%= yield(:side_body_append) %> 9 | <% end %> 10 | -------------------------------------------------------------------------------- /db/migrate/20120601151114_create_category_translations.rb: -------------------------------------------------------------------------------- 1 | class CreateCategoryTranslations < ActiveRecord::Migration 2 | def up 3 | Refinery::Blog::Category.create_translation_table!({ 4 | :title => :string, 5 | :slug => :string 6 | }, { 7 | :migrate_data => true 8 | }) 9 | end 10 | 11 | def down 12 | Refinery::Blog::Category.drop_translation_table! :migrate_data => true 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/views/refinery/blog/shared/_categories.html.erb: -------------------------------------------------------------------------------- 1 | <% if @categories.any? %> 2 |

<%= t('.title') %>

3 | 10 | <% end %> -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | before_script: 2 | - "bundle exec rake refinery:testing:dummy_app > /dev/null" 3 | script: "bundle exec rake spec" 4 | notifications: 5 | email: 6 | - parndt@gmail.com 7 | - ugis.ozolss@gmail.com 8 | - joe@joesak.com 9 | - jamie@enmasse.com 10 | env: 11 | - DB=postgresql 12 | - DB=mysql 13 | matrix: 14 | allow_failures: 15 | - rvm: rbx-19mode 16 | rvm: 17 | - 1.8.7 18 | - 1.9.3 19 | - rbx-19mode 20 | - jruby 21 | -------------------------------------------------------------------------------- /app/models/refinery/categorization.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | class Categorization < ActiveRecord::Base 3 | 4 | self.table_name = 'refinery_blog_categories_blog_posts' 5 | belongs_to :blog_post, :class_name => 'Refinery::Blog::Post', :foreign_key => :blog_post_id 6 | belongs_to :blog_category, :class_name => 'Refinery::Blog::Category', :foreign_key => :blog_category_id 7 | 8 | attr_accessible :blog_category_id, :blog_post_id 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/controllers/refinery/blog/blog_controller.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class BlogController < ::ApplicationController 4 | 5 | include ControllerHelper 6 | 7 | helper :'refinery/blog/posts' 8 | before_filter :find_page, :find_all_blog_categories 9 | 10 | protected 11 | 12 | def find_page 13 | @page = Refinery::Page.find_by_link_url(Refinery::Blog.page_url) 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/models/refinery/blog/comment_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Refinery 4 | module Blog 5 | describe Comment do 6 | context "wiring up" do 7 | let(:comment) { FactoryGirl.create(:blog_comment) } 8 | 9 | it "saves" do 10 | comment.should_not be_nil 11 | end 12 | 13 | it "has a blog post" do 14 | comment.post.should_not be_nil 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/mailers/refinery/blog/comment_mailer.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class CommentMailer < ActionMailer::Base 4 | 5 | def notification(comment, request) 6 | @comment = comment 7 | mail :subject => Blog::Comment::Notification.subject, 8 | :to => Blog::Comment::Notification.recipients, 9 | :from => "\"#{Refinery::Core.site_name}\" " 10 | end 11 | 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20110803223529_add_primary_key_to_categorizations.rb: -------------------------------------------------------------------------------- 1 | class AddPrimaryKeyToCategorizations < ActiveRecord::Migration 2 | def up 3 | unless Refinery::Categorization.column_names.include?("id") 4 | add_column Refinery::Categorization.table_name, :id, :primary_key 5 | end 6 | end 7 | 8 | def down 9 | if Refinery::Categorization.column_names.include?("id") 10 | remove_column Refinery::Categorization.table_name, :id 11 | end 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /db/migrate/20120530102901_create_blog_translations.rb: -------------------------------------------------------------------------------- 1 | class CreateBlogTranslations < ActiveRecord::Migration 2 | def up 3 | Refinery::Blog::Post.create_translation_table!({ 4 | :body => :text, 5 | :custom_teaser => :text, 6 | :custom_url => :string, 7 | :slug => :string, 8 | :title => :string 9 | }, { 10 | :migrate_data => true 11 | }) 12 | end 13 | 14 | def down 15 | Refinery::Blog::Post.drop_translation_table! :migrate_data => true 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/_teaser_part.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.text_area :custom_teaser, :rows => 20, :class => 'wymeditor widest' -%> 3 |

4 | 5 | <%= link_to t('copy_body', :scope => 'refinery.blog.admin.posts.form'), "#", 6 | :id => 'copy_body_link', 7 | :title => t('copy_body_help', :scope => 'refinery.blog.admin.posts.form') %> 8 | 9 |

10 |
11 | 12 | -------------------------------------------------------------------------------- /lib/refinery/blog/configuration.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | include ActiveSupport::Configurable 4 | 5 | config_accessor :validate_source_url, :comments_per_page, :posts_per_page, 6 | :post_teaser_length, :share_this_key, :page_url 7 | 8 | self.validate_source_url = false 9 | self.comments_per_page = 10 10 | self.posts_per_page = 10 11 | self.post_teaser_length = 250 12 | self.share_this_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 13 | self.page_url = "/blog" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/factories/blog_posts.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :blog_post, :class => Refinery::Blog::Post do 3 | sequence(:title) { |n| "Top #{n} Shopping Centers in Chicago" } 4 | body "These are the top ten shopping centers in Chicago. You're going to read a long blog post about them. Come to peace with it." 5 | draft false 6 | tag_list "chicago, shopping, fun times" 7 | published_at Time.now 8 | author { Factory(:refinery_user) } 9 | 10 | factory :blog_post_draft do 11 | draft true 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/index.rss.builder: -------------------------------------------------------------------------------- 1 | xml.instruct! :xml, :version => "1.0" 2 | xml.rss :version => "2.0" do 3 | xml.channel do 4 | xml.title Refinery::Core.site_name 5 | xml.description Refinery::Core.site_name + " Blog Posts" 6 | xml.link refinery.blog_root_url 7 | 8 | @posts.each do |post| 9 | xml.item do 10 | xml.title post.title 11 | xml.description post.body 12 | xml.pubDate post.published_at.to_s(:rfc822) 13 | xml.link refinery.blog_post_url(post) 14 | end 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/_comment.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= image_tag avatar_url(comment.email), :alt => comment.name, :class => 'avatar' %> 3 | <%= simple_format auto_link(comment.message.to_s) %> 4 |
5 |

6 | <%= t('by', :scope => 'refinery.blog.posts.comments', :who => comment.name) %>, 7 | <%= t('time_ago', :scope => 'refinery.blog.posts.comments', :time => time_ago_in_words(comment.created_at)) %> 8 |

9 |
10 |
11 | -------------------------------------------------------------------------------- /lib/refinery/blog/tabs.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class Tab 4 | attr_accessor :name, :partial 5 | 6 | def self.register(&block) 7 | tab = self.new 8 | 9 | yield tab 10 | 11 | raise "A tab MUST have a name!: #{tab.inspect}" if tab.name.blank? 12 | raise "A tab MUST have a partial!: #{tab.inspect}" if tab.partial.blank? 13 | end 14 | 15 | protected 16 | 17 | def initialize 18 | ::Refinery::Blog.tabs << self # add me to the collection of registered page tabs 19 | end 20 | end 21 | end 22 | end -------------------------------------------------------------------------------- /spec/factories/blog_comments.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :blog_comment, :class => Refinery::Blog::Comment do 3 | name "Joe Commenter" 4 | sequence(:email) { |n| "person#{n}@example.com" } 5 | body "Which one is the best for picking up new shoes?" 6 | association :post, :factory => :blog_post 7 | 8 | trait :approved do 9 | state 'approved' 10 | end 11 | 12 | trait :rejected do 13 | state 'rejected' 14 | end 15 | 16 | factory :approved_comment, :traits => [:approved] 17 | factory :rejected_comment, :traits => [:rejected] 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/generators/refinery/blog/templates/config/initializers/refinery/blog.rb.erb: -------------------------------------------------------------------------------- 1 | Refinery::Blog.configure do |config| 2 | # config.validate_source_url = <%= Refinery::Blog.validate_source_url.inspect %> 3 | 4 | # config.comments_per_page = <%= Refinery::Blog.comments_per_page.inspect %> 5 | 6 | # config.posts_per_page = <%= Refinery::Blog.posts_per_page.inspect %> 7 | 8 | # config.post_teaser_length = <%= Refinery::Blog.post_teaser_length.inspect %> 9 | 10 | # config.share_this_key = <%= Refinery::Blog.share_this_key.inspect %> 11 | 12 | # config.page_url = <%= Refinery::Blog.page_url.inspect %> 13 | end 14 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | begin 3 | require 'bundler/setup' 4 | rescue LoadError 5 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks' 6 | end 7 | 8 | ENGINE_PATH = File.dirname(__FILE__) 9 | APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__) 10 | 11 | if File.exists?(APP_RAKEFILE) 12 | load 'rails/tasks/engine.rake' 13 | end 14 | 15 | require "refinerycms-testing" 16 | Refinery::Testing::Railtie.load_tasks 17 | Refinery::Testing::Railtie.load_dummy_tasks(ENGINE_PATH) 18 | 19 | load File.expand_path('../tasks/rspec.rake', __FILE__) 20 | 21 | task :default => :spec 22 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/shared/_locale_picker.html.erb: -------------------------------------------------------------------------------- 1 | 2 | <% if (locales ||= Refinery::I18n.frontend_locales).present? and locales.many? %> 3 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | *.gem 3 | *.DS_Store 4 | 5 | # Documentation 6 | doc/api 7 | doc/app 8 | doc/* 9 | .yardoc 10 | .yardopts 11 | 12 | # Refinery Specific 13 | *.tmproj 14 | *.autobackupbyrefinery.* 15 | /refinerycms-blog*.gem 16 | .autotest 17 | spec/dummy 18 | 19 | # Mac 20 | .DS_Store 21 | 22 | # NetBeans 23 | nbproject 24 | 25 | # Eclipse 26 | .project 27 | 28 | # Redcar 29 | .redcar 30 | 31 | # Rubinius 32 | *.rbc 33 | 34 | # Vim 35 | *.swp 36 | *.swo 37 | 38 | # RubyMine 39 | .idea 40 | 41 | # Backup 42 | *~ 43 | 44 | # Capybara Bug 45 | capybara-*html 46 | 47 | # rvm 48 | .rvmrc 49 | 50 | #rbenv 51 | .rbenv-version 52 | 53 | Gemfile.lock 54 | .rbx -------------------------------------------------------------------------------- /app/views/refinery/blog/categories/show.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :body_content_title, @category.title %> 2 | 3 | <% content_for :body do %> 4 | <% if @posts.any? %> 5 |
6 | <%= render :partial => "/refinery/blog/shared/post", :collection => @posts %> 7 | <%= will_paginate @posts %> 8 |
9 | <% else %> 10 |

11 | <%= t('.no_posts') %> 12 |

13 | <% end %> 14 | <% end %> 15 | 16 | <% content_for :side_body do %> 17 | <%= render "/refinery/blog/shared/categories" %> 18 | <% end %> 19 | 20 | <%= render "/refinery/content_page" %> 21 | <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/frontend') %> 22 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | Refinery::User.all.each do |user| 2 | if user.plugins.where(:name => 'refinerycms_blog').blank? 3 | user.plugins.create(:name => "refinerycms_blog", 4 | :position => (user.plugins.maximum(:position) || -1) +1) 5 | end 6 | end if defined?(Refinery::User) 7 | 8 | if defined?(Refinery::Page) and !Refinery::Page.exists?(:link_url => '/blog') 9 | page = Refinery::Page.create( 10 | :title => "Blog", 11 | :link_url => "/blog", 12 | :deletable => false, 13 | :menu_match => "^/blogs?(\/|\/.+?|)$" 14 | ) 15 | 16 | Refinery::Pages.default_parts.each do |default_page_part| 17 | page.parts.create(:title => default_page_part, :body => nil) 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/_nav.html.erb: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/settings/notification_recipients.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_tag refinery.notification_recipients_blog_admin_settings_path do %> 2 | 3 |
4 | 5 | <%= label_tag :recipients, t('.value') %> 6 | 7 | <%= text_field_tag :recipients, @recipients, :class => "larger widest" %> 8 |
9 | 10 |

11 | <%= t('.hint') %> 12 |

13 |

14 | <%= t('.example') %> 15 |

16 | 17 | <%= render "/refinery/admin/form_actions", 18 | :f => nil, 19 | :continue_editing => false, 20 | :cancel_url => refinery.blog_admin_posts_url, 21 | :hide_delete => true %> 22 | <% end %> 23 | -------------------------------------------------------------------------------- /app/views/refinery/blog/comment_mailer/notification.html.erb: -------------------------------------------------------------------------------- 1 | <%=raw t('.greeting') %>, 2 | 3 | <%=raw t('.you_recieved_new_comment') %> 4 | 5 | <%=raw t('.comment_starts') %> 6 | 7 | <%=raw t('.from') %>: <%= @comment.name %> 8 | <%=raw t('.email') %>: <%= @comment.email %> 9 | <%=raw t('.message') %>: 10 | <%=simple_format strip_tags(@comment.body) %> 11 | 12 | <%=raw t('.comment_ends') %> 13 | 14 | <%=raw link_to t('.approve'), refinery.approve_blog_admin_comment_url(@comment) -%> 15 | <%=raw t('.or') -%> 16 | <%=raw link_to t('.reject'), refinery.reject_blog_admin_comment_url(@comment) -%> 17 | <%=raw t('.this_comment') %> 18 | 19 | <%=raw t('.closing_line') %>, 20 | <%=raw Refinery::Core.site_name %> 21 | 22 | <%=raw t('.ps') %> 23 | -------------------------------------------------------------------------------- /spec/lib/refinery/blog/engine_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Refinery 4 | module Blog 5 | describe Engine do 6 | describe "plugin activity" do 7 | let(:activity) do 8 | Refinery::Plugins.registered.find_by_name("refinerycms_blog").activity.first 9 | end 10 | 11 | it "sets the correct path for activity entries" do 12 | activity.url.should eq("refinery.edit_blog_admin_post_path") 13 | end 14 | end 15 | 16 | describe ".load_seed" do 17 | it "is idempotent" do 18 | Engine.load_seed 19 | Engine.load_seed 20 | 21 | Refinery::Page.where(:link_url => '/blog').count.should eq(1) 22 | end 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/archive.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :title, "#{t('.blog_archive_for', :date => @archive_date.strftime('%B %Y'))}" %> 2 | 3 | <% content_for :body do %> 4 |

<%= t('.blog_archive_for', :date => @archive_date.strftime('%B %Y')) %>

5 | <% if @posts.any? %> 6 |
7 | <%= render :partial => "/refinery/blog/shared/post", :collection => @posts %> 8 |
9 | <% else %> 10 |

<%= t('.no_blog_articles_posted', :date => @archive_date.strftime('%B %Y')) %>

11 | <% end %> 12 | <% end %> 13 | 14 | <%= render '/refinery/blog/shared/body_content_right' %> 15 | 16 | <%= render "/refinery/content_page" %> 17 | <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/frontend') %> 18 | -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/tagged.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :title, "#{t('.posts_tagged')} “#{h(@tag_name.titleize)}”".html_safe %> 2 | 3 | <% content_for :body_content_title, "#{t('.posts_tagged')} “#{h(@tag_name.titleize)}”".html_safe -%> 4 | 5 | <% content_for :body do %> 6 | <% if @posts.any? %> 7 |
8 | <%= render :partial => "/refinery/blog/shared/post", :collection => @posts %> 9 | <%= will_paginate @posts %> 10 |
11 | <% else %> 12 |

<%= t('.no_blog_articles_yet') %>

13 | <% end %> 14 | <% end %> 15 | 16 | <%= render '/refinery/blog/shared/body_content_right' %> 17 | 18 | <%= render "/refinery/content_page" %> 19 | <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/frontend') %> 20 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/categories/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for [refinery, :blog_admin, @category] do |f| -%> 2 | <%= render "/refinery/admin/error_messages", 3 | :object => f.object, 4 | :include_object_name => true %> 5 | 6 | <%= render "/refinery/blog/admin/shared/locale_picker", 7 | :current_locale => Thread.current[:globalize_locale] if Refinery.i18n_enabled? %> 8 | 9 |
10 | <%= f.label :title -%> 11 | <%= f.text_field :title, :class => 'larger widest' -%> 12 |
13 | 14 | <%= render "/refinery/admin/form_actions", 15 | :f => f, 16 | :continue_editing => false, 17 | :delete_title => t('delete', :scope => 'refinery.blog.admin.categories.category') %> 18 | <% end %> 19 | -------------------------------------------------------------------------------- /db/migrate/20110803223524_acts_as_taggable_on_migration.rb: -------------------------------------------------------------------------------- 1 | class ActsAsTaggableOnMigration < ActiveRecord::Migration 2 | def up 3 | create_table :tags do |t| 4 | t.string :name 5 | end 6 | 7 | create_table :taggings do |t| 8 | t.references :tag 9 | 10 | # You should make sure that the column created is 11 | # long enough to store the required class names. 12 | t.references :taggable, :polymorphic => true 13 | t.references :tagger, :polymorphic => true 14 | 15 | t.string :context 16 | 17 | t.datetime :created_at 18 | end 19 | 20 | add_index :taggings, :tag_id 21 | add_index :taggings, [:taggable_id, :taggable_type, :context] 22 | end 23 | 24 | def down 25 | drop_table :taggings 26 | drop_table :tags 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/refinery/blog/engine.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class Engine < Rails::Engine 4 | include Refinery::Engine 5 | 6 | isolate_namespace Refinery::Blog 7 | 8 | initializer "register refinerycms_blog plugin" do 9 | Refinery::Plugin.register do |plugin| 10 | plugin.pathname = root 11 | plugin.name = "refinerycms_blog" 12 | plugin.url = proc { Refinery::Core::Engine.routes.url_helpers.blog_admin_posts_path } 13 | plugin.menu_match = /refinery\/blog\/?(posts|comments|categories)?/ 14 | plugin.activity = { :class_name => :'refinery/blog/post' } 15 | end 16 | end 17 | 18 | config.after_initialize do 19 | Refinery.register_engine(Refinery::Blog) 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /app/assets/javascripts/refinery/blog/frontend.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('#show_blog_post').height($('#show_blog_post').height()); 3 | 4 | $('#next_prev_article a:not(".home")').live('click', function(){ 5 | url = this.href + ".js"; 6 | $('#show_blog_post > *').fadeOut(); 7 | $.ajax({ 8 | url: url, 9 | success: function(data) { 10 | $('#show_blog_post').html(data); 11 | new_height = 0; 12 | $('#show_blog_post > *').each(function(){ 13 | new_height += $(this).height() 14 | }); 15 | $('#show_blog_post').animate({ 16 | height: new_height 17 | }); 18 | } 19 | }); 20 | $('html, body').animate({ 21 | scrollTop: $('body').offset().top 22 | }, 2000); 23 | return false; 24 | }) 25 | }) -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/show.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :body do %> 2 |
3 | <%= render 'post' %> 4 |
5 | 6 | <%= render 'comments' %> 7 | <% end %> 8 | 9 | <%= render '/refinery/blog/shared/body_content_right' %> 10 | 11 | <%= render "/refinery/content_page", :remove_automatic_sections => true %> 12 | 13 | <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/frontend') %> 14 | <% content_for :javascripts do %> 15 | <%# enable AJAX'd post nav at your own risk until html5 history API implemented. %> 16 | <%#= javascript_include_tag('refinery/blog/frontend') %> 17 | 18 | 19 | <% end if Refinery::Blog::Post::ShareThis.enabled? %> 20 | -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/index.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :body do %> 2 | <%= raw @page.content_for(Refinery::Pages.default_parts.first.to_sym) if Refinery::Pages.default_parts.any? %> 3 | 4 | <% if @posts.any? %> 5 |
6 | <%= render :partial => "/refinery/blog/shared/post", :collection => @posts %> 7 | <%= will_paginate @posts %> 8 |
9 | <% else %> 10 |

<%= t('.no_blog_articles_yet') %>

11 | <% end %> 12 | <% end %> 13 | 14 | <% content_for :side_body_prepend do -%> 15 | <%= raw @page.content_for(Refinery::Pages.default_parts.second.to_sym) %> 16 | <% end if Refinery::Pages.default_parts.many? -%> 17 | <%= render '/refinery/blog/shared/body_content_right' %> 18 | 19 | <%= render "/refinery/content_page" %> 20 | <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/frontend') %> 21 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/uncategorized.html.erb: -------------------------------------------------------------------------------- 1 | <%= render '/refinery/blog/admin/submenu' %> 2 |
3 | <% if searching? %> 4 |

<%= t('results_for', :scope => 'refinery.admin.search', 5 | :query => params[:search]) %>

6 | <% if @posts.any? %> 7 | <%= render :partial => "blog_posts", 8 | :collection => @posts %> 9 | <% else %> 10 |

<%= t('no_results', :scope => 'refinery.admin.search') %>

11 | <% end %> 12 | <% else %> 13 | <% if @posts.any? %> 14 | <%= will_paginate @posts %> 15 | 16 | <%= render "sortable_list" %> 17 | 18 | <%= will_paginate @posts %> 19 | <% else %> 20 |

21 | 22 | <%= t('.no_items_yet') %> 23 | 24 |

25 | <% end %> 26 | <% end %> 27 |
28 | -------------------------------------------------------------------------------- /lib/generators/refinery/blog/blog_generator.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | class BlogGenerator < Rails::Generators::Base 3 | 4 | source_root File.expand_path("../templates", __FILE__) 5 | 6 | def generate_blog_initializer 7 | template "config/initializers/refinery/blog.rb.erb", File.join(destination_root, "config", "initializers", "refinery", "blog.rb") 8 | end 9 | 10 | def rake_db 11 | rake("refinery_blog:install:migrations") 12 | rake("refinery_settings:install:migrations") 13 | end 14 | 15 | def append_load_seed_data 16 | create_file 'db/seeds.rb' unless File.exists?(File.join(destination_root, 'db', 'seeds.rb')) 17 | append_file 'db/seeds.rb', :verbose => true do 18 | <<-EOH 19 | 20 | # Added by Refinery CMS Blog engine 21 | Refinery::Blog::Engine.load_seed 22 | EOH 23 | end 24 | end 25 | 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= render '/refinery/blog/admin/submenu' %> 2 |
3 | <% if searching? %> 4 |

<%= t('results_for', :scope => 'refinery.admin.search', :query => params[:search]) %>

5 | <% if @posts.any? %> 6 | 9 | <% else %> 10 |

<%= t('no_results', :scope => 'refinery.admin.search') %>

11 | <% end %> 12 | <% else %> 13 | <% if @posts.any? %> 14 | <%= will_paginate @posts %> 15 | 16 | <%= render "sortable_list" %> 17 | 18 | <%= will_paginate @posts %> 19 | <% else %> 20 |

21 | 22 | <%= t('.no_items_yet', :create => t('new', :scope => 'refinery.blog.admin.submenu.posts')) %> 23 | 24 |

25 | <% end %> 26 | <% end %> 27 |
28 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/categories/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= render '/refinery/blog/admin/submenu' %> 2 |
3 | <% if searching? %> 4 |

<%= t('results_for', :scope => 'refinery.admin.search', 5 | :query => params[:search]) %>

6 | <% if @categories.any? %> 7 | <%= render :partial => "blog_categories", 8 | :collection => @categories %> 9 | <% else %> 10 |

<%= t('no_results', :scope => 'refinery.admin.search') %>

11 | <% end %> 12 | <% else %> 13 | <% if @categories.any? %> 14 | <%= will_paginate @categories %> 15 | 16 | <%= render "sortable_list" %> 17 | 18 | <%= will_paginate @categories %> 19 | <% else %> 20 |

21 | 22 | <%= t('.no_items_yet', :create => t('new', :scope => 'refinery.blog.admin.submenu.categories')) %> 23 | 24 |

25 | <% end %> 26 | <% end %> 27 |
28 | -------------------------------------------------------------------------------- /lib/refinery/blog.rb: -------------------------------------------------------------------------------- 1 | require 'refinerycms-core' 2 | require 'refinerycms-settings' 3 | require 'filters_spam' 4 | require 'rails_autolink' 5 | require 'acts_as_indexed' 6 | 7 | module Refinery 8 | autoload :BlogGenerator, 'generators/refinery/blog/blog_generator' 9 | 10 | module Blog 11 | require 'refinery/blog/engine' 12 | require 'refinery/blog/configuration' 13 | 14 | autoload :Version, 'refinery/blog/version' 15 | autoload :Tab, 'refinery/blog/tabs' 16 | 17 | class << self 18 | attr_writer :root 19 | attr_writer :tabs 20 | 21 | def root 22 | @root ||= Pathname.new(File.expand_path('../../../', __FILE__)) 23 | end 24 | 25 | def tabs 26 | @tabs ||= [] 27 | end 28 | 29 | def version 30 | ::Refinery::Blog::Version.to_s 31 | end 32 | 33 | def factory_paths 34 | @factory_paths ||= [ root.join("spec/factories").to_s ] 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /spec/requests/refinery/blog/categories_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Refinery 4 | describe "BlogCategories" do 5 | refinery_login_with :refinery_user 6 | 7 | context "has one category and post" do 8 | before(:each) do 9 | post = Globalize.with_locale(:en) do 10 | FactoryGirl.create(:blog_post, :title => "Refinery CMS blog post") 11 | end 12 | @category = Globalize.with_locale(:en) do 13 | FactoryGirl.create(:blog_category, :title => "Video Games") 14 | end 15 | post.categories << @category 16 | post.save! 17 | end 18 | 19 | describe "show categories blog posts" do 20 | it "should displays categories blog posts" do 21 | visit refinery.blog_category_path(@category) 22 | page.should have_content("Refinery CMS blog post") 23 | page.should have_content("Video Games") 24 | end 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/comments/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= render '/refinery/blog/admin/submenu' %> 2 |
3 | <% if searching? %> 4 |

<%= t('results_for', :scope => 'shared.admin.search', :query => params[:search]) %>

5 | <% if @comments.any? %> 6 | <%= will_paginate @comments %> 7 | 8 | 12 | 13 | <%= will_paginate @comments %> 14 | <% else %> 15 |

<%= t('search_no_results', :scope => 'admin') %>

16 | <% end %> 17 | <% else %> 18 | <% if @comments.any? %> 19 | <%= will_paginate @comments %> 20 | 21 | <%= render "sortable_list" %> 22 | 23 | <%= will_paginate @comments %> 24 | <% else %> 25 |

26 | <%= t('.no_items_yet', :type => action_name.gsub('index', 'new').downcase) %> 27 |

28 | <% end %> 29 | <% end %> 30 |
31 | -------------------------------------------------------------------------------- /app/helpers/refinery/blog/controller_helper.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | module ControllerHelper 4 | 5 | protected 6 | 7 | def find_blog_post 8 | unless (@post = Refinery::Blog::Post.with_globalize.find(params[:id])).try(:live?) 9 | if refinery_user? and current_refinery_user.authorized_plugins.include?("refinerycms_blog") 10 | @post = Refinery::Blog::Post.find(params[:id]) 11 | else 12 | error_404 13 | end 14 | end 15 | end 16 | 17 | def find_all_blog_posts 18 | @posts = Refinery::Blog::Post.live.includes(:comments, :categories).with_globalize.page(params[:page]) 19 | end 20 | 21 | def find_tags 22 | @tags = Refinery::Blog::Post.tag_counts_on(:tags) 23 | end 24 | def find_all_blog_categories 25 | @categories = Refinery::Blog::Category.translated 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | guard 'spork', :wait => 60, :cucumber => false, :rspec_env => { 'RAILS_ENV' => 'test' } do 2 | watch('config/application.rb') 3 | watch('config/environment.rb') 4 | watch(%r{^config/environments/.+\.rb$}) 5 | watch(%r{^config/initializers/.+\.rb$}) 6 | watch('spec/spec_helper.rb') 7 | end 8 | 9 | guard 'rspec', :version => 2, :cli => "--color --drb" do 10 | watch(%r{^spec/.+_spec\.rb$}) 11 | watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } 12 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } 13 | watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/controllers/#{m[1]}_#{m[2]}_spec.rb", "spec/requests/#{m[1]}_spec.rb"] } 14 | watch(%r{^spec/support/(.+)\.rb$}) { "spec" } 15 | watch('spec/spec_helper.rb') { "spec" } 16 | # Capybara request specs 17 | watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" } 18 | end 19 | -------------------------------------------------------------------------------- /app/models/refinery/blog/category.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class Category < ActiveRecord::Base 4 | 5 | translates :title, :slug 6 | 7 | extend FriendlyId 8 | friendly_id :title, :use => [:slugged, :globalize] 9 | 10 | has_many :categorizations, :dependent => :destroy, :foreign_key => :blog_category_id 11 | has_many :posts, :through => :categorizations, :source => :blog_post 12 | 13 | acts_as_indexed :fields => [:title] 14 | 15 | validates :title, :presence => true, :uniqueness => true 16 | 17 | attr_accessible :title 18 | attr_accessor :locale 19 | 20 | class Translation 21 | attr_accessible :locale 22 | end 23 | 24 | def self.translated 25 | with_translations(::Globalize.locale) 26 | end 27 | 28 | def post_count 29 | posts.live.with_globalize.count 30 | end 31 | 32 | # how many items to show per page 33 | self.per_page = Refinery::Blog.posts_per_page 34 | 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/comments/_comment.html.erb: -------------------------------------------------------------------------------- 1 |
  • "> 2 | 3 | <%= comment.name %> 4 | - <%= truncate(comment.message, :length => 75) %> 5 | 6 | 7 | <%= link_to refinery_icon_tag("application_go.png"), 8 | refinery.blog_post_path(comment.post, :anchor => "comment-#{comment.to_param}"), 9 | :title => t('.view_live_html'), 10 | :target => "_blank" unless comment.unmoderated? %> 11 | <%= link_to refinery_icon_tag('zoom.png'), refinery.blog_admin_comment_path(comment), 12 | :title => t('.read') %> 13 | <%= link_to refinery_icon_tag("cross.png"), 14 | refinery.reject_blog_admin_comment_path(comment), 15 | :method => :post, 16 | :title => t('.reject') unless comment.rejected? %> 17 | <%= link_to refinery_icon_tag("tick.png"), 18 | refinery.approve_blog_admin_comment_path(comment), 19 | :method => :post, 20 | :title => t('.approve') unless comment.approved? %> 21 | 22 |
  • 23 | -------------------------------------------------------------------------------- /refinerycms-blog.gemspec: -------------------------------------------------------------------------------- 1 | # Encoding: UTF-8 2 | $:.push File.expand_path('../lib', __FILE__) 3 | require 'refinery/blog/version' 4 | 5 | version = Refinery::Blog::Version.to_s 6 | 7 | Gem::Specification.new do |s| 8 | s.name = %q{refinerycms-blog} 9 | s.version = version 10 | s.description = %q{A really straightforward open source Ruby on Rails blog engine designed for integration with Refinery CMS.} 11 | s.summary = %q{Ruby on Rails blogging engine for Refinery CMS.} 12 | s.email = %q{info@refinerycms.com} 13 | s.homepage = %q{http://refinerycms.com/blog} 14 | s.authors = ['Resolve Digital', 'Neoteric Design'] 15 | s.require_paths = %w(lib) 16 | 17 | s.files = `git ls-files`.split("\n") 18 | s.test_files = `git ls-files -- spec/*`.split("\n") 19 | 20 | # Runtime dependencies 21 | s.add_dependency 'refinerycms-core', '~> 2.1.0.dev' 22 | s.add_dependency 'refinerycms-settings', '~> 2.1.0.dev' 23 | s.add_dependency 'filters_spam', '~> 0.2' 24 | s.add_dependency 'acts-as-taggable-on' 25 | s.add_dependency 'seo_meta', '~> 1.3.0' 26 | s.add_dependency 'rails_autolink', '~> 1.0.7' 27 | end 28 | -------------------------------------------------------------------------------- /config/locales/nb.yml: -------------------------------------------------------------------------------- 1 | nb: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | posts: 9 | form: 10 | seo_override_title: Nettleser tittel 11 | seo_override_title_help: Skriv inn en tittel på 5-10 ord som oppsummerer innholdet på siden. 12 | meta_keywords_title: Meta stikkord 13 | meta_keywords_help: Skriv inn 5-10 stikkord som relaterer til denne siden. Separer stikkordene med komma. 14 | meta_description_title: Meta beskrivelse 15 | meta_description_help: Skriv en kort beskrivelse på to eller tre setninger som forteller hva denne siden inneholder. 16 | index: 17 | no_items_yet: 'Det er ingen Blog Posts enda. Klikk på "Lag en ny Blog Posts" for å legge til din første blog posts.' 18 | post: 19 | view_live: 'Vis hvordan denne blog post ser ut offentlig
    (åpner i et nytt vindu)' 20 | edit: Rediger denne blog post 21 | delete: Fjern denne blog post permanent 22 | submenu: 23 | comments: 24 | new: ny 25 | posts: 26 | new: Lag en ny post 27 | settings: 28 | update_notified: Oppdater hvem som blir informert 29 | blog_posts: 30 | show: 31 | other: Andre Blog Posts 32 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/categories/_category.html.erb: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | <%= category.title.presence || category.translations.detect {|t| t.title.present?}.title %> 4 | 5 | <% category.translations.each do |translation| %> 6 | <% if translation.title.present? %> 7 | <%= link_to refinery_icon_tag("flags/#{translation.locale}.png", :size => '16x11'), 8 | refinery.edit_blog_admin_category_path(category, :switch_locale => translation.locale), 9 | :class => 'locale' %> 10 | <% end %> 11 | <% end %> 12 | 13 | 14 | 15 | <%= link_to refinery_icon_tag("application_edit.png"), 16 | refinery.edit_blog_admin_category_path(category, :dialog => true, :height => 325), 17 | :title => t('.edit') %> 18 | <%= link_to refinery_icon_tag("delete.png"), refinery.blog_admin_category_path(category), 19 | :class => "cancel confirm-delete", 20 | :title => t('.delete'), 21 | :method => :delete, 22 | :data => { 23 | :confirm => t('message', :scope => 'refinery.admin.delete', :title => category.title) 24 | } %> 25 | 26 |
  • 27 | -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/_comments.html.erb: -------------------------------------------------------------------------------- 1 | 38 | -------------------------------------------------------------------------------- /app/controllers/refinery/blog/admin/comments_controller.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | module Admin 4 | class CommentsController < ::Refinery::AdminController 5 | 6 | crudify :'refinery/blog/comment', 7 | :title_attribute => :name, 8 | :order => 'published_at DESC' 9 | 10 | def index 11 | @comments = Refinery::Blog::Comment.unmoderated.page(params[:page]) 12 | 13 | render :index 14 | end 15 | 16 | def approved 17 | @comments = Refinery::Blog::Comment.approved.page(params[:page]) 18 | 19 | render :index 20 | end 21 | 22 | def approve 23 | @comment = Refinery::Blog::Comment.find(params[:id]) 24 | @comment.approve! 25 | flash[:notice] = t('approved', :scope => 'refinery.blog.admin.comments', :author => @comment.name) 26 | 27 | redirect_to refinery.blog_admin_comments_path 28 | end 29 | 30 | def rejected 31 | @comments = Refinery::Blog::Comment.rejected.page(params[:page]) 32 | 33 | render :index 34 | end 35 | 36 | def reject 37 | @comment = Refinery::Blog::Comment.find(params[:id]) 38 | @comment.reject! 39 | flash[:notice] = t('rejected', :scope => 'refinery.blog.admin.comments', :author => @comment.name) 40 | 41 | redirect_to refinery.blog_admin_comments_path 42 | end 43 | 44 | end 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Refinery::Core::Engine.routes.draw do 2 | namespace :blog, :path => Refinery::Blog.page_url do 3 | root :to => "posts#index" 4 | resources :posts, :only => [:show] 5 | 6 | match 'feed.rss', :to => 'posts#index', :as => 'rss_feed', :defaults => {:format => "rss"} 7 | match 'categories/:id', :to => 'categories#show', :as => 'category' 8 | match ':id/comments', :to => 'posts#comment', :as => 'comments' 9 | get 'archive/:year(/:month)', :to => 'posts#archive', :as => 'archive_posts' 10 | get 'tagged/:tag_id(/:tag_name)' => 'posts#tagged', :as => 'tagged_posts' 11 | end 12 | 13 | namespace :blog, :path => '' do 14 | namespace :admin, :path => 'refinery' do 15 | scope :path => Refinery::Blog.page_url do 16 | root :to => "posts#index" 17 | 18 | resources :posts do 19 | collection do 20 | get :uncategorized 21 | get :tags 22 | end 23 | end 24 | 25 | resources :categories 26 | 27 | resources :comments do 28 | collection do 29 | get :approved 30 | get :rejected 31 | end 32 | member do 33 | post :approve 34 | post :reject 35 | end 36 | end 37 | 38 | resources :settings do 39 | collection do 40 | get :notification_recipients 41 | post :notification_recipients 42 | 43 | get :moderation 44 | get :comments 45 | get :teasers 46 | end 47 | end 48 | end 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /db/migrate/20110803223522_create_blog_structure.rb: -------------------------------------------------------------------------------- 1 | class CreateBlogStructure < ActiveRecord::Migration 2 | 3 | def up 4 | create_table Refinery::Blog::Post.table_name, :id => true do |t| 5 | t.string :title 6 | t.text :body 7 | t.boolean :draft 8 | t.datetime :published_at 9 | t.timestamps 10 | end 11 | 12 | add_index Refinery::Blog::Post.table_name, :id 13 | 14 | create_table Refinery::Blog::Comment.table_name, :id => true do |t| 15 | t.integer :blog_post_id 16 | t.boolean :spam 17 | t.string :name 18 | t.string :email 19 | t.text :body 20 | t.string :state 21 | t.timestamps 22 | end 23 | 24 | add_index Refinery::Blog::Comment.table_name, :id 25 | 26 | create_table Refinery::Blog::Category.table_name, :id => true do |t| 27 | t.string :title 28 | t.timestamps 29 | end 30 | 31 | add_index Refinery::Blog::Category.table_name, :id 32 | 33 | create_table Refinery::Categorization.table_name, :id => true do |t| 34 | t.integer :blog_category_id 35 | t.integer :blog_post_id 36 | end 37 | 38 | add_index Refinery::Categorization.table_name, [:blog_category_id, :blog_post_id], :name => 'index_blog_categories_blog_posts_on_bc_and_bp' 39 | end 40 | 41 | def down 42 | Refinery::UserPlugin.destroy_all({:name => "refinerycms_blog"}) 43 | 44 | Refinery::Page.delete_all({:link_url => "/blog"}) 45 | 46 | drop_table Refinery::Blog::Post.table_name 47 | drop_table Refinery::Blog::Comment.table_name 48 | drop_table Refinery::Blog::Category.table_name 49 | drop_table Refinery::Categorization.table_name 50 | end 51 | 52 | end 53 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/_post.html.erb: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | <%= post.title.presence || post.translations.detect {|t| t.title.present?}.title %> 4 | 5 | <% post.translations.each do |translation| %> 6 | <% if translation.title.present? %> 7 | <%= link_to refinery_icon_tag("flags/#{translation.locale}.png", :size => '16x11'), 8 | refinery.edit_blog_admin_post_path(post, :switch_locale => translation.locale), 9 | :class => 'locale' %> 10 | <% end %> 11 | <% end %> 12 | 13 | <%= post.published_at.try(:strftime, '%b %d, %Y') || 'draft' %> 14 | <%= " by #{post.author.username}" if post.author.present? %> 15 | <% if post.draft? %> 16 | <%= t('refinery.blog.admin.posts.post.draft') %> 17 | <% else %> 18 | <%= post.published_at.strftime('%b %d, %Y') %> 19 | <% end %> 20 | 21 | 22 | 23 | <%= link_to refinery_icon_tag("application_go.png"), refinery.blog_post_path(post), 24 | :title => t('.view_live_html'), 25 | :target => "_blank" %> 26 | <%= link_to refinery_icon_tag("application_edit.png"), refinery.edit_blog_admin_post_path(post), 27 | :title => t('.edit') %> 28 | <%= link_to refinery_icon_tag("delete.png"), refinery.blog_admin_post_path(post), 29 | :class => "cancel confirm-delete", 30 | :title => t('.delete'), 31 | :method => :delete, 32 | :data => { 33 | :confirm => t('message', :scope => 'refinery.admin.delete', :title => post.title) 34 | } %> 35 | 36 |
  • 37 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | def setup_environment 4 | # Configure Rails Environment 5 | ENV["RAILS_ENV"] ||= 'test' 6 | 7 | require File.expand_path("../dummy/config/environment", __FILE__) 8 | 9 | require 'rspec/rails' 10 | require 'capybara/rspec' 11 | require 'factory_girl_rails' 12 | 13 | Rails.backtrace_cleaner.remove_silencers! 14 | 15 | RSpec.configure do |config| 16 | config.mock_with :rspec 17 | config.treat_symbols_as_metadata_keys_with_true_values = true 18 | config.filter_run :focus => true 19 | config.run_all_when_everything_filtered = true 20 | end 21 | 22 | # set javascript driver for capybara 23 | Capybara.javascript_driver = :selenium 24 | end 25 | 26 | def each_run 27 | ActiveSupport::Dependencies.clear 28 | 29 | FactoryGirl.reload 30 | 31 | # Requires supporting files with custom matchers and macros, etc, 32 | # in ./support/ and its subdirectories including factories. 33 | ([Rails.root.to_s] | ::Refinery::Plugins.registered.pathnames).map{|p| 34 | Dir[File.join(p, 'spec', 'support', '**', '*.rb').to_s] 35 | }.flatten.sort.each do |support_file| 36 | require support_file 37 | end 38 | end 39 | 40 | # If spork is available in the Gemfile it'll be used but we don't force it. 41 | unless (begin; require 'spork'; rescue LoadError; nil end).nil? 42 | Spork.prefork do 43 | # Loading more in this block will cause your tests to run faster. However, 44 | # if you change any configuration or code from libraries loaded here, you'll 45 | # need to restart spork for it take effect. 46 | setup_environment 47 | end 48 | 49 | Spork.each_run do 50 | # This code will be run each time you run your specs. 51 | each_run 52 | end 53 | else 54 | setup_environment 55 | each_run 56 | end 57 | -------------------------------------------------------------------------------- /app/views/refinery/blog/posts/_post.html.erb: -------------------------------------------------------------------------------- 1 | <% flash.each do |key, value| %> 2 |
    3 | <%= value %> 4 |
    5 | <% end %> 6 |
    7 |
    8 |

    <%= @post.title %>

    9 |
    10 | 13 | <%= content_tag(:div, "#{t('by', :scope => 'refinery.blog.posts.show')} #{@post.author.username}", :class => "blog_author") if @post.author.present? %> 14 | <% if @post.source_url.present? %> 15 |
    16 | <%= "#{t('source', :scope => 'refinery.blog.posts.show')}: " %> 17 | <%= link_to (@post.source_url_title.blank? ? @post.source_url : @post.source_url_title), @post.source_url %> 18 |
    19 | <% end %> 20 | <% if (categories = @post.categories).any? %> 21 | 27 | <% end %> 28 |
    29 |
    30 | <%= @post.body.html_safe %> 31 | 32 | <% if Refinery::Blog::Post::ShareThis.enabled? %> 33 | 34 | <% end %> 35 |
    36 | <%= render '/refinery/draft_page_message' unless @post.nil? or @post.live? -%> 37 | <%= render 'nav' if next_or_previous?(@post) %> 38 | -------------------------------------------------------------------------------- /spec/models/refinery/blog/category_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Refinery 4 | module Blog 5 | describe Category do 6 | let(:category) { FactoryGirl.create(:blog_category) } 7 | let(:refinery_user) { FactoryGirl.create(:refinery_user) } 8 | 9 | describe "validations" do 10 | it "requires title" do 11 | FactoryGirl.build(:blog_category, :title => "").should_not be_valid 12 | end 13 | 14 | it "won't allow duplicate titles" do 15 | FactoryGirl.build(:blog_category, :title => category.title).should_not be_valid 16 | end 17 | end 18 | 19 | describe "blog posts association" do 20 | it "has a posts attribute" do 21 | category.should respond_to(:posts) 22 | end 23 | 24 | it "returns posts by published_at date in descending order" do 25 | first_post = category.posts.create!({ :title => "Breaking News: Joe Sak is hot stuff you guys!!", 26 | :body => "True story.", 27 | :published_at => Time.now.yesterday, 28 | :author => refinery_user }) 29 | 30 | latest_post = category.posts.create!({ :title => "parndt is p. okay", 31 | :body => "For a Kiwi.", 32 | :published_at => Time.now, 33 | :author => refinery_user }) 34 | 35 | category.posts.first.should == latest_post 36 | end 37 | 38 | end 39 | 40 | describe "#post_count" do 41 | it "returns post count in category" do 42 | 2.times do 43 | category.posts << FactoryGirl.create(:blog_post) 44 | end 45 | category.post_count.should == 2 46 | end 47 | end 48 | end 49 | end 50 | end -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Refinery CMS Blog 2 | 3 | Simple blog engine for [Refinery CMS](http://refinerycms.com). It supports posts, categories and comments. 4 | 5 | This version of `refinerycms-blog` supports Rails 3.2.x. To use Rails 2.3.x use the [refinerycms-blog "Rails 2.3.x stable branch"](http://github.com/resolve/refinerycms-blog/tree/rails2-stable). 6 | 7 | Options: 8 | 9 | * Comment moderation 10 | * [ShareThis.com](http://sharethis.com) support on posts. To enable, set your key in Refinery's settings area. 11 | 12 | ## Requirements 13 | 14 | Refinery CMS version 2.0.1 or above. 15 | 16 | ## Install 17 | 18 | Open up your ``Gemfile`` and add at the bottom this line: 19 | 20 | ```ruby 21 | gem 'refinerycms-blog', '~> 2.0.0' 22 | ``` 23 | 24 | Now, run ``bundle install`` 25 | 26 | Next, to install the blog plugin run: 27 | 28 | rails generate refinery:blog 29 | 30 | Run database migrations: 31 | 32 | rake db:migrate 33 | 34 | Finally seed your database and you're done. 35 | 36 | rake db:seed 37 | 38 | ## Developing & Contributing 39 | 40 | The version of Refinery to develop this engine against is defined in the gemspec. To override the version of refinery to develop against, edit the project Gemfile to point to a local path containing a clone of refinerycms. 41 | 42 | ### Testing 43 | 44 | Generate the dummy application to test against 45 | 46 | $ bundle exec rake refinery:testing:dummy_app 47 | 48 | Run the test suite with [Guard](https://github.com/guard/guard) 49 | 50 | $ bundle exec guard start 51 | 52 | Or just with rake spec 53 | 54 | $ bundle exec rake spec 55 | 56 | ## More Information 57 | * Check out our [Website](http://refinerycms.com/) 58 | * Documentation is available in the [guides](http://refinerycms.com/guides) 59 | * Questions can be asked on our [Google Group](http://group.refinerycms.org) 60 | * Questions can also be asked in our IRC room, [#refinerycms on freenode](irc://irc.freenode.net/refinerycms) -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gemspec 4 | 5 | gem 'refinerycms', :git => 'git://github.com/refinery/refinerycms.git' 6 | gem 'refinerycms-i18n', :git => 'git://github.com/refinery/refinerycms-i18n.git' 7 | gem 'refinerycms-settings', :git => 'git://github.com/refinery/refinerycms-settings.git' 8 | 9 | group :development, :test do 10 | require 'rbconfig' 11 | 12 | gem 'refinerycms-testing', :git => 'git://github.com/refinery/refinerycms.git' 13 | gem 'guard-rspec', '~> 1.1.0' 14 | 15 | platforms :jruby do 16 | gem 'activerecord-jdbcsqlite3-adapter' 17 | gem 'activerecord-jdbcmysql-adapter' 18 | gem 'activerecord-jdbcpostgresql-adapter' 19 | gem 'jruby-openssl' 20 | end 21 | 22 | unless defined?(JRUBY_VERSION) 23 | gem 'sqlite3' 24 | gem 'mysql2' 25 | gem 'pg' 26 | end 27 | 28 | platforms :mswin, :mingw do 29 | gem 'win32console' 30 | gem 'rb-fchange', '~> 0.0.5' 31 | gem 'rb-notifu', '~> 0.0.4' 32 | end 33 | 34 | platforms :ruby do 35 | gem 'guard-spork', '~> 1.1.0' 36 | 37 | unless ENV['TRAVIS'] 38 | if RbConfig::CONFIG['target_os'] =~ /darwin/i 39 | gem 'rb-fsevent', '~> 0.9.1' 40 | gem 'ruby_gntp', '~> 0.3.4' 41 | end 42 | if RbConfig::CONFIG['target_os'] =~ /linux/i 43 | gem 'rb-inotify', '~> 0.8.8' 44 | gem 'libnotify', '~> 0.7.4' 45 | gem 'therubyracer', '~> 0.10.1' 46 | end 47 | end 48 | end 49 | 50 | platforms :jruby do 51 | unless ENV['TRAVIS'] 52 | if RbConfig::CONFIG['target_os'] =~ /darwin/i 53 | gem 'ruby_gntp', '~> 0.3.4' 54 | end 55 | if RbConfig::CONFIG['target_os'] =~ /linux/i 56 | gem 'rb-inotify', '~> 0.8.8' 57 | gem 'libnotify', '~> 0.7.4' 58 | end 59 | end 60 | end 61 | end 62 | 63 | # Refinery/rails should pull in the proper versions of these 64 | group :assets do 65 | gem 'sass-rails' 66 | gem 'coffee-rails' 67 | gem 'uglifier' 68 | end 69 | 70 | gem 'jquery-rails' 71 | -------------------------------------------------------------------------------- /app/controllers/refinery/blog/admin/settings_controller.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | module Admin 4 | class SettingsController < ::Refinery::AdminController 5 | 6 | def notification_recipients 7 | @recipients = Refinery::Blog::Comment::Notification.recipients 8 | 9 | if request.post? 10 | Refinery::Blog::Comment::Notification.recipients = params[:recipients] 11 | flash[:notice] = t('updated', :scope => 'refinery.blog.admin.settings.notification_recipients', 12 | :recipients => Refinery::Blog::Comment::Notification.recipients) 13 | unless request.xhr? or from_dialog? 14 | redirect_back_or_default(refinery.blog_admin_posts_path) 15 | else 16 | render :text => "", 17 | :layout => false 18 | end 19 | end 20 | end 21 | 22 | def moderation 23 | enabled = Refinery::Blog::Comment::Moderation.toggle! 24 | unless request.xhr? 25 | redirect_back_or_default(refinery.blog_admin_posts_path) 26 | else 27 | render :json => {:enabled => enabled}, 28 | :layout => false 29 | end 30 | end 31 | 32 | def comments 33 | enabled = Refinery::Blog::Comment.toggle! 34 | unless request.xhr? 35 | redirect_back_or_default(refinery.blog_admin_posts_path) 36 | else 37 | render :json => {:enabled => enabled}, 38 | :layout => false 39 | end 40 | end 41 | 42 | def teasers 43 | enabled = Refinery::Blog::Post.teaser_enabled_toggle! 44 | unless request.xhr? 45 | redirect_back_or_default(refinery.blog_admin_posts_path) 46 | else 47 | render :json => {:enabled => enabled}, 48 | :layout => false 49 | end 50 | end 51 | 52 | end 53 | end 54 | end 55 | end -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/backend.css.scss: -------------------------------------------------------------------------------- 1 | .comments_icon { 2 | background-image: image_url('refinery/blog/icons/comments.png'); 3 | } 4 | .comment_icon { 5 | background-image: image_url('refinery/blog/icons/comment.png'); 6 | } 7 | .comment_cross_icon { 8 | background-image: image_url('refinery/blog/icons/comment_cross.png'); 9 | } 10 | .comment_tick_icon { 11 | background-image: image_url('refinery/blog/icons/comment_tick.png'); 12 | } 13 | .folder_icon { 14 | background-image: image_url('refinery/blog/icons/folder.png'); 15 | } 16 | .folder_add_icon { 17 | background-image: image_url('refinery/blog/icons/folder_add.png'); 18 | } 19 | .folder_edit_icon { 20 | background-image: image_url('refinery/blog/icons/folder_edit.png'); 21 | } 22 | .settings_icon { 23 | background-image: image_url('refinery/blog/icons/cog.png'); 24 | } 25 | .page_icon { 26 | background-image: image_url('refinery/blog/icons/page.png'); 27 | } 28 | .page_copy_icon { 29 | background-image: image_url('refinery/blog/icons/page_copy.png'); 30 | } 31 | .page_add_icon { 32 | background-image: image_url('refinery/blog/icons/page_add.png'); 33 | } 34 | ul.collapsible_menu li { 35 | position: relative; 36 | } 37 | ul.collapsible_menu li span.arrow { 38 | background-repeat: no-repeat; 39 | position: absolute; 40 | right: 10px; 41 | top: 13px; 42 | width: 11px; 43 | height: 7px; 44 | cursor: pointer; 45 | } 46 | ul.collapsible_menu li span.arrow { 47 | background-image: image_url('refinery/blog/icons/up.gif'); 48 | } 49 | ul.collapsible_menu li.closed span.arrow { 50 | background-image: image_url('refinery/blog/icons/down.gif'); 51 | } 52 | ul.collapsible_menu > div { 53 | width: 93%; 54 | margin: 0px auto; 55 | } 56 | ul.blog_categories{ 57 | height:200px; 58 | overflow:auto; 59 | border:1px solid #ccc; 60 | padding:5px; 61 | } 62 | ul.blog_categories, ul.blog_categories li { 63 | list-style: none; 64 | margin:5px 0; 65 | } 66 | a#copy_body_link { 67 | background: image_url('refinery/icons/add.png') no-repeat scroll 0 6px transparent; 68 | border-bottom: 0 none; 69 | display: inline; 70 | line-height: 29px; 71 | margin-top: 0; 72 | padding-left: 20px; 73 | } 74 | -------------------------------------------------------------------------------- /app/views/refinery/blog/shared/_post.html.erb: -------------------------------------------------------------------------------- 1 | <% if post.live? %> 2 |
    3 |
    4 |

    <%= link_to post.title, refinery.blog_post_path(post) %>

    5 |
    6 | 9 | <%= "#{t('by', :scope => 'refinery.blog.posts.show')} #{post.author.username}" if post.author.present? %>. 10 | <% if (categories = post.categories.translated).any? %> 11 | 15 | <% end %> 16 | <% if (tags = post.tags).any? %> 17 | 21 | <% end %> 22 |
    23 |
    24 |
    25 | <% if blog_post_teaser_enabled? %> 26 | <%= blog_post_teaser(post) %> 27 | <% else %> 28 | <%= post.body.html_safe %> 29 | <% end %> 30 |
    31 |
    32 |

    33 | <% if blog_post_teaser_enabled? && post.custom_teaser.present? %> 34 | <%= link_to t('read_more', :scope => 'refinery.blog.shared.posts'), refinery.blog_post_path(post) %> 35 | <% end %> 36 |

    37 | <% if Refinery::Blog::Post.comments_allowed? %> 38 | 41 | <% end %> 42 |
    43 |
    44 | <% end %> 45 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/comments/show.html.erb: -------------------------------------------------------------------------------- 1 |
    2 |

    <%= t('.details')%>

    3 |

    4 | <%= t('.age') %>: <%= time_ago_in_words(@comment.created_at) %> 5 |

    6 |

    <%= t('.actions') %>

    7 | 22 |
    23 |
    24 |

    <%= t('.comment') %>

    25 | 26 | 27 | 30 | 35 | 36 | 37 | 40 | 43 | 44 | 45 | 48 | 51 | 52 | 53 | 56 | 61 | 62 |
    28 | <%= t('.blog_post') %> 29 | 31 | <%= link_to @comment.post.title, 32 | refinery.blog_post_path(@comment.post, :anchor => "comment-#{@comment.to_param}"), 33 | :target => '_blank' %> 34 |
    38 | <%= t('.from') %> 39 | 41 | <%= @comment.name %> [<%= mail_to @comment.email, @comment.email, {:title => t('.click_to_email')} %>] 42 |
    46 | <%= t('.date') %> 47 | 49 | <%= l(Date.parse(@comment.created_at.to_s), :format => :long) %> 50 |
    54 | <%= t('.message') %> 55 | 57 |

    58 | <%= @comment.message.gsub("\r\n\r\n", "\r\n").gsub("\r\n", "

    ") %> 59 |

    60 |
    63 |
    64 | 65 | <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/backend') %> 66 | -------------------------------------------------------------------------------- /app/assets/stylesheets/refinery/blog/frontend.css.scss: -------------------------------------------------------------------------------- 1 | .blog_post header, .blog_post footer { 2 | width: auto; 3 | } 4 | .blog_post .posted_at{ 5 | } 6 | .post_categories .filed_in { 7 | display: inline; 8 | } 9 | .post_categories ul { 10 | margin: 0px 0px 0px 6px; 11 | padding: 0px; 12 | display: inline; 13 | } 14 | .post_categories ul li { 15 | margin: 0px; 16 | padding: 0px; 17 | display: inline; 18 | } 19 | .field.message_field label { 20 | vertical-align: top; 21 | } 22 | #rss_feed_subscribe { 23 | display: block; 24 | padding-left: 25px; 25 | background: image_url('refinery/blog/rss-feed.png') no-repeat; 26 | } 27 | #next_prev_article{ 28 | overflow:hidden; 29 | margin:10px 0; 30 | position:relative; 31 | height:30px; 32 | } 33 | #next_prev_article a{ 34 | display:block; 35 | width:33%; 36 | height:30px; 37 | line-height:30px; 38 | position:absolute; 39 | top:0; 40 | } 41 | #next_prev_article a.prev{ 42 | left:0; 43 | } 44 | #next_prev_article a.home{ 45 | left:33%; 46 | text-align:center; 47 | } 48 | #next_prev_article a.next{ 49 | text-align:right; 50 | right:0; 51 | } 52 | 53 | #message, .flash { 54 | padding: 8px 8px 8px 30px; 55 | margin-bottom: 15px; 56 | position: relative; 57 | } 58 | .flash_notice, .flash_message { 59 | border: 1px solid #00A017; 60 | color: #00A017; 61 | background: 7px 7px no-repeat image_url('refinery/blog/icons/accept.png') #E0F5E0; 62 | } 63 | .flash_notice, .flash_notice * { 64 | color: #00A017; 65 | } 66 | .flash_error { 67 | border: 1px solid #A00027; 68 | color: #A00027; 69 | background: 7px 7px no-repeat image_url('refinery/blog/icons/cancel.png') #FFB1B1; 70 | } 71 | .flash.flash_notice #flash_close, .flash.flash_error #flash_close { 72 | text-transform: lowercase; 73 | } 74 | .flash.flash_message { 75 | background: #E0F5E0; 76 | padding: 9px; 77 | position: relative; 78 | margin-bottom: 32px; 79 | } 80 | .flash.flash_message h2 { 81 | margin-top: 12px; 82 | } 83 | .flash_message, .flash_message * { 84 | color: #262719; 85 | font-size: 14px; 86 | } 87 | .flash a, .flash a:hover { 88 | color: #e20003; 89 | border-bottom-color: #e20003; 90 | } 91 | .flash.flash_error a, .flash.flash_error a:hover { 92 | display: none; 93 | } /* FLASH MESSAGES */ 94 | -------------------------------------------------------------------------------- /config/initializers/url_validator.rb: -------------------------------------------------------------------------------- 1 | require 'net/http' 2 | 3 | class UrlValidator < ActiveModel::EachValidator 4 | 5 | def validate_each(record, attribute, value) 6 | url = value 7 | 8 | # Regex code by 'Arsenic' from http://snippets.dzone.com/posts/show/3654 9 | if url =~ /^ 10 | ( (https?):\/\/ )? 11 | ( [a-z\d]+([\-\.][a-z\d]+)*\.[a-z]{2,6} ) 12 | ( 13 | (: 14 | ( \d{1,5} ) 15 | )? 16 | ( \/.* )? 17 | )? 18 | $/ix 19 | url = "http#{'s' if $7 == '81'}://#{url}" unless $1 20 | else 21 | record.errors[attribute] << 'Not a valid URL' 22 | end 23 | 24 | if options[:verify] 25 | begin 26 | url_response = RedirectFollower.new(url).resolve 27 | url = url_response.url if options[:verify] == [:resolve_redirects] 28 | rescue RedirectFollower::TooManyRedirects 29 | record.errors[attribute] << 'URL is redirecting too many times' 30 | rescue 31 | record.errors[attribute] << 'could not be resolved' 32 | end 33 | end 34 | 35 | if options[:update] 36 | value.replace url 37 | end 38 | end 39 | end 40 | 41 | # Code below written by John Nunemaker 42 | # See blog post at http://railstips.org/blog/archives/2009/03/04/following-redirects-with-nethttp/ 43 | class RedirectFollower 44 | class TooManyRedirects < StandardError; end 45 | 46 | attr_accessor :url, :body, :redirect_limit, :response 47 | 48 | def initialize(url, limit=5) 49 | @url, @redirect_limit = url, limit 50 | end 51 | 52 | def logger 53 | @logger ||= Rails.logger 54 | end 55 | 56 | def resolve 57 | raise TooManyRedirects if redirect_limit < 0 58 | 59 | self.response = Net::HTTP.get_response(URI.parse(url)) 60 | 61 | logger.info "redirect limit: #{redirect_limit}" 62 | logger.info "response code: #{response.code}" 63 | logger.debug "response body: #{response.body}" 64 | 65 | if response.kind_of?(Net::HTTPRedirection) 66 | self.url = redirect_url 67 | self.redirect_limit -= 1 68 | 69 | logger.info "redirect found, headed to #{url}" 70 | resolve 71 | end 72 | 73 | self.body = response.body 74 | self 75 | end 76 | 77 | def redirect_url 78 | if response['location'].nil? 79 | response.body.match(/]+)\">/i)[1] 80 | else 81 | response['location'] 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /spec/controllers/refinery/blog/admin/comments_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Refinery 4 | module Blog 5 | module Admin 6 | describe CommentsController do 7 | refinery_login_with :refinery_user 8 | 9 | describe "#index" do 10 | let!(:comment) { FactoryGirl.create(:blog_comment) } 11 | 12 | it "succeeds" do 13 | get :index 14 | response.should be_success 15 | response.should render_template(:index) 16 | end 17 | 18 | it "assigns unmoderated comments" do 19 | get :index 20 | assigns(:comments).first.should eq(comment) 21 | end 22 | end 23 | 24 | describe "#approved" do 25 | let!(:comment) { FactoryGirl.create(:approved_comment) } 26 | 27 | it "succeeds" do 28 | get :approved 29 | response.should be_success 30 | response.should render_template(:index) 31 | end 32 | 33 | it "assigns approved comments" do 34 | get :approved 35 | assigns(:comments).first.should eq(comment) 36 | end 37 | end 38 | 39 | describe "#approve" do 40 | let!(:comment) { FactoryGirl.create(:blog_comment) } 41 | 42 | it "redirects on success" do 43 | post :approve, :id => comment.id 44 | response.should be_redirect 45 | end 46 | 47 | it "approves the comment" do 48 | post :approve, :id => comment.id 49 | Refinery::Blog::Comment.approved.count.should eq(1) 50 | end 51 | end 52 | 53 | describe "#rejected" do 54 | let!(:comment) { FactoryGirl.create(:rejected_comment) } 55 | 56 | it "succeeds" do 57 | get :rejected 58 | response.should be_success 59 | response.should render_template(:index) 60 | end 61 | 62 | it "assigns rejected comments" do 63 | get :rejected 64 | assigns(:comments).first.should eq(comment) 65 | end 66 | end 67 | 68 | describe "#reject" do 69 | let!(:comment) { FactoryGirl.create(:blog_comment) } 70 | 71 | it "redirects on success" do 72 | post :reject, :id => comment.id 73 | response.should be_redirect 74 | end 75 | 76 | it "rejects the comment" do 77 | post :reject, :id => comment.id 78 | Refinery::Blog::Comment.rejected.count.should eq(1) 79 | end 80 | end 81 | end 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /app/helpers/refinery/blog/posts_helper.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | module PostsHelper 4 | def next_or_previous?(post) 5 | post.next.present? or post.prev.present? 6 | end 7 | 8 | def blog_post_teaser_enabled? 9 | Refinery::Blog::Post.teasers_enabled? 10 | end 11 | 12 | def blog_post_teaser(post) 13 | if post.respond_to?(:custom_teaser) && post.custom_teaser.present? 14 | post.custom_teaser.html_safe 15 | else 16 | truncate(post.body, { 17 | :length => Refinery::Blog.post_teaser_length, 18 | :preserve_html_tags => true 19 | }).html_safe 20 | end 21 | end 22 | 23 | def blog_archive_widget(dates=blog_archive_dates) 24 | ArchiveWidget.new(dates, self).display 25 | end 26 | 27 | def blog_archive_dates(cutoff=Time.now.beginning_of_month) 28 | Refinery::Blog::Post.published_dates_older_than(cutoff) 29 | end 30 | 31 | def avatar_url(email, options = {:size => 60}) 32 | require 'digest/md5' 33 | "http://gravatar.com/avatar/#{Digest::MD5.hexdigest(email.to_s.strip.downcase)}?s=#{options[:size]}.jpg" 34 | end 35 | 36 | class ArchiveWidget 37 | delegate :t, :link_to, :refinery, :render, :to => :view_context 38 | attr_reader :view_context 39 | 40 | def initialize(dates, view_context, cutoff=3.years.ago.end_of_year) 41 | @recent_dates, @old_dates = dates.sort_by {|date| -date.to_i }. 42 | partition {|date| date > cutoff } 43 | 44 | @view_context = view_context 45 | end 46 | 47 | def recent_links 48 | @recent_dates.group_by {|date| [date.year, date.month] }. 49 | map {|(year, month), dates| recent_link(year, month, dates.count) } 50 | end 51 | 52 | def recent_link(year, month, count) 53 | link_to "#{t("date.month_names")[month]} #{year} (#{count})", 54 | refinery.blog_archive_posts_path(:year => year, :month => month) 55 | end 56 | 57 | def old_links 58 | @old_dates.group_by {|date| date.year }. 59 | map {|year, dates| old_link(year, dates.size) } 60 | end 61 | 62 | def old_link(year, count) 63 | link_to "#{year} (#{count})", refinery.blog_archive_posts_path(:year => year) 64 | end 65 | 66 | def links 67 | recent_links + old_links 68 | end 69 | 70 | def display 71 | return "" if links.empty? 72 | render "refinery/blog/widgets/blog_archive", :links => links 73 | end 74 | end 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /spec/helpers/refinery/blog/posts_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Refinery 4 | module Blog 5 | describe PostsHelper do 6 | describe "#blog_archive_widget" do 7 | let(:html) { helper.blog_archive_widget(dates) } 8 | let(:links) { Capybara.string(html).find("#blog_archive_widget ul") } 9 | 10 | context "with no archive dates" do 11 | let(:dates) { [] } 12 | 13 | it "does not display anything" do 14 | html.should be_blank 15 | end 16 | end 17 | 18 | context "with archive dates" do 19 | let(:recent_post) { 2.months.ago } 20 | let(:old_post) { 4.years.ago } 21 | 22 | let(:dates) do 23 | [old_post, recent_post].map do |date| 24 | [date, date.beginning_of_month, date.end_of_month] 25 | end.flatten 26 | end 27 | 28 | it "has a link for the month of dates not older than one year" do 29 | month = Date::MONTHNAMES[recent_post.month] 30 | year = recent_post.year 31 | 32 | links.should have_link("#{month} #{year} (3)") 33 | end 34 | 35 | it "has a link for the year of dates older than one year" do 36 | year = old_post.year 37 | 38 | links.should have_link("#{year} (3)") 39 | end 40 | 41 | it "sorts recent links before old links" do 42 | links.find("li:first").should have_content(recent_post.year.to_s) 43 | links.find("li:last").should have_content(old_post.year.to_s) 44 | end 45 | end 46 | 47 | context "with multiple recent dates" do 48 | let(:dates) { [3.months.ago, 2.months.ago] } 49 | 50 | it "sorts by the more recent date" do 51 | first, second = dates.map {|p| Date::MONTHNAMES[p.month] } 52 | 53 | links.find("li:first").should have_content(second) 54 | links.find("li:last").should have_content(first) 55 | end 56 | end 57 | 58 | context "with multiple old dates" do 59 | let(:dates) { [5.years.ago, 4.years.ago] } 60 | 61 | it "sorts by the more recent date" do 62 | first, second = dates.map {|p| p.year.to_s } 63 | 64 | links.find("li:first").should have_content(second) 65 | links.find("li:last").should have_content(first) 66 | end 67 | end 68 | end 69 | 70 | describe "#avatar_url" do 71 | let(:email) { "test@test.com" } 72 | 73 | it "returns gravatar url" do 74 | helper.avatar_url(email).should eq("http://gravatar.com/avatar/b642b4217b34b1e8d3bd915fc65c4452?s=60.jpg") 75 | end 76 | 77 | it "accepts options hash to change default size" do 78 | helper.avatar_url(email, :size => 55).should eq("http://gravatar.com/avatar/b642b4217b34b1e8d3bd915fc65c4452?s=55.jpg") 79 | end 80 | end 81 | end 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /app/controllers/refinery/blog/posts_controller.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class PostsController < BlogController 4 | 5 | before_filter :find_all_blog_posts, :except => [:archive] 6 | before_filter :find_blog_post, :only => [:show, :comment, :update_nav] 7 | before_filter :find_tags 8 | 9 | respond_to :html, :js, :rss 10 | 11 | def index 12 | # Rss feeders are greedy. Let's give them every blog post instead of paginating. 13 | (@posts = Post.live.includes(:comments, :categories).with_globalize) if request.format.rss? 14 | respond_with (@posts) do |format| 15 | format.html 16 | format.rss { render :layout => false } 17 | end 18 | end 19 | 20 | def show 21 | @comment = Comment.new 22 | 23 | @canonical = refinery.url_for(:locale => Refinery::I18n.current_frontend_locale) if canonical? 24 | 25 | @post.increment!(:access_count, 1) 26 | 27 | respond_with (@post) do |format| 28 | format.html { present(@post) } 29 | format.js { render :partial => 'post', :layout => false } 30 | end 31 | end 32 | 33 | def comment 34 | if (@comment = @post.comments.create(params[:comment])).valid? 35 | if Comment::Moderation.enabled? or @comment.ham? 36 | begin 37 | CommentMailer.notification(@comment, request).deliver 38 | rescue 39 | logger.warn "There was an error delivering a blog comment notification.\n#{$!}\n" 40 | end 41 | end 42 | 43 | if Comment::Moderation.enabled? 44 | flash[:notice] = t('thank_you_moderated', :scope => 'refinery.blog.posts.comments') 45 | redirect_to refinery.blog_post_url(params[:id]) 46 | else 47 | flash[:notice] = t('thank_you', :scope => 'refinery.blog.posts.comments') 48 | redirect_to refinery.blog_post_url(params[:id], 49 | :anchor => "comment-#{@comment.to_param}") 50 | end 51 | else 52 | render :show 53 | end 54 | end 55 | 56 | def archive 57 | if params[:month].present? 58 | date = "#{params[:month]}/#{params[:year]}" 59 | @archive_date = Time.parse(date) 60 | @date_title = @archive_date.strftime('%B %Y') 61 | @posts = Post.live.by_month(@archive_date).page(params[:page]) 62 | else 63 | date = "01/#{params[:year]}" 64 | @archive_date = Time.parse(date) 65 | @date_title = @archive_date.strftime('%Y') 66 | @posts = Post.live.by_year(@archive_date).page(params[:page]) 67 | end 68 | respond_with (@posts) 69 | end 70 | 71 | def tagged 72 | @tag = ActsAsTaggableOn::Tag.find(params[:tag_id]) 73 | @tag_name = @tag.name 74 | @posts = Post.tagged_with(@tag_name).with_globalize.page(params[:page]) 75 | end 76 | 77 | protected 78 | def canonical? 79 | ::Refinery.i18n_enabled? && ::Refinery::I18n.default_frontend_locale != ::Refinery::I18n.current_frontend_locale 80 | end 81 | end 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /app/controllers/refinery/blog/admin/posts_controller.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | module Admin 4 | class PostsController < ::Refinery::AdminController 5 | 6 | crudify :'refinery/blog/post', 7 | :order => 'published_at DESC', 8 | :include => [:translations] 9 | 10 | before_filter :find_all_categories, 11 | :only => [:new, :edit, :create, :update] 12 | 13 | before_filter :check_category_ids, :only => :update 14 | 15 | def uncategorized 16 | @posts = Refinery::Blog::Post.uncategorized.page(params[:page]) 17 | end 18 | 19 | def tags 20 | if ActiveRecord::Base.connection.adapter_name.downcase == 'postgresql' 21 | op = '~*' 22 | wildcard = '.*' 23 | else 24 | op = 'LIKE' 25 | wildcard = '%' 26 | end 27 | 28 | @tags = Refinery::Blog::Post.tag_counts_on(:tags).where( 29 | ["tags.name #{op} ?", "#{wildcard}#{params[:term].to_s.downcase}#{wildcard}"] 30 | ).map { |tag| {:id => tag.id, :value => tag.name}} 31 | render :json => @tags.flatten 32 | end 33 | 34 | def new 35 | @post = ::Refinery::Blog::Post.new(:author => current_refinery_user) 36 | end 37 | 38 | def create 39 | # if the position field exists, set this object as last object, given the conditions of this class. 40 | if Refinery::Blog::Post.column_names.include?("position") 41 | params[:post].merge!({ 42 | :position => ((Refinery::Blog::Post.maximum(:position, :conditions => "")||-1) + 1) 43 | }) 44 | end 45 | 46 | if (@post = Refinery::Blog::Post.create(params[:post])).valid? 47 | (request.xhr? ? flash.now : flash).notice = t( 48 | 'refinery.crudify.created', 49 | :what => "'#{@post.title}'" 50 | ) 51 | 52 | unless from_dialog? 53 | unless params[:continue_editing] =~ /true|on|1/ 54 | redirect_back_or_default(refinery.blog_admin_posts_path) 55 | else 56 | unless request.xhr? 57 | redirect_to :back 58 | else 59 | render "/shared/message" 60 | end 61 | end 62 | else 63 | render :text => "" 64 | end 65 | else 66 | unless request.xhr? 67 | render :new 68 | else 69 | render :partial => "/refinery/admin/error_messages", 70 | :locals => { 71 | :object => @post, 72 | :include_object_name => true 73 | } 74 | end 75 | end 76 | end 77 | 78 | protected 79 | def find_post 80 | @post = Refinery::Blog::Post.find_by_slug_or_id(params[:id]) 81 | end 82 | 83 | def find_all_categories 84 | @categories = Refinery::Blog::Category.find(:all) 85 | end 86 | 87 | def check_category_ids 88 | params[:post][:category_ids] ||= [] 89 | end 90 | end 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | ## 1.6.3 [UNRELEASED] 2 | * Bulgarian translations [mirosr](https://github.com/mirosr) 3 | * posts/tagged... params[:tag_name] is optional [joemsak](https://github.com/joemsak) 4 | 5 | ## 1.6.2 [29 June 2011] 6 | * Custom teaser field to overwrite the automatic truncation of the body [wikyd](https://github.com/wikyd) 7 | * Tagging URL strategy updated again [joemsak](https://github.com/joemsak) 8 | * Tagging bug fixed [ruprict](https://github.com/ruprict) 9 | * Refactored specs [parndt](https://github.com/parndt) 10 | 11 | ## 1.6.1 [21 June 2011] 12 | * Tagging URL strategy updated for reliability /blog/posts/tagged/ID-name-parameterized [joemsak](https://github.com/joemsak) 13 | * Heroku/PostgreSQL support for autocomplete tags [joemsak](https://github.com/joemsak) 14 | 15 | ## 1.6 [20 June 2011] 16 | * Category bug fixes and cleanup [wikyd](https://github.com/wikyd) 17 | * Cleaned up deprecated code [ugisozols](https://github.com/ugisozols) 18 | * Performance boosts (cached slugs) [joemsak](https://github.com/joemsak) 19 | * More translations [cerebroso](https://github.com/cerebroso), [peresleguine](https://github.com/peresleguine) 20 | * More testing [wakeless](https://github.com/wakeless) 21 | * Tag list autocomplete baked in [joemsak](https://github.com/joemsak) 22 | * Customize the URL of your blog post [wikyd](https://github.com/wikyd) 23 | 24 | ## 1.5 [28 May 2011] 25 | 26 | * Added Gravatar support. [parndt](https://github.com/parndt) 27 | * Added support for Refinery CMS 1.0.0 and above. [parndt](https://github.com/parndt) 28 | 29 | ## 1.4 [26 May 2011] 30 | 31 | * Spanish language fixes [scambra](https://github.com/scambra) 32 | * Bug fixes [scambra](https://github.com/scambra) 33 | * Tags [joemsak](https://github.com/joemsak) 34 | * Tagged posts route / view [joemsak](https://github.com/joemsak) 35 | * Tag cloud in sidebar 36 | * Czech & slovak translations [karem](https://github.com/keram) 37 | * SEO fields and migration [parndt](https://github.com/parndt) [ugisozols](https://github.com/ugisozols) 38 | * [See full list](https://github.com/resolve/refinerycms-blog/compare/1.3...1.4) 39 | 40 | ## 1.3 [03 March 2011] 41 | 42 | * Moved to EngineInstaller [parndt](https://github.com/parndt) 43 | * Off Rails 2 support [parndt](https://github.com/parndt) 44 | * [See full list](https://github.com/resolve/refinerycms-blog/compare/1.2...1.3) 45 | 46 | ## 1.2 [01 March 2011] 47 | 48 | * Posts can be authored [joemsak](https://github.com/joemsak) 49 | * Front-end pagination [joemsak](https://github.com/joemsak) 50 | * Archives start grouping by year after 2 years [joemsak](https://github.com/joemsak) 51 | * Removed ajax blog post navigation [joemsak](https://github.com/joemsak) 52 | * Administrate uncategorized posts [joemsak](https://github.com/joemsak) 53 | * Categories in has_many :through relationship [joemsak](https://github.com/joemsak) 54 | * General bug fixing & test coverage [parndt](https://github.com/parndt) [joemsak](https://github.com/joemsak) 55 | * Russian translation [iband](https://github.com/iband) 56 | * French translation [AdrienGiboire](https://github.com/AdrienGiboire) 57 | * Polish translation [murbanski](https://github.com/murbanski) 58 | * German translation [gern](https://github.com/gern) 59 | * Spanish translation help [xavib](https://github.com/xavib) 60 | * Rails 3 cleanup & optimization [ugisozols](https://github.com/ugisozols) 61 | * [See full list](https://github.com/resolve/refinerycms-blog/compare/1.1...1.2) 62 | 63 | 64 | ## 1.1 [02 December 2010] 65 | 66 | * Rails 3 Support 67 | * Archives 68 | * Categories 69 | * [See full list](https://github.com/resolve/refinerycms-blog/compare/1.0...1.1) -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/_submenu.html.erb: -------------------------------------------------------------------------------- 1 | 92 | 93 | <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/backend') %> 94 | -------------------------------------------------------------------------------- /app/models/refinery/blog/comment.rb: -------------------------------------------------------------------------------- 1 | module Refinery 2 | module Blog 3 | class Comment < ActiveRecord::Base 4 | 5 | attr_accessible :name, :email, :message 6 | 7 | filters_spam :author_field => :name, 8 | :email_field => :email, 9 | :message_field => :body 10 | 11 | belongs_to :post, :foreign_key => 'blog_post_id' 12 | 13 | acts_as_indexed :fields => [:name, :email, :message] 14 | 15 | alias_attribute :message, :body 16 | 17 | validates :name, :message, :presence => true 18 | validates :email, :format => { :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i } 19 | 20 | class << self 21 | def unmoderated 22 | where(:state => nil) 23 | end 24 | 25 | def approved 26 | where(:state => 'approved') 27 | end 28 | 29 | def rejected 30 | where(:state => 'rejected') 31 | end 32 | end 33 | 34 | self.per_page = Refinery::Blog.comments_per_page 35 | 36 | def approve! 37 | self.update_column(:state, 'approved') 38 | end 39 | 40 | def reject! 41 | self.update_column(:state, 'rejected') 42 | end 43 | 44 | def rejected? 45 | self.state == 'rejected' 46 | end 47 | 48 | def approved? 49 | self.state == 'approved' 50 | end 51 | 52 | def unmoderated? 53 | self.state.nil? 54 | end 55 | 56 | def self.toggle! 57 | currently = Refinery::Setting.find_or_set(:comments_allowed, true, { 58 | :scoping => 'blog' 59 | }) 60 | Refinery::Setting.set(:comments_allowed, {:value => !currently, :scoping => 'blog'}) 61 | end 62 | 63 | before_create do |comment| 64 | unless Moderation.enabled? 65 | comment.state = comment.ham? ? 'approved' : 'rejected' 66 | end 67 | end 68 | 69 | module Moderation 70 | class << self 71 | def enabled? 72 | Refinery::Setting.find_or_set(:comment_moderation, true, { 73 | :scoping => 'blog', 74 | :restricted => false 75 | }) 76 | end 77 | 78 | def toggle! 79 | new_value = { 80 | :value => !Blog::Comment::Moderation.enabled?, 81 | :scoping => 'blog', 82 | :restricted => false 83 | } 84 | Refinery::Setting.set(:comment_moderation, new_value) 85 | end 86 | end 87 | end 88 | 89 | module Notification 90 | class << self 91 | def recipients 92 | Refinery::Setting.find_or_set(:comment_notification_recipients, (Refinery::Role[:refinery].users.first.email rescue ''), 93 | { 94 | :scoping => 'blog', 95 | :restricted => false 96 | }) 97 | end 98 | 99 | def recipients=(emails) 100 | new_value = { 101 | :value => emails, 102 | :scoping => 'blog', 103 | :restricted => false 104 | } 105 | Refinery::Setting.set(:comment_notification_recipients, new_value) 106 | end 107 | 108 | def subject 109 | Refinery::Setting.find_or_set(:comment_notification_subject, "New inquiry from your website", { 110 | :scoping => 'blog', 111 | :restricted => false 112 | }) 113 | end 114 | 115 | def subject=(subject_line) 116 | new_value = { 117 | :value => subject_line, 118 | :scoping => 'blog', 119 | :restricted => false 120 | } 121 | Refinery::Setting.set(:comment_notification_subject, new_value) 122 | end 123 | end 124 | end 125 | 126 | end 127 | end 128 | end 129 | -------------------------------------------------------------------------------- /spec/requests/refinery/blog/admin/categories_spec.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | require 'spec_helper' 3 | 4 | describe "Categories admin" do 5 | refinery_login_with :refinery_user 6 | 7 | let(:title) { "lol" } 8 | 9 | it "can create categories" do 10 | visit refinery.admin_root_path 11 | 12 | within("nav#menu") { click_link "Blog" } 13 | within("nav.multilist") { click_link "Create new category" } 14 | 15 | fill_in "Title", :with => title 16 | click_button "Save" 17 | 18 | category = Refinery::Blog::Category.first 19 | category.title.should eq(title) 20 | end 21 | 22 | context "with translations" do 23 | before(:each) do 24 | Refinery::I18n.stub(:frontend_locales).and_return([:en, :ru]) 25 | blog_page = Globalize.with_locale(:en) { Factory.create(:page, :link_url => "/blog", :title => "Blog") } 26 | Globalize.with_locale(:ru) do 27 | blog_page.title = 'блог' 28 | blog_page.save 29 | end 30 | end 31 | 32 | describe "add a category with title for default locale" do 33 | before do 34 | Globalize.locale = :en 35 | visit refinery.blog_admin_posts_path 36 | click_link "Create new category" 37 | fill_in "Title", :with => "Testing Category" 38 | click_button "Save" 39 | @c = Refinery::Blog::Category.find_by_title("Testing Category") 40 | end 41 | 42 | it "suceeds" do 43 | page.should have_content("'#{@c.title}' was successfully added.") 44 | Refinery::Blog::Category.count.should eq(1) 45 | end 46 | 47 | it "shows locale flag for category" do 48 | click_link "Manage" 49 | within "#category_#{@c.id}" do 50 | page.should have_css("img[src='/assets/refinery/icons/flags/en.png']") 51 | end 52 | end 53 | 54 | it "shows up in blog page for default locale" do 55 | visit refinery.blog_root_path 56 | within "#categories" do 57 | page.should have_selector('li') 58 | end 59 | end 60 | 61 | it "does not show up in blog page for secondary locale" do 62 | visit refinery.blog_root_path(:locale => :ru) 63 | page.should_not have_selector('#categories') 64 | end 65 | 66 | end 67 | 68 | describe "add a category with title for secondary locale" do 69 | 70 | let(:ru_category_title) { 'категория' } 71 | 72 | before do 73 | visit refinery.blog_admin_posts_path 74 | click_link "Create new category" 75 | within "#switch_locale_picker" do 76 | click_link "Ru" 77 | end 78 | fill_in "Title", :with => ru_category_title 79 | click_button "Save" 80 | @c = Refinery::Blog::Category.find_by_title(ru_category_title) 81 | end 82 | 83 | it "suceeds" do 84 | page.should have_content("'#{@c.title}' was successfully added.") 85 | Refinery::Blog::Category.count.should eq(1) 86 | end 87 | 88 | it "shows locale flag for category" do 89 | click_link "Manage" 90 | within "#category_#{@c.id}" do 91 | page.should have_css("img[src='/assets/refinery/icons/flags/ru.png']") 92 | end 93 | end 94 | 95 | it "does not show locale flag for primary locale" do 96 | click_link "Manage" 97 | within "#category_#{@c.id}" do 98 | page.should_not have_css("img[src='/assets/refinery/icons/flags/en.png']") 99 | end 100 | end 101 | 102 | it "does not shows up in blog page for default locale" do 103 | visit refinery.blog_root_path 104 | page.should_not have_selector('#categories') 105 | end 106 | 107 | it "shows up in blog page for secondary locale" do 108 | visit refinery.blog_root_path(:locale => :ru) 109 | within "#categories" do 110 | page.should have_selector('li') 111 | end 112 | end 113 | 114 | 115 | end 116 | 117 | 118 | end 119 | end 120 | -------------------------------------------------------------------------------- /app/assets/javascripts/refinery/blog/backend.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('nav#actions.multilist > ul:not(.search_list) li a[href$="' + window.location.pathname + '"]') 3 | .parent().addClass('selected'); 4 | if($('nav#actions.multilist > ul:not(.search_list) li.selected').length == 0) { 5 | $('nav#actions.multilist > ul:not(.search_list) li a:nth(1)').parent().addClass('selected'); 6 | } 7 | 8 | $('nav#actions.multilist > ul:not(.search_list) li > a').each(function(i,a){ 9 | if ($(this).data('dialog-title') == null) { 10 | $(this).bind('click', function(){ 11 | $(this).css('background-image', "url('/images/refinery/icons/ajax-loader.gif') !important"); 12 | }); 13 | } 14 | }); 15 | 16 | $('ul.collapsible_menu').each(function(i, ul) { 17 | (first_li = $(this).children('li:first')).after(div=$("
    ")); 18 | 19 | $(" ").appendTo(first_li) 20 | 21 | if (($(this).children('li.selected')).length == 0) { 22 | div.hide(); 23 | first_li.addClass("closed"); 24 | } 25 | $(this).children('li:not(:first)').appendTo(div); 26 | 27 | first_li.find('> a, > span.arrow').click(function(e){ 28 | $(this).parent().toggleClass("closed"); 29 | $(this).parent().toggleClass("open"); 30 | 31 | $(this).parent().next('div').animate({ 32 | opacity: 'toggle' 33 | , height: 'toggle' 34 | }, 250, $.proxy(function(){ 35 | $(this).css('background-image', null); 36 | }, $(this)) 37 | ); 38 | e.preventDefault(); 39 | }); 40 | }); 41 | 42 | $('.success_icon, .failure_icon').bind('click', function(e) { 43 | $.get($(this).attr('href'), $.proxy(function(data){ 44 | $(this).css('background-image', null) 45 | .removeClass('failure_icon').removeClass('success_icon') 46 | .addClass(data.enabled ? 'success_icon' : 'failure_icon'); 47 | }, $(this))); 48 | e.preventDefault(); 49 | }); 50 | 51 | 52 | $(function() { 53 | $('#page-tabs').tabs(); 54 | $('#copy_body_link').click(function(event) { 55 | // Find the WYMEditor that maps to the custom_teaser field 56 | var teaserTextArea = $('#post_custom_teaser')[0]; 57 | var teaserEditor = null; 58 | $.each(WYMeditor.INSTANCES, function(index, editor) { 59 | if (editor._element[0] == teaserTextArea) { 60 | teaserEditor = editor; 61 | } 62 | }); 63 | 64 | if (teaserEditor) { 65 | teaserEditor.html($('#post_body').attr('value')); 66 | } 67 | 68 | event.preventDefault(); 69 | }); 70 | }); 71 | 72 | 73 | function split( val ) { 74 | return val.split( /,\s*/ ); 75 | } 76 | function extractLast( term ) { 77 | return split( term ).pop(); 78 | } 79 | 80 | page_options.init(false, '', '') 81 | 82 | $('<%= dom_id %>').bind( "keydown", function( event ) { 83 | if ( event.keyCode === $.ui.keyCode.TAB && $( this ).data( "autocomplete" ).menu.active ) { 84 | event.preventDefault() 85 | } 86 | }).autocomplete({ 87 | source: function( request, response ) { 88 | $.getJSON( "<%= url %>", { 89 | term: extractLast( request.term ) 90 | }, response ); 91 | }, 92 | search: function() { 93 | // custom minLength 94 | var term = extractLast( this.value ); 95 | if ( term.length < 2 ) { 96 | return false; 97 | } 98 | }, 99 | focus: function() { 100 | // prevent value inserted on focus 101 | return false; 102 | }, 103 | select: function( event, ui ) { 104 | var terms = split( this.value ); 105 | // remove the current input 106 | terms.pop(); 107 | // add the selected item 108 | terms.push( ui.item.value ); 109 | // add placeholder to get the comma-and-space at the end 110 | terms.push( "" ); 111 | this.value = terms.join( ", " ); 112 | return false; 113 | } 114 | }) 115 | }); 116 | -------------------------------------------------------------------------------- /config/locales/zh-CN.yml: -------------------------------------------------------------------------------- 1 | zh-CN: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: 博客 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: 编辑此类别 11 | delete: 永久删除此类别 12 | index: 13 | no_items_yet: '没有此类别。 点击 "%{create}" 添加第一次类别。' 14 | comments: 15 | approved: '评论来自 "%{author}" 已被审批。' 16 | comment: 17 | view_live_html: '查看此评论
    (opens in a new window)' 18 | read: 阅读此评论 19 | reject: 驳回此评论 20 | approve: 批准此评论 21 | rejected: '评论来自 "%{author}" 已被驳回。' 22 | index: 23 | no_items_yet: '没有 %{type} 评论。' 24 | show: 25 | comment: 评论 26 | blog_post: 发博 27 | from: 发布由 28 | date: 发布在 29 | message: 评论 30 | details: 详情 31 | age: 年龄 32 | actions: 行动 33 | back: 返回至所有评论 34 | reject: 驳回此评论 35 | approve: 批准此评论 36 | posts: 37 | form: 38 | toggle_advanced_options: 点击进入标签详解设置和菜单选项 39 | published_at: 发布日期 40 | index: 41 | no_items_yet: '目前尚未发博。 点击 "%{create}" 添加您的第一篇博文。' 42 | uncategorized: 43 | no_items_yet: '没有未归类的博文。' 44 | post: 45 | view_live_html: '查看此博
    (opens in a new window)' 46 | edit: 编辑此博 47 | delete: 永久删除此博 48 | settings: 49 | notification_recipients: 50 | value: 发送通知 51 | explanation: '每次有人发表评论,发送邮件告知有新评论。' 52 | hint: '增加新评论时,将会发送邮件告知您。' 53 | example: "输入您的邮件地址,如: jack@work.com, jill@office.com" 54 | updated: '通知收件人已被设为 "%{recipients}"' 55 | submenu: 56 | categories: 57 | title: 分类 58 | manage: 管理 59 | new: 创建新的类别 60 | comments: 61 | title: 评论 62 | title_with_count: '评论 (%{new_count} new)' 63 | new: 新 64 | unmoderated: 新 65 | approved: 批准 66 | rejected: 驳回 67 | posts: 68 | title: 博文 69 | manage: 管理博文 70 | new: 创建新博文 71 | uncategorized: 未归类博文 72 | settings: 73 | title: 设置 74 | moderation: 等待审核 75 | update_notified: 更新获得通知的人 76 | comments: 评论 77 | comment_mailer: 78 | notification: 79 | greeting: 您好 80 | you_recieved_new_comment: 您刚收到来自网站的一条新评论 81 | comment_starts: --- 评论开始 --- 82 | comment_ends: --- 评论结束 --- 83 | from: 来自 84 | email: 邮件 85 | message: 信息 86 | closing_line: 亲切问候 87 | ps: 'P.S. All your comments are stored in the "Blog" section of Refinery under the "Comments" submenu should you ever want to view it later there.' 88 | shared: 89 | categories: 90 | title: 分类 91 | rss_feed: 92 | title: RSS源 93 | subscribe: 订阅 94 | posts: 95 | other: 其他博文 96 | created_at: '发表于 %{when}' 97 | read_more: 阅读更多 98 | comments: 99 | singular: 评论 100 | none: 没有评论 101 | archives: 档案 102 | categories: 103 | show: 104 | no_posts: 此处没有文章。 105 | posts: 106 | post: 107 | filed_in: 用户体验 108 | comment: 评论 109 | comments: 110 | by: '发布由 %{who}' 111 | time_ago: '%{time} 之前' 112 | thank_you: '感谢您的评论。' 113 | thank_you_moderated: '感谢您的评论。 您的信息已被列入等待审核队列,并会在短期内出现。' 114 | index: 115 | no_blog_articles_yet: 尚未发布文章。敬请关注。 116 | show: 117 | blog_home: 博客首页 118 | comments: 119 | title: 评论 120 | add: 发表评论 121 | other: 其他博文 122 | filed_in: 用户体验 123 | submit: 发送评论 124 | archive: 125 | blog_archive_for: '博客存档 %{date}' 126 | no_blog_articles_posted: '没有发布文章 %{date}。敬请关注。' 127 | -------------------------------------------------------------------------------- /spec/requests/refinery/blog/admin/comments_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Refinery 4 | module Blog 5 | module Admin 6 | describe Comment do 7 | refinery_login_with :refinery_user 8 | 9 | describe "#index" do 10 | context "when has no new unapproved comments" do 11 | before(:each) do 12 | subject.class.delete_all 13 | visit refinery.blog_admin_comments_path 14 | end 15 | 16 | it "should list no comments" do 17 | visit refinery.blog_admin_comments_path 18 | 19 | page.should have_content('There are no new comments') 20 | end 21 | end 22 | context "when has new unapproved comments" do 23 | let!(:blog_comment) { FactoryGirl.create(:blog_comment) } 24 | before(:each) { visit refinery.blog_admin_comments_path } 25 | 26 | it "should list comments" do 27 | page.should have_content(blog_comment.body) 28 | page.should have_content(blog_comment.name) 29 | end 30 | 31 | it "should allow me to approve a comment" do 32 | click_link "Approve this comment" 33 | 34 | page.should have_content("has been approved") 35 | end 36 | 37 | it "should allow me to reject a comment" do 38 | click_link "Reject this comment" 39 | 40 | page.should have_content("has been rejected") 41 | end 42 | end 43 | end 44 | 45 | describe "#approved" do 46 | context "when has no approved comments" do 47 | before(:each) do 48 | subject.class.delete_all 49 | visit refinery.approved_blog_admin_comments_path 50 | end 51 | 52 | it "should list no comments" do 53 | page.should have_content('There are no approved comments') 54 | end 55 | end 56 | context "when has approved comments" do 57 | let!(:blog_comment) do 58 | FactoryGirl.create(:blog_comment, :state => 'approved') 59 | end 60 | before(:each) { visit refinery.approved_blog_admin_comments_path } 61 | 62 | it "should list comments" do 63 | page.should have_content(blog_comment.body) 64 | page.should have_content(blog_comment.name) 65 | end 66 | 67 | it "should allow me to reject a comment" do 68 | click_link "Reject this comment" 69 | 70 | page.should have_content("has been rejected") 71 | end 72 | end 73 | end 74 | 75 | describe "#rejected" do 76 | context "when has no rejected comments" do 77 | before(:each) do 78 | subject.class.delete_all 79 | visit refinery.rejected_blog_admin_comments_path 80 | end 81 | 82 | it "should list no comments" do 83 | page.should have_content('There are no rejected comments') 84 | end 85 | end 86 | context "when has rejected comments" do 87 | let!(:blog_comment) do 88 | FactoryGirl.create(:blog_comment, :state => 'rejected') 89 | end 90 | before(:each) { visit refinery.rejected_blog_admin_comments_path } 91 | 92 | it "should list comments" do 93 | page.should have_content(blog_comment.body) 94 | page.should have_content(blog_comment.name) 95 | end 96 | 97 | it "should allow me to approve a comment" do 98 | click_link "Approve this comment" 99 | 100 | page.should have_content("has been approved") 101 | end 102 | end 103 | end 104 | 105 | describe "#show" do 106 | let!(:blog_comment) { FactoryGirl.create(:blog_comment) } 107 | before(:each) { visit refinery.blog_admin_comment_path(blog_comment) } 108 | it "should display the comment" do 109 | page.should have_content(blog_comment.body) 110 | page.should have_content(blog_comment.name) 111 | end 112 | it "should allow me to approve the comment" do 113 | click_link "Approve this comment" 114 | 115 | page.should have_content("has been approved") 116 | end 117 | end 118 | end 119 | end 120 | end 121 | end 122 | -------------------------------------------------------------------------------- /app/views/refinery/blog/admin/posts/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for [refinery, :blog_admin, @post] do |f| -%> 2 | <%= render "/refinery/admin/error_messages", 3 | :object => f.object, 4 | :include_object_name => true %> 5 | 6 | <%= render "/refinery/blog/admin/shared/locale_picker", 7 | :current_locale => Thread.current[:globalize_locale] if Refinery.i18n_enabled? %> 8 | 9 |
    10 | <%= f.label :title -%> 11 | <%= f.text_field :title, :class => 'larger widest' -%> 12 |
    13 | 14 |
    15 |
    16 |
      17 |
    • 18 | <%= link_to t('body', :scope => 'activerecord.attributes.refinery/blog_post'), "#page_part_body" %> 19 |
    • 20 |
    • 21 | <%= link_to t('teaser', :scope => 'activerecord.attributes.refinery/blog_post'), "#page_part_teaser" %> 22 |
    • 23 | <% Refinery::Blog.tabs.each_with_index do |tab, tab_index| %> 24 |
    • 25 | <%= link_to tab.name.titleize, "#custom_tab_#{tab_index}" %> 26 |
    • 27 | <% end %> 28 |
    29 | 30 |
    31 | <% part_index = -1 %> 32 | <%= render 'form_part', :f => f, :part_index => (part_index += 1) -%> 33 | <%= render 'teaser_part', :f => f, :part_index => (part_index += 1) if f.object.respond_to?(:custom_teaser) -%> 34 | <% Refinery::Blog.tabs.each_with_index do |tab, tab_index| %> 35 |
    36 | <%= render tab.partial, :f => f %> 37 |
    38 | <% end %> 39 |
    40 |
    41 |
    42 | 43 | <%= render '/refinery/admin/form_advanced_options_menu', :f => f %> 44 | 45 |
    46 | <%= f.label :tag_list, t('refinery.blog.shared.tags.title') -%> 47 | <%= f.text_field :tag_list, :class => 'larger' -%> 48 |
    49 | 50 | 106 | <%= render "/refinery/admin/form_actions", 107 | :f => f, 108 | :continue_editing => true, 109 | :delete_title => t('delete', :scope => 'refinery.blog.admin.posts.post') %> 110 | <% end -%> 111 | 112 | <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/backend') %> 113 | <% content_for :javascripts, javascript_include_tag('refinery/blog/backend') %> 114 | <%= render 'refinery/shared/admin/autocomplete', 115 | :dom_id => '#blog_post_tag_list', 116 | :url => refinery.tags_blog_admin_posts_url %> 117 | -------------------------------------------------------------------------------- /config/locales/cs.yml: -------------------------------------------------------------------------------- 1 | cs: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Upravit kategorii 11 | delete: Smazat kategorii 12 | index: 13 | no_items_yet: 'Nejsou zde žádné kategorie. Klikni na "%{create}" pro přidání první.' 14 | comments: 15 | approved: 'Komentář od "%{author}" byl schválen.' 16 | comment: 17 | view_live_html: 'Zobrazit živý náhled
    (otevře nové okno)' 18 | read: Zobrazit komentář 19 | reject: Zamítnout komentář 20 | approve: Schválit 21 | rejected: 'Komentář od "%{author}" byl zamítnut.' 22 | index: 23 | no_items_yet: 'Nejsou zde žádné %{type} komentáře.' 24 | show: 25 | comment: Komentář 26 | blog_post: Blog článek 27 | from: Odeslal 28 | date: Datum 29 | message: Komentář 30 | details: Detaily 31 | age: Věk 32 | actions: Akce 33 | back: Zpět na seznam komentářů 34 | reject: Zamítnout komentář 35 | approve: Schváliť komentář 36 | posts: 37 | form: 38 | toggle_advanced_options: Klikni pro přístup k nastavením meta tagů a menu 39 | published_at: Datum publikování 40 | index: 41 | no_items_yet: 'Nejsou žádné články na blogu. Klikni na "%{create}" pro přidání prvního.' 42 | uncategorized: 43 | no_items_yet: 'Nejsou žádné nekategorizované články.' 44 | post: 45 | view_live_html: 'Zobrazit článek
    (otevře jej v novém okně)' 46 | edit: Upravit článek 47 | delete: Smazat článek 48 | settings: 49 | notification_recipients: 50 | value: Poslat notifikaci pro 51 | explanation: 'Vždycky když někdo přidá komentář, Refinery zašle oznámení.' 52 | hint: 'Vždycky když někdo přidá komentář, Refinery ti pošle oznámení.' 53 | example: "Zadej tvou emailovou adresu(y) jako například: jack@work.com, jill@office.com" 54 | updated: 'Seznam příjemců notifikací "%{recipients}"' 55 | submenu: 56 | categories: 57 | title: Kategorie 58 | manage: Spravovat 59 | new: Nová kategórie 60 | comments: 61 | title: Komentáře 62 | title_with_count: 'Komentáře (%{new_count} nových)' 63 | new: Nový 64 | unmoderated: Nový 65 | approved: Schválený 66 | rejected: Zamítnutý 67 | posts: 68 | title: Články 69 | manage: Spravovat články 70 | new: Vytvořit nový článek 71 | uncategorized: Nekategorizované články 72 | settings: 73 | title: Nastavení 74 | moderation: Moderování 75 | update_notified: Upravit seznam notifikovaných 76 | comments: Komentáře 77 | comment_mailer: 78 | notification: 79 | greeting: Ahoj 80 | you_recieved_new_comment: Máš nový komentář na stránce 81 | comment_starts: --- začátek komentáře --- 82 | comment_ends: --- konec komentáře --- 83 | from: Od 84 | email: Email 85 | message: Zpráva 86 | closing_line: S pozdravem 87 | ps: 'P.S. Všechny komentáře jsou uloženy v sekci "Blog" pod záložkou "Komentáře" v případě pokud by je bylo třeba zobrazit později.' 88 | shared: 89 | categories: 90 | title: Kategorie 91 | rss_feed: 92 | title: RSS zdroj článků 93 | subscribe: Přihlásit k odběru 94 | posts: 95 | other: Další články 96 | created_at: 'Publikován %{when}' 97 | read_more: Celý článek 98 | comments: 99 | singular: komentář 100 | none: žiadne komentáře 101 | archives: Archiv 102 | categories: 103 | show: 104 | no_posts: Nejsou zde žádné články. 105 | posts: 106 | post: 107 | filed_in: Podaný 108 | comment: komentář 109 | comments: 110 | by: 'Odeslal %{who}' 111 | time_ago: '%{time} zpět' 112 | thank_you: 'Díky za komentář.' 113 | thank_you_moderated: 'Děkujeme za Váš komentář. Vaše zpráva čeká na schválení a objeví se v nejbližší době.' 114 | index: 115 | no_blog_articles_yet: Právě nejsou žádné články na blogu. Zůstaňte naladěni. 116 | show: 117 | blog_home: Hlavní stránka blogu 118 | comments: 119 | title: Komentáře 120 | add: Přidat komentář 121 | other: Další články 122 | filed_in: Podaný 123 | submit: Odeslat komentář 124 | archive: 125 | blog_archive_for: 'Blog archiv pro %{date}' 126 | no_blog_articles_posted: 'Nejsou žádné články publikované %{date}.' 127 | -------------------------------------------------------------------------------- /config/locales/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: ブログ 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: このカテゴリを編集 11 | delete: このカテゴリを削除 12 | index: 13 | no_items_yet: 'まだカテゴリが一つも登録されていません。「%{create}」をクリックし、カテゴリを作成して下さい。' 14 | comments: 15 | approved: '「%{author}さん」の投稿が承認されました。' 16 | comment: 17 | view_live_html: 'このコメントを見る
    (新規ウインドウに開かれます)' 18 | read: このコメントを読む 19 | reject: このコメントを却下する 20 | approve: このコメントを承認する 21 | rejected: '「%{author}」によるコメントが却下されました。' 22 | index: 23 | no_items_yet: '%{type}に関するコメントがありません。' 24 | show: 25 | comment: コメント 26 | blog_post: 投稿 27 | from: 投稿者 28 | date: 投稿時刻 29 | message: コメント 30 | details: 詳細 31 | age: 投稿から 32 | actions: アクション 33 | back: 全てのコメントに戻る 34 | reject: このコメントを却下する 35 | approve: このコメントを承認する 36 | posts: 37 | form: 38 | toggle_advanced_options: メタタグの設定メニューをアクセスするにはここをクリックして下さい 39 | published_at: 公開時刻 40 | custom_url: カスタムURL 41 | custom_url_help: 投稿のURLをここのテキストとして登録する。 42 | copy_body: 本文を短説明文にコピーする 43 | copy_body_help: 短説明文として本文を引用します。短説明文を空にすると自動的に反映されます。 44 | index: 45 | no_items_yet: '投稿がありません。「%{create}」をクリックし、作成して下さい。' 46 | uncategorized: 47 | no_items_yet: '未分類の投稿がありませす。' 48 | post: 49 | view_live_html: 'この投稿を見る。
    (新規ウィンドウに開かれます)' 50 | edit: この投稿を編集する 51 | delete: この投稿を削除する 52 | settings: 53 | notification_recipients: 54 | value: 通知の受信者 55 | explanation: '投稿にコメントが出される度にRefineryが通知を送れます。' 56 | hint: 'コメントが追加されたらメールで通知されます。' 57 | example: "複数のメールアドを登録することが出来ます。入力例: jack@work.com, jill@office.com" 58 | updated: '通知受信者の「%{recipients}」に通知が送信されました。' 59 | submenu: 60 | categories: 61 | title: カテゴリ 62 | manage: 管理 63 | new: 新規カテゴリ作成 64 | comments: 65 | title: コメント 66 | title_with_count: 'コメント (新規%{new_count}通)' 67 | new: 新規 68 | unmoderated: 新規 69 | approved: 承認された 70 | rejected: 却下された 71 | posts: 72 | title: 投稿 73 | manage: 投稿管理 74 | new: 新規投稿 75 | uncategorized: 未分類 76 | settings: 77 | title: 設定 78 | moderation: 管理する 79 | update_notified: 通知者を変更・更新する 80 | comments: コメント 81 | comment_mailer: 82 | notification: 83 | greeting: こんにちわ 84 | you_recieved_new_comment: サイトに新規コメントが投稿されました。 85 | comment_starts: --- コメント開始 --- 86 | comment_ends: --- コメント終了 --- 87 | from: 差出人 88 | email: メール 89 | message: メッセージ 90 | closing_line: 以上、 91 | ps: '追記: 全てのコメントを見るにはRefineryブログの「コメント」に参照して下さい。' 92 | shared: 93 | categories: 94 | title: カテゴリ 95 | rss_feed: 96 | title: RSSフィード 97 | subscribe: フィードを登録する 98 | posts: 99 | other: 他の投稿 100 | created_at: '%{when}に投稿' 101 | read_more: もっと読む 102 | comments: 103 | singular: コメント 104 | none: コメントが未登録 105 | archives: アーカイブ 106 | tags: 107 | title: "タグ" 108 | categories: 109 | show: 110 | no_posts: 投稿がありません。 111 | posts: 112 | post: 113 | filed_in: に分類されている 114 | comment: コメント 115 | comments: 116 | by: '%{who}より' 117 | time_ago: '%{time}前に' 118 | thank_you: 'コメントをありがとうございます。' 119 | thank_you_moderated: 'コメントをありがとうございます。コメントが承認待ちとされています。承認次第公開されます。' 120 | index: 121 | no_blog_articles_yet: ブログ記事がまだ投稿されてません。 122 | show: 123 | blog_home: ブログ・ホーム 124 | comments: 125 | title: コメント 126 | add: コメントを投稿 127 | other: 他のブログ投稿 128 | filed_in: に分類されている 129 | tagged: とのタグが付いている 130 | submit: コメントを送信 131 | name: 名前 132 | email: メール 133 | message: メッセージ 134 | by: '投稿者:' 135 | tagged: 136 | no_blog_articles_yet: ブログ記事がまだ投稿されてません。 137 | posts_tagged: 投稿タグ 138 | archive: 139 | blog_archive_for: '%{date}搭載のブログ記事' 140 | no_blog_articles_posted: '%{date}付のブログ記事が投稿されてません。' 141 | activerecord: 142 | models: 143 | refinery/blog/category: カテゴリ 144 | refinery/blog/comment: コメント 145 | refinery/blog/post: 投稿 146 | attributes: 147 | refinery/blog/category: 148 | title: 題名 149 | refinery/blog/comment: 150 | name: 名前 151 | email: メール 152 | message: メッセージ 153 | refinery/blog/post: 154 | title: 題名 155 | body: 本文 156 | teaser: 短紹介文 157 | -------------------------------------------------------------------------------- /config/locales/ru.yml: -------------------------------------------------------------------------------- 1 | ru: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Блог 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Редактировать эту категорию 11 | delete: Удалить эту категорию навсегда 12 | index: 13 | no_items_yet: 'Категории пока не созданы. Нажмите "%{create}", чтобы добавить вашу первую категорию.' 14 | comments: 15 | approved: 'Комментарий от "%{author}" был опубликован.' 16 | comment: 17 | view_live_html: Посмотреть комментарий на сайте
    (откроется в новом окне) 18 | read: Прочитать комментарий 19 | reject: Отклонить комментарий 20 | approve: Принять комментарий 21 | rejected: 'Комментарий от "%{author}" был отклонен.' 22 | index: 23 | no_items_yet: '%{type} комментарии: отсутствуют.' 24 | show: 25 | comment: Комментарий 26 | blog_post: Запись в блоге 27 | from: Опубликовал 28 | date: Опубликовано 29 | message: Комментарий 30 | details: Детали 31 | age: Возраст 32 | actions: Действия 33 | back: Вернуться к списку комментариев 34 | reject: Отклонить этот комментарий 35 | approve: Принять этот комментарий 36 | posts: 37 | form: 38 | toggle_advanced_options: 'Нажмите, чтобы получить доступ к настройкам мета-тегов и меню' 39 | published_at: Дата публикации 40 | index: 41 | no_items_yet: 'Записи в блоге отстутствуют. Нажмите "%{create}", чтобы добавить первую запись.' 42 | uncategorized: 43 | no_items_yet: 'Записи без категорий отсутствуют.' 44 | post: 45 | view_live_html: Посмотреть запись на сайте
    (откроется в новом окне) 46 | edit: Редактировать запись 47 | delete: Удалить запись 48 | settings: 49 | notification_recipients: 50 | value: Отправлять уведомления 51 | explanation: 'При появлении новых комментариев Refinery пришлет уведомление на email.' 52 | hint: 'При появлении новых комментариев Refinery пришлет уведомление на email.' 53 | example: "Введите адреса эл. почты, например: jack@work.com, jill@office.com" 54 | updated: 'Получателем уведомлений является "%{recipients}"' 55 | submenu: 56 | categories: 57 | title: Категории 58 | manage: Редактировать категории 59 | new: Создать новую категорию 60 | comments: 61 | title: Комментарии 62 | title_with_count: 'Комментарии (%{new_count} новых)' 63 | new: Новые 64 | unmoderated: Новые 65 | approved: Принятые 66 | rejected: Отклоненные 67 | posts: 68 | title: Записи 69 | manage: Редактировать записи 70 | new: Создать новую запись 71 | uncategorized: Записи без категорий 72 | settings: 73 | title: Настройки 74 | moderation: Модерирование 75 | update_notified: Настроить уведомления 76 | comments: Комментарии 77 | comment_mailer: 78 | notification: 79 | greeting: Здравствуйте 80 | you_recieved_new_comment: Новый комментарий опубликован на вашем сайте. 81 | comment_starts: --- начало комментария --- 82 | comment_ends: --- конец комментария --- 83 | from: От 84 | email: Эл. почта 85 | message: Сообщение 86 | closing_line: С уважением 87 | ps: P.S. Все комментарии находятся в разделе "Блог" Refinery CMS в подменю "Комментарии". 88 | shared: 89 | categories: 90 | title: Категории 91 | rss_feed: 92 | title: RSS-лента 93 | subscribe: Подписаться 94 | posts: 95 | other: Другие записи 96 | created_at: 'Опубликовано %{when}' 97 | read_more: Читать дальше 98 | comments: 99 | singular: комментарий 100 | none: нет комментариев 101 | archives: Архивы 102 | categories: 103 | show: 104 | no_posts: Записей пока нет. 105 | posts: 106 | post: 107 | filed_in: Категория 108 | comment: комментарий 109 | comments: 110 | by: 'Опубликовал %{who}' 111 | time_ago: '%{time} назад' 112 | thank_you: 'Спасибо за комментарий.' 113 | thank_you_moderated: 'Спасибо за комментарий. Ваше сообщение модерируется и скоро появится на сайте.' 114 | index: 115 | no_blog_articles_yet: Пока ни одной записи не опубликовано. Следите за новостями. 116 | show: 117 | blog_home: Вернуться к списку записей 118 | comments: 119 | title: Комментарии 120 | add: Написать комментарий 121 | other: Другие записи 122 | filed_in: Категория 123 | submit: Отправить комментарий 124 | archive: 125 | blog_archive_for: 'Архив %{date}' 126 | no_blog_articles_posted: 'Ни одной записи за %{date} не опубликовано. Следите за новостями.' 127 | -------------------------------------------------------------------------------- /config/locales/pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Edytuj tą kategorię 11 | delete: Usuń na zawsze 12 | index: 13 | no_items_yet: 'W tej chwili nie ma żadnych kategorii. Kliknij "%{create}" aby dodać pierwszą.' 14 | comments: 15 | approved: 'Komentarz "%{author}" został zaakceptowany.' 16 | comment: 17 | view_live: 'Zobacz ten komentarz na żywo
    (otwiera w nowym oknie)' 18 | read: Pokaż ten komentarz 19 | reject: Odrzuć ten komentarz 20 | approve: Zaakceptuj ten komentarz 21 | rejected: 'Komentarz "%{author}" został odrzucony.' 22 | index: 23 | no_items_yet: 'Nie ma więcej komentarzy typu "%{type}".' 24 | show: 25 | comment: Komentarz 26 | blog_post: Post 27 | from: Autor 28 | date: Data 29 | message: Komentarz 30 | details: Szczegóły 31 | age: Wiek 32 | actions: Akcje 33 | back: Powrót do listy komentarzy 34 | reject: Odrzuć ten komentarz 35 | approve: Zaakceptuj ten komentarz 36 | posts: 37 | form: 38 | toggle_advanced_options: 'Kliknij, aby zarządzać meta-ustawieniami' 39 | published_at: Data publikacji 40 | index: 41 | no_items_yet: 'Na blogu nie ma jeszcze żadnych wpisów. Kliknij "%{create}" aby dodać pierwszy post.' 42 | uncategorized: 43 | no_items_yet: 'Brak nieskategoryzowanych wpisów na blogu.' 44 | post: 45 | view_live: 'Zobacz ten post na żywo
    (otwiera w nowym oknie)' 46 | edit: Edytuj ten post 47 | delete: Usuń ten post na zawsze 48 | settings: 49 | notification_recipients: 50 | value: Powiadomienia wysyłane do 51 | explanation: 'Gdy zostanie dodany nowy komentarz, system wyśle powiadomienie przez e-mail.' 52 | hint: 'Gdy zostanie dodany nowy komentarz, system wyśle powiadomienie przez e-mail.' 53 | example: 'Podaj adresy e-mail oddzielone przecinkiem, np: jack@work.com, jill@office.com' 54 | updated: 'Powiadomienia będą wysyłane do "%{recipients}"' 55 | submenu: 56 | categories: 57 | title: Kategorie 58 | manage: Zarządzaj kategoriami 59 | new: Dodaj nową kategorię 60 | comments: 61 | title: Komentarze 62 | title_with_count: 'Komentarze (%{new_count} nowych)' 63 | new: Nowe 64 | unmoderated: Nowe 65 | approved: Zaakceptowane 66 | rejected: Odrzucone 67 | posts: 68 | title: Posty 69 | manage: Zarządzaj postami 70 | new: Dodaj nowy post 71 | uncategorized: Posty bez kategorii 72 | settings: 73 | title: Ustawienia 74 | moderation: Wł./wył. moderację 75 | update_notified: Powiadamianie przez e-mail 76 | comments: Komentarze 77 | comment_mailer: 78 | notification: 79 | greeting: Witaj:) 80 | you_recieved_new_comment: Właśnie otrzymałeś nowy komentarz na swojej stronie! 81 | comment_starts: --- początek komentarza --- 82 | comment_ends: --- koniec komentarza --- 83 | from: Od 84 | email: Email 85 | message: Treść 86 | closing_line: Pozdrawiamy 87 | ps: 'P.S. Wszystkie komentarze przechowywane są w panelu zarządzania, w sekcji "Blog" i podmenu "Komentarze". ' 88 | shared: 89 | categories: 90 | title: Kategorie 91 | rss_feed: 92 | title: RSS Feed 93 | subscribe: Sukskrybuj 94 | posts: 95 | other: Pozostałe posty 96 | created_at: 'Data: %{when}' 97 | read_more: Więcej 98 | comments: 99 | singular: komentarz 100 | none: brak komentarzy 101 | archives: Archiwum 102 | categories: 103 | show: 104 | no_posts: Nie ma jeszcze żadnych postów. 105 | posts: 106 | post: 107 | filed_in: 'kategorie:' 108 | comment: komentarz 109 | comments: 110 | by: 'Autor: %{who}' 111 | time_ago: '%{time} temu' 112 | thank_you: 'Dziękujemy za Twój komentarz.' 113 | thank_you_moderated: 'Dziękujemy za Twój komentarz. Został on przekazany do moderacji i niedługo pojawi się na stronie.' 114 | index: 115 | no_blog_articles_yet: W tej chwili nie ma jeszcze żadnych postów. Cierpliwości:) 116 | show: 117 | blog_home: Blog 118 | comments: 119 | title: Komentarze 120 | add: Dodaj komentarz 121 | other: Pozostałe wpisy 122 | filed_in: 'kategorie:' 123 | submit: Dodaj komentarz 124 | archive: 125 | blog_archive_for: 'Archiwum dla %{date}' 126 | no_blog_articles_posted: 'Brak wpisów dla daty %{date}.' 127 | activerecord: 128 | attributes: 129 | refinery/blog/comment: 130 | name: "Imię" 131 | email: "Email" 132 | message: "Treść" 133 | -------------------------------------------------------------------------------- /config/locales/es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Editar esta categoría 11 | delete: Borrar esta categoría para siempre 12 | index: 13 | no_items_yet: 'Todavía no hay categorías. Haz click en "%{create}" para añadir la primera.' 14 | comments: 15 | approved: 'El comentario de "%{author}" ha sido aprobado.' 16 | comment: 17 | view_live_html: 'Ver este comentario
    (se abrirá en una ventana nueva)' 18 | read: Leer este comentario 19 | reject: Rechazar este comentario 20 | approve: Aprovar este comentario 21 | rejected: 'El comentario de "%{author}" ha sido rechazado.' 22 | index: 23 | no_items_yet: 'No hay comentarios %{type}.' 24 | show: 25 | comment: Comentario 26 | blog_post: Entrada en el Blog 27 | from: Enviado por 28 | date: Enviado el 29 | message: Mensaje 30 | details: Detalles 31 | age: Edad 32 | actions: Acciones 33 | back: Volver a todos los comentarios 34 | reject: Rechazar este comentario 35 | approve: Aprovar este comentario 36 | posts: 37 | form: 38 | toggle_advanced_options: Click para acceder a las opciones de menú y etiquetas 39 | published_at: Fecha de publicación 40 | index: 41 | no_items_yet: 'Aún no hay entradas en el Blog. Haz click en "%{create}" para añadir el primero' 42 | uncategorized: 43 | no_items_yet: 'No hay entradas en el Blog sin categoría.' 44 | post: 45 | view_live_html: 'Ver entrada
    (se abrirá en una ventana nueva)' 46 | edit: Editar esta entrada 47 | delete: Eliminar esta entrada para siempre 48 | settings: 49 | notification_recipients: 50 | value: Enviar notificaciones a 51 | explanation: 'Cada vez que alguien comente en una entrada, Refinery envia un email para avisar de que hay un nuevo comentario.' 52 | hint: 'Refinery te avisará con un email cada vez que haya un nuevo comentario en tu Blog.' 53 | example: 'Si deseas que las notificaciones lleguen a más de una cuenta, puedes usar comas para separarlas (pepe@direccionpersonal.com, jose@direccionlaboral.com, ...)' 54 | updated: 'Las notifiaciones han sido enviadas a "%{recipients}"' 55 | submenu: 56 | categories: 57 | title: Categorías 58 | manage: Gestionar 59 | new: Añadir categoría 60 | comments: 61 | title: Comentarios 62 | title_with_count: 'Comentarios (%{new_count} nuevos)' 63 | new: Nuevo 64 | unmoderated: Nuevos 65 | approved: Aprobados 66 | rejected: Rechazados 67 | posts: 68 | title: Entradas 69 | manage: Gestionar entradas 70 | new: Crear nueva entrada 71 | uncategorized: Entradas sin categoría 72 | settings: 73 | title: Configuración 74 | moderation: Moderación 75 | update_notified: '¿Quién recibe las notificaciones?' 76 | comments: Comentarios 77 | comment_mailer: 78 | notification: 79 | greeting: Hola 80 | you_recieved_new_comment: Han hecho un nuevo comentario en una de las entradas de tu Blog. 81 | comment_starts: --- inicio comentario --- 82 | comment_ends: --- fin comentario --- 83 | from: De 84 | email: Email 85 | message: Mensaje 86 | closing_line: Saludos 87 | ps: 'P.D. Recuerda que puedes ver todos los comentarios en el apartado "Comentarios" dentro de la sección "Blog".' 88 | shared: 89 | categories: 90 | title: Categorías 91 | rss_feed: 92 | title: Feed RSS 93 | subscribe: Suscribirse 94 | posts: 95 | other: Otras entradas 96 | created_at: 'Enviado hace %{when}' 97 | read_more: Leer más 98 | comments: 99 | singular: comentario 100 | none: no hay comentarios 101 | archives: Archivos 102 | categories: 103 | show: 104 | no_posts: Todavía no hay entradas. 105 | posts: 106 | post: 107 | filed_in: Archivado en 108 | comment: comentario 109 | comments: 110 | by: 'Enviado por %{who}' 111 | time_ago: 'Hace %{time}' 112 | thank_you: Gracias por tu comentario. 113 | thank_you_moderated: 'Gracias por tu comentario. Ha sido enviado a la cola de moderación y, si lo aprobamos, aparecerá dentro de poco.' 114 | index: 115 | no_blog_articles_yet: 'Todavía no hay artículos. ¡Pero vuelve pronto!' 116 | show: 117 | blog_home: 'Página principal del Blog' 118 | comments: 119 | title: Comentarios 120 | add: 'Envía tu comentario' 121 | other: Otros posts 122 | filed_in: Archivado en 123 | submit: Enviar comentario 124 | archive: 125 | blog_archive_for: 'Archivo del blog en %{date}' 126 | no_blog_articles_posted: 'No hay entradas publicadas en %{date}.' 127 | -------------------------------------------------------------------------------- /config/locales/pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Editar esta categoria 11 | delete: Apagar esta categoria para sempre 12 | index: 13 | no_items_yet: 'Não há categorias ainda. Clique em "%{create}" para adicionar a primeira categoria.' 14 | comments: 15 | approved: 'O comentário de "%{author}" foi aprovado.' 16 | comment: 17 | view_live_html: 'Ver este comentário
    (será aberto em outra janela)' 18 | read: Ler este comentário 19 | reject: Rejeitar este comentário 20 | approve: Aprovar este comentário 21 | rejected: 'O comentário de "%{author}" foi rejeitado.' 22 | index: 23 | no_items_yet: 'Não há %{type} comentários.' 24 | show: 25 | comment: Comentário 26 | blog_post: Post 27 | from: Postado por 28 | date: Postado em 29 | message: Comentário 30 | details: Detalhes 31 | age: Idade 32 | actions: Ações 33 | back: Voltar para todos os comentários 34 | reject: Rejeitar este comentário 35 | approve: Aprovar este comentário 36 | posts: 37 | form: 38 | toggle_advanced_options: Clique aqui para acessar as configurações de meta tag e menu 39 | published_at: Data de publicação 40 | index: 41 | no_items_yet: 'Ainda não há Posts no Blog. Clique em "%{create}" para adicionar o primeiro post.' 42 | uncategorized: 43 | no_items_yet: 'Ainda não há posts sem categoria.' 44 | post: 45 | view_live_html: 'Ver este comentário
    (será aberto em outra janela)' 46 | edit: Editar este post 47 | delete: Remover esse post para sempre 48 | settings: 49 | notification_recipients: 50 | value: Enviar notificações para 51 | explanation: 'Cada vez que alguém comenta em um post no blog, é enviado um e-mail para informar que há um novo comentário.' 52 | hint: 'Quando um novo comentário é adicionado, será enviado uma notificação por e-mail para você.' 53 | example: 'Entre com o(s) seu(s) endereço(s) de email, como: jack@work.com, jill@office.com' 54 | updated: 'As notificações foram enviadas para "%{recipients}"' 55 | submenu: 56 | categories: 57 | title: Categorias 58 | manage: Gerenciar 59 | new: Criar nova categoria 60 | comments: 61 | title: Comentários 62 | title_with_count: 'Comentários (%{new_count} novos)' 63 | new: Novo 64 | unmoderated: Novo 65 | approved: Aprovado 66 | rejected: Rejeitado 67 | posts: 68 | title: Posts 69 | manage: Gerenciar posts 70 | new: Criar novo post 71 | uncategorized: Posts sem categoria 72 | settings: 73 | title: Configurações 74 | moderation: Moderação 75 | update_notified: Quem receberá a notificação? 76 | comments: Comentários 77 | comment_mailer: 78 | notification: 79 | greeting: Olá 80 | you_recieved_new_comment: Você acaba de receber um novo comentário em seu site. 81 | comment_starts: --- Início do comentário --- 82 | comment_ends: --- Fim do comentário --- 83 | from: De 84 | email: Email 85 | message: Mensagem 86 | closing_line: Atenciosamente 87 | ps: 'P.S. Lembre-se que você pode ver todos os comentários em "Comentários" dentro da seção "Blog".' 88 | shared: 89 | categories: 90 | title: Categorias 91 | rss_feed: 92 | title: Feed RSS 93 | subscribe: Assinar 94 | posts: 95 | other: Últimos posts 96 | created_at: 'Postado em %{when}' 97 | read_more: Continue lendo... 98 | comments: 99 | singular: comentário 100 | none: não há comentários 101 | archives: Arquivos 102 | tags: 103 | title: Tags 104 | categories: 105 | show: 106 | no_posts: Não há posts aqui ainda. 107 | posts: 108 | comment: commentário 109 | comments: 110 | by: 'Postado por %{who}' 111 | time_ago: '%{time} atrás' 112 | thank_you: 'Obrigado por comentar.' 113 | thank_you_moderated: 'Obrigado por comentar. Sua mensagem foi colocada na fila de moderação e será exibida em breve.' 114 | index: 115 | no_blog_articles_yet: Ainda não há artigos postados no blog. 116 | show: 117 | blog_home: Blog Home 118 | comments: 119 | title: Comentários 120 | add: Fazer um comentário 121 | other: Outros posts 122 | filed_in: Arquivado em 123 | submit: Enviar comentário 124 | archive: 125 | blog_archive_for: 'Arquivo do blog em %{date}' 126 | no_blog_articles_posted: 'Não há arquivos do blog em %{date}.' 127 | post: 128 | filed_in: Arquivado em 129 | activerecord: 130 | attributes: 131 | refinery/blog/post: 132 | title: Título 133 | body: Corpo 134 | refinery/blog/comment: 135 | name: Nome 136 | message: Mensagem 137 | -------------------------------------------------------------------------------- /config/locales/nl.yml: -------------------------------------------------------------------------------- 1 | nl: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Bewerk deze categorie 11 | delete: Verwijder deze categorie definitief 12 | index: 13 | no_items_yet: 'Er zijn momenteel geen categorien. Klik op "%{create}" om uw eerste categorie toe te voegen.' 14 | comments: 15 | approved: 'De reactie van "%{author}" is goedgekeurd.' 16 | comment: 17 | view_live_html: 'Bekijk deze reactie op de website
    (opent in een nieuw venster)' 18 | read: Lees deze reactie 19 | reject: Keur deze reactie af 20 | approve: Keur deze reactie goed 21 | rejected: 'De reactie van "%{author}" is afgekeurd.' 22 | index: 23 | no_items_yet: 'Er zijn geen %{type} reacties.' 24 | show: 25 | comment: Reactie 26 | blog_post: Blogpost 27 | from: Gepost door 28 | date: Gepost op 29 | message: Reactie 30 | details: Details 31 | age: Leeftijd 32 | actions: Acties 33 | back: Terug naar alle reacties 34 | reject: Keur deze reactie af 35 | approve: Keur deze reactie goed 36 | posts: 37 | form: 38 | toggle_advanced_options: Klik voor toegang tot meta tag instellingen en menu opties 39 | published_at: Publicatiedatum 40 | index: 41 | no_items_yet: 'Er zijn momenteel geen blogposts. Klik op "%{create}" om uw eerste blogpost toe te voegen.' 42 | uncategorized: 43 | no_items_yet: 'Er zijn geen ongecategoriseerde blogposts.' 44 | post: 45 | view_live_html: 'Bekijk deze blogpost op de website
    (opent in een nieuw venster)' 46 | edit: Bewerk deze blogpost 47 | delete: Verwijder deze blogpost definitief 48 | settings: 49 | notification_recipients: 50 | value: Stuur notificaties naar 51 | explanation: 'Bij elke nieuwe reactie op een blogpost stuurt Refinery u een e-mail om dit te melden.' 52 | hint: 'Als er een reactie is toegevoegd stuurt Refinery een e-mail notificatie naar u.' 53 | example: "Voer uw e-mailadres(sen) in, bijvoorbeeld: jack@work.com, jill@office.com" 54 | updated: 'De ontvanger(s) van notificaties is/zijn gewijzigd naar "%{recipients}"' 55 | submenu: 56 | categories: 57 | title: Categorien 58 | manage: Beheren 59 | new: Voeg een nieuwe categorie toe 60 | comments: 61 | title: Reacties 62 | title_with_count: 'Reacties (%{new_count} nieuwe)' 63 | new: Nieuw 64 | unmoderated: Nieuw 65 | approved: Goedgekeurd 66 | rejected: Afgekeurd 67 | posts: 68 | title: Posts 69 | manage: Beheer posts 70 | new: Voeg een nieuwe post toe 71 | uncategorized: Ongecategoriseerde posts 72 | settings: 73 | title: Instellingen 74 | moderation: Stuur notificaties 75 | update_notified: Wijzig wie notificaties ontvangt 76 | comments: Reacties 77 | teasers: Teasers 78 | comment_mailer: 79 | notification: 80 | greeting: Hallo 81 | you_recieved_new_comment: Er is zojuist een reactie geplaatst op uw website. 82 | comment_starts: --- begin reactie --- 83 | comment_ends: --- einde reactie --- 84 | from: Van 85 | email: E-mail 86 | message: Bericht 87 | closing_line: Met vriendelijke groet 88 | ps: 'P.S. Alle reacties worden opgeslagen in de "Blog" sectie van Refinery onder het submenu "Comments", voor als u deze reacties later wilt bekijken.' 89 | shared: 90 | categories: 91 | title: Categorien 92 | rss_feed: 93 | title: RSS Feed 94 | subscribe: Aanmelden 95 | posts: 96 | other: Andere posts 97 | created_at: 'Gepost op %{when}' 98 | read_more: Lees verder 99 | comments: 100 | singular: Reactie 101 | none: Geen reacties 102 | archives: Archief 103 | tags: 104 | title: "Tags" 105 | categories: 106 | show: 107 | no_posts: Er zijn momenteel geen posts. 108 | posts: 109 | post: 110 | filed_in: Toegevoegd aan 111 | comment: Reactie 112 | comments: 113 | by: 'Gepost door %{who}' 114 | time_ago: '%{time} geleden' 115 | thank_you: 'Bedankt voor uw reactie.' 116 | thank_you_moderated: 'Bedankt voor uw reactie. Uw reactie is in de wachtrij geplaatst en zal binnenkort verschijnen.' 117 | index: 118 | no_blog_articles_yet: Er zijn momenteel nog geen blogposts. Neem regelmatig een kijkje. 119 | show: 120 | blog_home: Blog Home 121 | comments: 122 | title: Reacties 123 | add: Plaats een reactie 124 | other: Andere blogposts 125 | filed_in: Toegevoegd aan 126 | tagged: Tagged 127 | submit: Verstuur reactie 128 | tagged: 129 | no_blog_articles_yet: Er zijn momenteel nog geen blogposts. Neem regelmatig een kijkje. 130 | archive: 131 | blog_archive_for: 'Blog archief voor %{date}' 132 | no_blog_articles_posted: 'Er zijn geen blogposts voor %{date}. Neem regelmatig een kijkje.' 133 | -------------------------------------------------------------------------------- /app/models/refinery/blog/post.rb: -------------------------------------------------------------------------------- 1 | require 'acts-as-taggable-on' 2 | require 'seo_meta' 3 | 4 | module Refinery 5 | module Blog 6 | class Post < ActiveRecord::Base 7 | 8 | translates :title, :body, :custom_url, :custom_teaser, :slug, :include => :seo_meta 9 | 10 | extend FriendlyId 11 | friendly_id :friendly_id_source, :use => [:slugged, :globalize] 12 | 13 | is_seo_meta if self.table_exists? 14 | 15 | default_scope :order => 'published_at DESC' 16 | 17 | belongs_to :author, :class_name => 'Refinery::User', :foreign_key => :user_id, :readonly => true 18 | 19 | has_many :comments, :dependent => :destroy, :foreign_key => :blog_post_id 20 | acts_as_taggable 21 | 22 | has_many :categorizations, :dependent => :destroy, :foreign_key => :blog_post_id 23 | has_many :categories, :through => :categorizations, :source => :blog_category 24 | 25 | acts_as_indexed :fields => [:title, :body] 26 | 27 | validates :title, :presence => true, :uniqueness => true 28 | validates :body, :presence => true 29 | validates :published_at, :author, :presence => true 30 | 31 | validates :source_url, :url => { :if => 'Refinery::Blog.validate_source_url', 32 | :update => true, 33 | :allow_nil => true, 34 | :allow_blank => true, 35 | :verify => [:resolve_redirects]} 36 | 37 | attr_accessible :title, :body, :custom_teaser, :tag_list, :draft, :published_at, :custom_url, :author 38 | attr_accessible :browser_title, :meta_keywords, :meta_description, :user_id, :category_ids 39 | attr_accessible :source_url, :source_url_title 40 | attr_accessor :locale 41 | 42 | 43 | class Translation 44 | is_seo_meta 45 | attr_accessible :browser_title, :meta_description, :meta_keywords, :locale 46 | end 47 | 48 | self.per_page = Refinery::Blog.posts_per_page 49 | 50 | def next 51 | self.class.next(self) 52 | end 53 | 54 | def prev 55 | self.class.previous(self) 56 | end 57 | 58 | def live? 59 | !draft and published_at <= Time.now 60 | end 61 | 62 | def friendly_id_source 63 | custom_url.presence || title 64 | end 65 | 66 | class << self 67 | 68 | # Wrap up the logic of finding the pages based on the translations table. 69 | def with_globalize(conditions = {}) 70 | conditions = {:locale => ::Globalize.locale}.merge(conditions) 71 | globalized_conditions = {} 72 | conditions.keys.each do |key| 73 | if (translated_attribute_names.map(&:to_s) | %w(locale)).include?(key.to_s) 74 | globalized_conditions["#{self.translation_class.table_name}.#{key}"] = conditions.delete(key) 75 | end 76 | end 77 | # A join implies readonly which we don't really want. 78 | joins(:translations).where(globalized_conditions).where(conditions).readonly(false) 79 | end 80 | 81 | def find_by_slug_or_id(slug_or_id) 82 | if slug_or_id.friendly_id? 83 | find_by_slug(slug_or_id) 84 | else 85 | find(slug_or_id) 86 | end 87 | end 88 | 89 | def by_month(date) 90 | where(:published_at => date.beginning_of_month..date.end_of_month).with_globalize 91 | end 92 | 93 | def by_archive(date) 94 | Refinery.deprecate("Refinery::Blog::Post.by_archive(date)", {:replacement => "Refinery::Blog::Post.by_month(date)", :when => 2.2 }) 95 | by_month(date) 96 | end 97 | 98 | def by_year(date) 99 | where(:published_at => date.beginning_of_year..date.end_of_year).with_globalize 100 | end 101 | 102 | def published_dates_older_than(date) 103 | published_before(date).with_globalize.pluck(:published_at) 104 | end 105 | 106 | def recent(count) 107 | live.limit(count).with_globalize 108 | end 109 | 110 | def popular(count) 111 | unscoped.order("access_count DESC").limit(count).with_globalize 112 | end 113 | 114 | def previous(item) 115 | published_before(item.published_at).with_globalize.first 116 | end 117 | 118 | def uncategorized 119 | live.includes(:categories).where(Refinery::Categorization.table_name => { :blog_category_id => nil }).with_globalize 120 | end 121 | 122 | def next(current_record) 123 | where(["published_at > ? and draft = ?", current_record.published_at, false]).with_globalize.first 124 | end 125 | 126 | def published_before(date=Time.now) 127 | where("published_at < ? and draft = ?", date, false).with_globalize 128 | end 129 | alias_method :live, :published_before 130 | 131 | def comments_allowed? 132 | Refinery::Setting.find_or_set(:comments_allowed, true, :scoping => 'blog') 133 | end 134 | 135 | def teasers_enabled? 136 | Refinery::Setting.find_or_set(:teasers_enabled, true, :scoping => 'blog') 137 | end 138 | 139 | def teaser_enabled_toggle! 140 | currently = Refinery::Setting.find_or_set(:teasers_enabled, true, :scoping => 'blog') 141 | Refinery::Setting.set(:teasers_enabled, :value => !currently, :scoping => 'blog') 142 | end 143 | end 144 | 145 | module ShareThis 146 | def self.enabled? 147 | Refinery::Blog.share_this_key != "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 148 | end 149 | end 150 | 151 | end 152 | end 153 | end 154 | -------------------------------------------------------------------------------- /spec/requests/refinery/blog/posts_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Refinery 4 | describe "Blog::Posts" do 5 | refinery_login_with :refinery_user 6 | 7 | context "when has blog posts" do 8 | let!(:blog_post) { Globalize.with_locale(:en) { FactoryGirl.create(:blog_post, :title => "Refinery CMS blog post") } } 9 | 10 | it "should display blog post" do 11 | visit refinery.blog_post_path(blog_post) 12 | 13 | page.should have_content(blog_post.title) 14 | end 15 | 16 | it "should display the blog rss feed" do 17 | get refinery.blog_rss_feed_path 18 | 19 | response.should be_success 20 | response.content_type.should eq("application/rss+xml") 21 | end 22 | 23 | describe "visit blog" do 24 | 25 | before(:each) do 26 | Factory.create(:page, :link_url => "/") 27 | Factory.create(:page, :link_url => "/blog", :title => "Blog") 28 | end 29 | 30 | it "shows blog link in menu" do 31 | visit "/" 32 | within "#menu" do 33 | page.should have_content("Blog") 34 | page.should have_selector("a[href='/blog']") 35 | end 36 | end 37 | 38 | it "shows blog posts" do 39 | visit refinery.blog_root_path 40 | page.should have_content blog_post.title 41 | end 42 | 43 | end 44 | 45 | end 46 | 47 | describe "list tagged posts" do 48 | context "when has tagged blog posts" do 49 | before(:each) do 50 | @tag_name = "chicago" 51 | @post = FactoryGirl.create(:blog_post, 52 | :title => "I Love my city", 53 | :tag_list => @tag_name) 54 | @tag = ::Refinery::Blog::Post.tag_counts_on(:tags).first 55 | end 56 | it "should have one tagged post" do 57 | visit refinery.blog_tagged_posts_path(@tag.id, @tag_name.parameterize) 58 | 59 | page.should have_content(@tag_name) 60 | page.should have_content(@post.title) 61 | end 62 | end 63 | end 64 | 65 | describe "#show" do 66 | context "when has no comments" do 67 | let(:blog_post) { FactoryGirl.create(:blog_post) } 68 | 69 | it "should display the blog post" do 70 | visit refinery.blog_post_path(blog_post) 71 | page.should have_content(blog_post.title) 72 | page.should have_content(blog_post.body) 73 | end 74 | end 75 | context "when has approved comments" do 76 | let(:approved_comment) { FactoryGirl.create(:approved_comment) } 77 | 78 | it "should display the comments" do 79 | visit refinery.blog_post_path(approved_comment.post) 80 | 81 | page.should have_content(approved_comment.body) 82 | page.should have_content("Posted by #{approved_comment.name}") 83 | end 84 | end 85 | context "when has rejected comments" do 86 | let(:rejected_comment) { FactoryGirl.create(:rejected_comment) } 87 | 88 | it "should not display the comments" do 89 | visit refinery.blog_post_path(rejected_comment.post) 90 | 91 | page.should_not have_content(rejected_comment.body) 92 | end 93 | end 94 | context "when has new comments" do 95 | let(:blog_comment) { FactoryGirl.create(:blog_comment) } 96 | 97 | it "should not display the comments" do 98 | visit refinery.blog_post_path(blog_comment.post) 99 | 100 | page.should_not have_content(blog_comment.body) 101 | end 102 | end 103 | 104 | context "when posting comments" do 105 | let(:blog_post) { Factory(:blog_post) } 106 | let(:name) { "pete" } 107 | let(:email) { "pete@mcawesome.com" } 108 | let(:body) { "Witty comment." } 109 | 110 | before do 111 | visit refinery.blog_post_path(blog_post) 112 | 113 | fill_in "Name", :with => name 114 | fill_in "Email", :with => email 115 | fill_in "Message", :with => body 116 | click_button "Send comment" 117 | end 118 | 119 | it "creates the comment" do 120 | comment = blog_post.reload.comments.last 121 | 122 | comment.name.should eq(name) 123 | comment.email.should eq(email) 124 | comment.body.should eq(body) 125 | end 126 | end 127 | 128 | context "post popular" do 129 | let(:blog_post) { FactoryGirl.create(:blog_post) } 130 | let(:blog_post2) { FactoryGirl.create(:blog_post) } 131 | 132 | before do 133 | visit refinery.blog_post_path(blog_post) 134 | end 135 | 136 | it "should increment access count" do 137 | blog_post.reload.access_count.should eq(1) 138 | visit refinery.blog_post_path(blog_post) 139 | blog_post.reload.access_count.should eq(2) 140 | end 141 | 142 | it "should be most popular" do 143 | Refinery::Blog::Post.popular(2).first.should eq(blog_post) 144 | end 145 | end 146 | 147 | context "post recent" do 148 | let!(:blog_post) { FactoryGirl.create(:blog_post, :published_at => Time.now - 5.minutes) } 149 | let!(:blog_post2) { FactoryGirl.create(:blog_post, :published_at => Time.now - 2.minutes) } 150 | 151 | it "should be the most recent" do 152 | Refinery::Blog::Post.recent(2).first.id.should eq(blog_post2.id) 153 | end 154 | end 155 | 156 | end 157 | 158 | describe "#show draft preview" do 159 | let(:blog_post) { FactoryGirl.create(:blog_post_draft) } 160 | 161 | context "when logged in as admin" do 162 | it "should display the draft notification" do 163 | visit refinery.blog_post_path(blog_post) 164 | 165 | page.should have_content('This page is NOT live for public viewing.') 166 | end 167 | end 168 | 169 | context "when not logged in as an admin" do 170 | before do 171 | visit refinery.logout_path 172 | end 173 | 174 | it "should not display the blog post" do 175 | visit refinery.blog_post_path(blog_post) 176 | 177 | page.should have_content("The page you were looking for doesn't exist (404)") 178 | end 179 | end 180 | end 181 | end 182 | end 183 | -------------------------------------------------------------------------------- /config/locales/fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Modifier cette catégorie 11 | delete: Supprimer cett catégorie 12 | index: 13 | no_items_yet: 'Il n''y a aucune catégorie pour le moment. Cliquez sur "%{create}" pour ajouter votre première catégorie.' 14 | comments: 15 | approved: 'Le commentaire de "%{author}" a été approuvé.' 16 | comment: 17 | view_live_html: 'Voir ce commentaire
    (Ouvre une nouvelle fenêtre)' 18 | read: Lire ce commentaire 19 | reject: Rejeter ce commentaire 20 | approve: Approuver ce commentaire 21 | rejected: 'Le commentaire de "%{author}" a été rejeté.' 22 | index: 23 | no_items_yet: 'Il n''y aucun %{type} de commentaires.' 24 | show: 25 | comment: Commenter 26 | blog_post: Article 27 | from: Écrit par 28 | date: Écrit le 29 | message: Commentaire 30 | details: Détails 31 | age: Âge 32 | actions: Actions 33 | back: Retour à la liste des commentaires 34 | reject: Rejeter ce commentaire 35 | approve: Approuver ce commentaire 36 | posts: 37 | form: 38 | toggle_advanced_options: Cliquez ici pour accéder aux paramêtres des meta-tags et au menu des options 39 | published_at: Date de publication 40 | index: 41 | no_items_yet: 'Il n''y a aucun article pour l''instant. Cliquez sur "%{create}" pour ajouter votre premier article.' 42 | uncategorized: 43 | no_items_yet: 'Il n''y a aucun article non catégorisé.' 44 | post: 45 | view_live_html: 'Voir cet article sur le site
    (Ouvre une nouvelle fenêtre)' 46 | edit: Modifier cet article 47 | delete: Supprimer cet article 48 | settings: 49 | notification_recipients: 50 | value: Envoyer les notifications à 51 | explanation: 'Chaque fois que quelqu''un écrit un commentaire sur un article, Refinery envoie un e-mail pour prévenir qu''il y a un nouveau commentaire.' 52 | hint: 'Quand un nouveau commentaire est ajouté, Refinery vous enverra un e-mail de notifications.' 53 | example: "Entrez une/des adresse(s) e-mail comme : jack@work.com, jill@office.com" 54 | updated: 'Les destinataires des notifications sont définis : "%{recipients}"' 55 | submenu: 56 | categories: 57 | title: Catégories 58 | manage: Gérer 59 | new: Créer une nouvelle catégorie 60 | comments: 61 | title: Commentaires 62 | title_with_count: 'Commentaires (%{new_count} nouveau(x))' 63 | new: Nouveau 64 | unmoderated: Nouveau 65 | approved: Approuvé 66 | rejected: Rejeté 67 | posts: 68 | title: Articles 69 | manage: Gérer les articles 70 | new: Créer un nouvel article 71 | uncategorized: Aricles non catégorisés 72 | settings: 73 | title: Paramêtres 74 | moderation: Modération 75 | update_notified: Mettre à jour les personnes à notifier 76 | comments: Commentaires 77 | comment_mailer: 78 | notification: 79 | greeting: Bonjour 80 | you_recieved_new_comment: Il y a un nouveau commentaire sur le blog. 81 | comment_starts: --- comment starts --- 82 | comment_ends: --- comment ends --- 83 | from: De 84 | email: Email 85 | message: Message 86 | closing_line: Cordialement 87 | ps: P.S. Tous les commentaires sont stockés dans la section "Blog" de Refinery dans le menu "Commentaires" si vous voulez les revoir plus tard. 88 | shared: 89 | categories: 90 | title: Catégories 91 | rss_feed: 92 | title: Flux RSS 93 | subscribe: Souscrire 94 | posts: 95 | other: Autres articles 96 | created_at: 'Écrit le %{when}' 97 | read_more: Lire la suite 98 | by: 'par' 99 | comments: 100 | singular: commentaire 101 | none: aucun commentaire 102 | archives: Archives 103 | tags: 104 | title: "Mots clés" 105 | categories: 106 | show: 107 | no_posts: 'Il n''y a aucun article pour cette catégorie.' 108 | posts: 109 | post: 110 | filed_in: Classé dans 111 | comment: commentaire 112 | comments: 113 | by: 'Écrit par %{who}' 114 | time_ago: 'il y a %{time} ' 115 | thank_you: 'Merci pour votre commentaire.' 116 | thank_you_moderated: 'Merci pour votre commentaire. Votre message a été placé en attente de validation et apparaitra bientôt.' 117 | index: 118 | no_blog_articles_yet: "Il n'y a aucun article pour l'instant. Restez en alerte." 119 | show: 120 | blog_home: Accueil du blog 121 | comments: 122 | title: Commentaires 123 | add: Ajouter un commentaire 124 | other: Autres articles 125 | filed_in: Classé dans 126 | tagged: Taggé 127 | submit: Envoyer le commentaire 128 | name: Nom 129 | email: Email 130 | message: Message 131 | by: par 132 | tagged: 133 | no_blog_articles_yet: "Il n'y a aucun article pour l'instant. Restez en alerte." 134 | posts_tagged: Articles taggés 135 | archive: 136 | blog_archive_for: 'Archive du blog pour le %{date}' 137 | no_blog_articles_posted: "Il n'y a aucun article pour la date du %{date}. Restez en alerte." 138 | activerecord: 139 | models: 140 | refinery/blog/category: Categorie 141 | refinery/blog/comment: Commentaire 142 | refinery/blog/post: Article 143 | attributes: 144 | refinery/blog/category: 145 | title: Titre 146 | refinery/blog/comment: 147 | name: Nom 148 | email: Email 149 | message: Message 150 | refinery/blog/post: 151 | title: Titre 152 | body: Corps 153 | -------------------------------------------------------------------------------- /config/locales/bg.yml: -------------------------------------------------------------------------------- 1 | bg: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Блог 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Редактиране на тази категория 11 | delete: Изтриване на тази категория завинаги 12 | index: 13 | no_items_yet: 'Все още няма категории. Натиснете "%{create}", за да въведете нова.' 14 | comments: 15 | approved: 'Коментара от "%{author}" бе одобрен.' 16 | comment: 17 | view_live_html: 'Преглед на този коментар
    (ще се отвори се в нов прозорец)' 18 | read: Прочитане на този коментар 19 | reject: Отхвърляне на този коментар 20 | approve: Одобряване на този коментар 21 | rejected: 'Коментара от "%{author}" бе отхвърлен.' 22 | index: 23 | no_items_yet: '%{type} коментари не бяха намерени.' 24 | show: 25 | comment: Коментар 26 | blog_post: Публикация 27 | from: Публикувано от 28 | date: Публикувано на 29 | message: Коментар 30 | details: Детайли 31 | age: Възраст 32 | actions: Действия 33 | back: Обратно към всички коментари 34 | reject: Отхвърляне на този коментар 35 | approve: Одобряване на този коментар 36 | posts: 37 | form: 38 | toggle_advanced_options: Натиснете, за да достъпите настройките за етикета "meta" и менюто 39 | published_at: Дата на публикуване 40 | custom_url: Уеб адрес по избор 41 | custom_url_help: Вместо от заглавието, генерирайте уеб адреса за тази публикация чрез този текст. 42 | copy_body: Копиране на съдържанието на публикацията като извадка 43 | copy_body_help: Съдържанието на публикацията ще се копира като извадка. Оставете извадката празна и Refinery автоматично ще я сглоби. 44 | index: 45 | no_items_yet: 'Все още няма публикации. Натиснете "%{create}", за да въведете нова.' 46 | uncategorized: 47 | no_items_yet: 'Не съществуват некатегоризирани публикации.' 48 | post: 49 | view_live_html: 'Преглед на този публикация
    (ще се отвори се в нов прозорец)' 50 | edit: Редактиране на тази публикация 51 | delete: Изтриване на тази публикация завинаги 52 | settings: 53 | notification_recipients: 54 | value: Изпращане на уведомления до 55 | explanation: 'Всеки път, когато някой коментира публикация, Refinery ще изпраща е-писмо, за да уведоми, че съществува нов коментар.' 56 | hint: 'При добавяне на коментар, Refinery ще Ви уведоми по е-пощата.' 57 | example: "Въведете адреса(ите) на Вашата е-поща. Например: jack@work.com, jill@office.com" 58 | updated: 'Уведомления бяха изпратени до "%{recipients}"' 59 | submenu: 60 | categories: 61 | title: Категории 62 | manage: Управление 63 | new: Добавяне на нова категория 64 | comments: 65 | title: Коментари 66 | title_with_count: 'Коментари (%{new_count} нови)' 67 | new: Нови 68 | unmoderated: Нови 69 | approved: Одобрени 70 | rejected: Отхвърлени 71 | posts: 72 | title: Публикации 73 | manage: Управление на публикации 74 | new: Добавяне на нова публикация 75 | uncategorized: Некатегоризирани публикации 76 | settings: 77 | title: Настройки 78 | moderation: Модерация 79 | update_notified: Получатели на уведомления 80 | comments: Коментари 81 | comment_mailer: 82 | notification: 83 | greeting: Здравейте 84 | you_recieved_new_comment: Току що получихте нов коментар на Вашия уебсайт. 85 | comment_starts: --- Начало на коментара --- 86 | comment_ends: --- Край на коментара --- 87 | from: От 88 | email: Е-поща 89 | message: Съобщение 90 | closing_line: Поздрави 91 | ps: 'П.П. Всички Ваши коментари се съхраняват от Refinery в секция "Блог" в подменю "Коментари" и могат да бъдат прегледани по-късно.' 92 | shared: 93 | categories: 94 | title: Категории 95 | rss_feed: 96 | title: RSS хранилка 97 | subscribe: Абониране 98 | posts: 99 | other: Други публикации 100 | created_at: 'Публикувано на %{when}' 101 | read_more: Цялата публикация 102 | comments: 103 | singular: коментар 104 | none: няма коментари 105 | archives: Архиви 106 | tags: 107 | title: "Етикети" 108 | categories: 109 | show: 110 | no_posts: Тук все още няма публикации. 111 | posts: 112 | post: 113 | filed_in: Категория 114 | comment: коментар 115 | comments: 116 | by: 'Публикувано от %{who}' 117 | time_ago: 'преди %{time}' 118 | thank_you: 'Благодаря за Вашия коментар.' 119 | thank_you_moderated: 'Благодаря за Вашия коментар. Съобщението Ви е в опашката за модерация и скоро ще бъде показано.' 120 | index: 121 | no_blog_articles_yet: Все още няма публикувани статии. Очаквайте скоро. 122 | show: 123 | blog_home: Обратно към началото на блога 124 | comments: 125 | title: Коментари 126 | add: Вашият коментар 127 | other: Други публикации 128 | filed_in: Категория 129 | tagged: Отбелязано с 130 | submit: Изпращане на коментар 131 | name: Име 132 | email: Е-поща 133 | message: Съобщение 134 | by: от 135 | tagged: 136 | no_blog_articles_yet: Все още няма публикувани статии. Очаквайте скоро. 137 | posts_tagged: Публикации отбелязани с 138 | archive: 139 | blog_archive_for: 'Архив на блога за %{date}' 140 | no_blog_articles_posted: 'Все още няма публикувани статии за %{date}. Очаквайте скоро.' 141 | activerecord: 142 | models: 143 | refinery/blog/category: Категория 144 | refinery/blog/comment: Коментар 145 | refinery/blog/post: Публикация 146 | attributes: 147 | refinery/blog/category: 148 | title: Заглавие 149 | refinery/blog/comment: 150 | name: Име 151 | email: Е-поща 152 | message: Съобщение 153 | refinery/blog/post: 154 | title: Заглавие 155 | body: Съдържание 156 | teaser: Извадка 157 | -------------------------------------------------------------------------------- /config/locales/de.yml: -------------------------------------------------------------------------------- 1 | de: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Diese Kategorie bearbeiten 11 | delete: Diese Kategorie dauerhaft entfernen 12 | index: 13 | no_items_yet: 'Es sind noch keine Kategorien vorhanden. Klicken Sie auf "%{create}", um Ihre erste Kategorie hinzuzufügen.' 14 | comments: 15 | approved: 'Der Kommentar von "%{author}" wurde genehmigt.' 16 | comment: 17 | view_live_html: 'Diesen Kommentar live betrachten
    (öffnet sich in einem neuen Fenster)' 18 | read: Kommentar lesen 19 | reject: Kommentar ablehnen 20 | approve: Kommentar genehmigen 21 | rejected: 'Der Kommentar von "%{author}" wurde abgelehnt.' 22 | index: 23 | no_items_yet: 'Es sind keine %{type}en Kommentare vorhanden.' 24 | show: 25 | comment: Kommentar 26 | blog_post: Artikel 27 | from: Verfasst von 28 | date: Verfasst am 29 | message: Kommentar 30 | details: Details 31 | age: Alter 32 | actions: Aktionen 33 | back: Zurück zu allen Kommentaren 34 | reject: Kommentar ablehnen 35 | approve: Kommentar genehmigen 36 | posts: 37 | form: 38 | toggle_advanced_options: 'Klicken, um auf Meta-Tag-Einstellungen und Menüoptionen zuzugreifen' 39 | published_at: Veröffentlichungsdatum 40 | custom_url: Eigene Url 41 | custom_url_help: Url von disem Text generieren und nicht vom Titel. 42 | source_url: Quell Url 43 | source_url_help: Url für die Quelle dieses Artikels. 44 | source_url_title: Quell Url Titel 45 | source_url_title_help: Titel der Quelle dieses Artikels. 46 | author: Autor 47 | author_help: Legt fest welcher Benutzer als Autor angegeben wird. 48 | copy_body: Kopiere Artikel zum Teaser 49 | copy_body_help: Kopiert den Inhalt zum Teaser. Ist der Teaser nicht angegeben generiert Refinery einen. 50 | index: 51 | no_items_yet: 'Es sind noch keine Artikel vorhanden. Klicken Sie auf "%{create}", um Ihren ersten Artikel hinzuzufügen.' 52 | uncategorized: 53 | no_items_yet: 'Es sind keine unkategorisierten Artikel vorhanden.' 54 | post: 55 | view_live_html: 'Diesen Artikel live betrachten
    (öffnet sich in einem neuen Fenster)' 56 | edit: Diesen Artikel bearbeiten 57 | delete: Diesen Artikel dauerhaft entfernen 58 | draft: Entwurf 59 | settings: 60 | notification_recipients: 61 | value: Sende Benachrichtigungen an 62 | explanation: 'Jedes Mal, wenn jemand einen Artikel kommentiert, sendet Refinery eine E-Mail Benachrichtigung aus, um über den neuen Kommentar zu informieren.' 63 | hint: 'Refinery sendet eine E-Mail Benachrichtigung an Sie, wenn ein neuer Kommentar hinzugefügt wurde.' 64 | example: 'Geben Sie Ihre E-Mail-Adresse(n) wie folgt ein: jack@work.com, jill@office.com' 65 | updated: 'Empfänger für Benachrichtigungen wurden auf "%{recipients}" gesetzt' 66 | submenu: 67 | categories: 68 | title: Kategorien 69 | manage: Verwalten 70 | new: Neue Kategorie anlegen 71 | comments: 72 | title: Kommentare 73 | title_with_count: 'Kommentare (%{new_count} neu)' 74 | new: Neu 75 | unmoderated: Neu 76 | approved: Genehmigt 77 | rejected: Abgelehnt 78 | posts: 79 | title: Artikel 80 | manage: Artikel verwalten 81 | new: Neuen Artikel anlegen 82 | uncategorized: Unkategorisierte Artikel 83 | settings: 84 | title: Einstellungen 85 | moderation: Moderation 86 | update_notified: Empfänger für Benachrichtigungen bearbeiten 87 | comments: Kommentare 88 | teasers: Teaser 89 | comment_mailer: 90 | notification: 91 | greeting: Hallo 92 | you_recieved_new_comment: Auf Ihrer Website wurde soeben ein neuer Kommentar hinzugefügt. 93 | comment_starts: --- Kommentar beginnt --- 94 | comment_ends: --- Kommentar endet --- 95 | from: Von 96 | email: E-Mail 97 | message: Nachricht 98 | closing_line: Mit besten Grüßen 99 | ps: 'P.S. Alle Kommentare sind im "Blog" Abschnitt von Refinery - im Untermenü "Kommentare" - gespeichert, falls Sie diese später dort lesen möchten.' 100 | shared: 101 | categories: 102 | title: Kategorien 103 | rss_feed: 104 | title: RSS Feed 105 | subscribe: Abonnieren 106 | posts: 107 | other: Andere Artikel 108 | created_at: 'Verfasst am %{when}' 109 | read_more: Weiterlesen 110 | comments: 111 | singular: Kommentar 112 | none: Keine Kommentare 113 | archives: Archiv 114 | tags: 115 | title: Tags 116 | categories: 117 | show: 118 | no_posts: Es sind noch keine Artikel vorhanden. 119 | posts: 120 | post: 121 | filed_in: Gespeichert unter 122 | comment: Kommentar 123 | comments: 124 | by: 'Verfasst von %{who}' 125 | time_ago: 'vor %{time}' 126 | thank_you: 'Danke für den Kommentar.' 127 | thank_you_moderated: 'Danke für den Kommentar. Die Nachricht wurde in die Warteschlange der Moderation gestellt und erscheint in Kürze.' 128 | index: 129 | no_blog_articles_yet: Es wurden noch keine Artikel verfasst. 130 | show: 131 | blog_home: Blog Startseite 132 | comments: 133 | title: Kommentare 134 | add: Neuen Kommentar hinzufügen 135 | other: Andere Artikel 136 | filed_in: Gespeichert unter 137 | tagged: Tagged 138 | submit: Kommentar senden 139 | name: Name 140 | email: Email 141 | message: Nachricht 142 | by: von 143 | source: Quelle 144 | tagged: 145 | no_blog_articles_yet: Es sind noch keine Artikel vorhanden. 146 | posts_tagged: Artikel getagged 147 | archive: 148 | blog_archive_for: 'Blog Archiv für %{date}' 149 | no_blog_articles_posted: 'Für %{date} wurden keine Artikel verfasst.' 150 | -------------------------------------------------------------------------------- /config/locales/it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blog 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Modifica questa categoria 11 | delete: Elimina questa categoria per sempre 12 | index: 13 | no_items_yet: 'Nessuna categoria ancora presente. Fare click su "%{create}" per aggiungere la tua prima categoria.' 14 | comments: 15 | approved: 'Il commento di "%{author}" è stato approvato.' 16 | comment: 17 | view_live_html: 'Visualizza questo commento
    live (si apre in una nuova finestra)
    ' 18 | read: Leggi questo commento 19 | reject: Rifiuta questo commento 20 | approve: Approva questo commento 21 | rejected: 'Il commento di "%{author}" è stato rifiutato.' 22 | index: 23 | no_items_yet: 'Non ci sono %{type} commenti.' 24 | show: 25 | comment: Commento 26 | blog_post: Articolo 27 | from: Pubblicato da 28 | date: Pubblicato il 29 | message: Commento 30 | details: Dettagli 31 | age: età 32 | actions: Azioni 33 | back: Torna a tutti i commenti 34 | reject: Rifiuta questo commento 35 | approve: Approva questo commento 36 | posts: 37 | form: 38 | toggle_advanced_options: Clicca per accedere alle impostationi dei meta tag e del menu 39 | published_at: Data di Pubblicazione 40 | custom_url: Url personalizzato 41 | custom_url_help: Puoi scegliere un url specifico per questo articolo. Lasciando questo campo vuoto verrà utilizzato il titolo. 42 | copy_body: Copia il testo dell'articolo nel teaser 43 | copy_body_help: Lascia il teaser bianco per creare il teaser automaticamente. 44 | index: 45 | no_items_yet: 'Non ci sono ancora articoli in questo Blog. Clicca su "%{create}" per aggiungerne uno.' 46 | uncategorized: 47 | no_items_yet: 'Non ci sono articoli senza categoria.' 48 | post: 49 | view_live_html: 'Visualizza questo articolo sul sito
    (si aprirà in una nuova finestra)' 50 | edit: Modifica questo articolo 51 | delete: Rimuovi questo articolo per sempre 52 | settings: 53 | notification_recipients: 54 | value: Inviare notifiche a 55 | explanation: "Ogni volta che qualcuno commenta un articolo, Refinery invia una mail per avvisare che c'è un nuovo comemnto" 56 | hint: 'Quando viene aggiunto un nuovo commento Refinery ti invierà una email di notifica.' 57 | example: "Inserisci il tuo indirizzo email. È possibile insierire più indirizzi separati dalla virgola. Es: jack@work.com, jill@office.com" 58 | updated: 'I destinatari delle notifiche sono stati impostati "%{recipients}"' 59 | submenu: 60 | categories: 61 | title: Categorie 62 | manage: Gestione categorie 63 | new: Crea una nuova categoria 64 | comments: 65 | title: Commenti 66 | title_with_count: 'Commenti (%{new_count} nuovi)' 67 | new: Nuovo 68 | unmoderated: Nuovo 69 | approved: Approvato 70 | rejected: Rifiutato 71 | posts: 72 | title: Articoli 73 | manage: Gestione articoli 74 | new: Crea un nuovo articolo 75 | uncategorized: Articoli senza categoria 76 | settings: 77 | title: Impostazioni 78 | moderation: Moderazione 79 | update_notified: Aggiornare i destinatari delle notifiche 80 | comments: Commenti 81 | comment_mailer: 82 | notification: 83 | greeting: Ciao 84 | you_recieved_new_comment: Hai ricevuto un commento sul tuo sito. 85 | comment_starts: --- inizio commento --- 86 | comment_ends: --- fine commento --- 87 | from: Da 88 | email: Email 89 | message: Testo 90 | closing_line: Saluti 91 | ps: 'P.S. Tutti i commenti sono memorizzati nella sezione "Blog di Refinery sotto la voce "Commenti" se mai volessi visualizzarli lì.' 92 | shared: 93 | categories: 94 | title: Categorie 95 | rss_feed: 96 | title: RSS Feed 97 | subscribe: Iscriviti 98 | posts: 99 | other: Altri Articoli 100 | created_at: 'Pubblicato il %{when}' 101 | read_more: Continua a leggere 102 | comments: 103 | singular: commento 104 | plural: commenti 105 | none: nessun commento 106 | tags: 107 | title: "Tags" 108 | categories: 109 | show: 110 | no_posts: Non sono ancora presenti articoli. 111 | posts: 112 | post: 113 | filed_in: Archiviato in 114 | comment: commento 115 | comments: 116 | by: 'Pubblicato da %{who}' 117 | time_ago: '%{time} fa' 118 | thank_you: 'Grazie per aver scritto un commento.' 119 | thank_you_moderated: 'Grazie per aver scritto un commento. Il tuo messaggio è stato inserito nella coda di moderazione e sarà visibile a breve.' 120 | index: 121 | no_blog_articles_yet: Non sono stati ancora pubblicati articoli nel blog. Continuate a seguirci. 122 | show: 123 | comments: 124 | title: Commenti 125 | add: Scrivi un Commento 126 | other: Altri Articoli 127 | filed_in: Archiviato in 128 | submit: Invia commento 129 | tagged: Taggato 130 | name: Nome 131 | email: Email 132 | message: Articolo 133 | by: da 134 | tagged: 135 | no_blog_articles_yet: Non sono stati ancora pubblicati articoli nel blog. Continuate a seguirci. 136 | posts_tagged: Articoli taggati 137 | archive: 138 | blog_archive_for: 'Articoli pubblicati il %{date}' 139 | no_blog_articles_posted: Non sono stati pubblicati articoli nel blog il %{date}. Continuate a seguirci. 140 | activerecord: 141 | models: 142 | refinery/blog/category: Categoria 143 | refinery/blog/comment: Commento 144 | refinery/blog/post: Articolo 145 | attributes: 146 | refinery/blog/category: 147 | title: Titolo 148 | refinery/blog/comment: 149 | name: Nome 150 | email: Email 151 | message: Testo 152 | refinery/blog/post: 153 | title: Titolo 154 | body: Testo 155 | -------------------------------------------------------------------------------- /config/locales/sv.yml: -------------------------------------------------------------------------------- 1 | sv: 2 | refinery: 3 | plugins: 4 | refinerycms_blog: 5 | title: Blogg 6 | blog: 7 | admin: 8 | categories: 9 | category: 10 | edit: Editera kategori 11 | delete: Radera kategori 12 | index: 13 | no_items_yet: 'Det finns inga kategorier än. Klicka på "%{create}" för att lägga till den första kategorin.' 14 | comments: 15 | approved: 'Kommentaren från "%{author}" Har godkänts.' 16 | comment: 17 | view_live_html: 'Visa kommentaren på webbplatsen.
    (öppnas i ett nytt fönster)' 18 | read: Läs denna kommentar 19 | reject: Avslå kommentar 20 | approve: Godkänn kommentar 21 | rejected: 'Kommentaren från "%{author}" har avslagits.' 22 | index: 23 | no_items_yet: 'Det finns inga %{type} kommentarer.' 24 | show: 25 | comment: Kommentar 26 | blog_post: Blogg post 27 | from: Postat av 28 | date: Postat 29 | message: Kommentar 30 | details: Detaljer 31 | age: Ålder 32 | actions: Actions 33 | back: Tillbaka till alla kommentarer 34 | reject: Avslå denna kommentar 35 | approve: Godkänn denna kommentar 36 | posts: 37 | form: 38 | toggle_advanced_options: Klicka för att ställa in metataggar och menyinställningar 39 | published_at: Publiceringsdatum 40 | custom_url: Anpassad URL 41 | custom_url_help: Skapa URL för bloggposten med denna text istället för ttieln 42 | source_url: Källans URL 43 | source_url_help: Sparar URL för postens källa 44 | source_url_title: Källhänvisning (titel) 45 | source_url_title_help: Källhänvisning för posten (URL). 46 | author: Författare 47 | author_help: Ställ in författare för denna post. 48 | copy_body: Kopiera innehåll i posten till en teaser. 49 | copy_body_help: Kopierar inneållet i posten till en teaser, lämna tom om du vill att det ska ske automatiskt. 50 | index: 51 | no_items_yet: 'Det finns inga poster än. Klicka "%{create}" för att lägga till din första post.' 52 | uncategorized: 53 | no_items_yet: 'Det finns inga okategoriserade poster.' 54 | post: 55 | view_live_html: 'Visa denna post i en webbläsare
    (öppnas i ett nytt fönster)' 56 | edit: Redigera denna bloggpost 57 | delete: Ta bort denna bloggpost 58 | draft: Utkast 59 | settings: 60 | notification_recipients: 61 | value: Skicka notis till 62 | explanation: 'Varje gång någon kommenterar på en post, skickas ett mail om kommentaren.' 63 | hint: 'När en kommentar läggs till, så skickar vi en notis till dig.' 64 | example: "Lägg till epostadress(er) i detta format: kalle@home.se, pelle@work.com" 65 | updated: 'Notiser har blivit skickade till: "%{recipients}"' 66 | submenu: 67 | categories: 68 | title: Kategorier 69 | manage: Hantera 70 | new: Skapa ny kategori 71 | comments: 72 | title: Kommentarer 73 | title_with_count: 'Det finns (%{new_count} nya kommentarer)' 74 | new: Ny 75 | unmoderated: Ny 76 | approved: Godkänd 77 | rejected: Avslagen 78 | posts: 79 | title: Poster 80 | manage: Hantera poster 81 | new: Skapa ny post 82 | uncategorized: Okategoriserade poster 83 | settings: 84 | title: Inställningar 85 | moderation: Moderering 86 | update_notified: Uppdarea vilka som får notiser 87 | comments: Kommentarer 88 | teasers: Teasers 89 | comment_mailer: 90 | notification: 91 | greeting: Hej! 92 | you_recieved_new_comment: Du har fått en ny kommentar på bloggenYou just received a new comment on your website. 93 | comment_starts: --- kommentar --- 94 | comment_ends: --- // kommentar --- 95 | from: Från 96 | email: E-post 97 | message: Meddelande 98 | closing_line: Vänliga hälsningar 99 | ps: 'P.S. Alla dina kommentarer finns lagrade i bloggsektionen av ditt CMS i undermenyn kommentarer, om du vill se dem senare.' 100 | shared: 101 | categories: 102 | title: Kategorier 103 | rss_feed: 104 | title: RSS 105 | subscribe: Prenumerera 106 | posts: 107 | other: Övriga poster 108 | created_at: 'Postat den %{when}' 109 | read_more: Läs mer 110 | comments: 111 | singular: Kommentar 112 | none: Inga kommentarer 113 | archives: Arkiv 114 | tags: 115 | title: "Taggar" 116 | categories: 117 | show: 118 | no_posts: Det finns inga poster än. 119 | posts: 120 | post: 121 | filed_in: Kategoriserat som 122 | comment: kommentar 123 | comments: 124 | by: 'Postad av %{who}' 125 | time_ago: 'för %{time} sedan' 126 | thank_you: 'Tack för din kommentar.' 127 | thank_you_moderated: 'Tack för din kommentar. Ditt meddelande har placerats i modereringskön och kommer snart att bli publicerat.' 128 | index: 129 | no_blog_articles_yet: Det finns inga bloggposter än. 130 | show: 131 | blog_home: Blogg hem 132 | comments: 133 | title: Kommentarer 134 | add: Kommentera 135 | other: Andra bloggposter 136 | filed_in: Kategoriserat i 137 | tagged: Taggar 138 | submit: Skicka kommentar 139 | name: Namn 140 | email: E-post 141 | message: Meddelande 142 | by: av 143 | source: Källa 144 | tagged: 145 | no_blog_articles_yet: Det finns inga bloggposter än. 146 | posts_tagged: Poster taggade med 147 | archive: 148 | blog_archive_for: 'Arkiv för %{date}' 149 | no_blog_articles_posted: 'Det finns inga artiklar för %{date}.' 150 | activerecord: 151 | models: 152 | refinery/blog/category: Kategori 153 | refinery/blog/comment: Kommentarer 154 | refinery/blog/post: Bloggposter 155 | attributes: 156 | refinery/blog/category: 157 | title: Titel 158 | refinery/blog/comment: 159 | name: Namn 160 | email: E-post 161 | message: Meddelande 162 | refinery/blog/post: 163 | title: Titel 164 | body: Innehåll 165 | teaser: Teaser 166 | --------------------------------------------------------------------------------