add source url for post

This commit is contained in:
Jeff Shumate 2012-01-25 22:27:46 -07:00
parent d1ad82d42e
commit e274bb1757
9 changed files with 171 additions and 4 deletions

View file

@ -22,6 +22,12 @@ module Refinery
validates :title, :presence => true, :uniqueness => true
validates :body, :presence => true
validates :source_url, :url => { :if => 'Refinery::Blog.config.validate_source_url',
:update => true,
:allow_nil => true,
:allow_blank => true,
:verify => [:resolve_redirects]}
has_friendly_id :friendly_id_source, :use_slug => true,
:default_locale => (::Refinery::I18n.default_frontend_locale rescue :en),
@ -48,6 +54,7 @@ module Refinery
attr_accessible :title, :body, :custom_teaser, :tag_list, :draft, :published_at, :custom_url
attr_accessible :browser_title, :meta_keywords, :meta_description, :user_id, :category_ids
attr_accessible :source_url, :source_url_title
self.per_page = Refinery::Setting.find_or_set(:blog_posts_per_page, 10)

View file

@ -81,6 +81,22 @@
<%= f.text_field :custom_url, :class => "widest" %>
</div>
<div class='field'>
<span class='label_with_help'>
<%= f.label :source_url_title, t('.source_url_title') %>
<%= refinery_help_tag t('.source_url_title_help') %>
</span>
<%= f.text_field :source_url_title, :class => "widest" %>
</div>
<div class='field'>
<span class='label_with_help'>
<%= f.label :source_url, t('.source_url') %>
<%= refinery_help_tag t('.source_url_help') %>
</span>
<%= f.text_field :source_url, :class => "widest" %>
</div>
<div class='field'>
<span class='label_with_help'>
<%= f.label :user_id, t('.author') %>

View file

@ -10,7 +10,13 @@
<time datetime="<%=l @post.published_at.to_date, :format => :default %>" class='posted_at'>
<%= t('created_at', :scope => 'refinery.blog.shared.posts', :when => l(@post.published_at.to_date, :format => :short)) %>
</time>
<%= "#{t('by', :scope => 'refinery.blog.posts.show')} #{@post.author.username}" if @post.author.present? %>.
<%= content_tag(:div, "#{t('by', :scope => 'refinery.blog.posts.show')} #{@post.author.username}", :class => "blog_author") if @post.author.present? %>
<% if @post.source_url.present? %>
<div class='blog_source'>
<%= "#{t('source', :scope => 'refinery.blog.posts.show')}: " %>
<%= link_to (@post.source_url_title.blank? ? @post.source_url : @post.source_url_title), @post.source_url %>
</div>
<% end %>
<% if (categories = @post.categories).any? %>
<aside class='filed_in'>
<%= t('filed_in', :scope => 'refinery.blog.posts.show') %>

View file

@ -0,0 +1,85 @@
require 'net/http'
class UrlValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
url = value
# Regex code by 'Arsenic' from http://snippets.dzone.com/posts/show/3654
if url =~ /^
( (https?):\/\/ )?
( [a-z\d]+([\-\.][a-z\d]+)*\.[a-z]{2,6} )
(
(:
( \d{1,5} )
)?
( \/.* )?
)?
$/ix
url = "http#{'s' if $7 == '81'}://#{url}" unless $1
else
record.errors[attribute] << 'Not a valid URL'
end
if options[:verify]
begin
url_response = RedirectFollower.new(url).resolve
url = url_response.url if options[:verify] == [:resolve_redirects]
rescue RedirectFollower::TooManyRedirects
record.errors[attribute] << 'URL is redirecting too many times'
rescue
record.errors[attribute] << 'could not be resolved'
end
end
if options[:update]
value.replace url
end
end
end
# Code below written by John Nunemaker
# See blog post at http://railstips.org/blog/archives/2009/03/04/following-redirects-with-nethttp/
class RedirectFollower
class TooManyRedirects < StandardError; end
attr_accessor :url, :body, :redirect_limit, :response
def initialize(url, limit=5)
@url, @redirect_limit = url, limit
logger.level = Logger::INFO
end
def logger
@logger ||= Logger.new(STDOUT)
end
def resolve
raise TooManyRedirects if redirect_limit < 0
self.response = Net::HTTP.get_response(URI.parse(url))
logger.info "redirect limit: #{redirect_limit}"
logger.info "response code: #{response.code}"
logger.debug "response body: #{response.body}"
if response.kind_of?(Net::HTTPRedirection)
self.url = redirect_url
self.redirect_limit -= 1
logger.info "redirect found, headed to #{url}"
resolve
end
self.body = response.body
self
end
def redirect_url
if response['location'].nil?
response.body.match(/<a href=\"([^>]+)\">/i)[1]
else
response['location']
end
end
end

View file

@ -41,6 +41,10 @@ en:
published_at: Publish Date
custom_url: Custom Url
custom_url_help: Generate the url for the blog post from this text instead of the title.
source_url: Source Url
source_url_help: Stores the url for the source of the post material.
source_url_title: Source Url Title
source_url_title_help: Title for the source url for the post.
author: Author
author_help: Set which user this post will show as the author.
copy_body: Copy Post Body to Teaser
@ -136,7 +140,8 @@ en:
name: Name
email: Email
message: Message
by: by
by: By
source: Source
tagged:
no_blog_articles_yet: There are no blog articles posted yet. Stay tuned.
posts_tagged: Posts tagged

View file

@ -0,0 +1,7 @@
class AddSourceUrlToBlogPosts < ActiveRecord::Migration
def change
add_column Refinery::Blog::Post.table_name, :source_url, :string
add_column Refinery::Blog::Post.table_name, :source_url_title, :string
end
end

View file

@ -7,6 +7,7 @@ module Refinery
module Blog
require 'refinery/blog/engine'
require 'refinery/blog/configuration'
autoload :Version, 'refinery/blog/version'
autoload :Tab, 'refinery/blog/tabs'

View file

@ -0,0 +1,9 @@
module Refinery
module Blog
include ActiveSupport::Configurable
config_accessor :validate_source_url
self.validate_source_url = false
end
end

View file

@ -212,9 +212,40 @@ module Refinery
subject.class.teasers_enabled?.should be_false
end
end
end
describe "source url" do
it "should allow a source url and title" do
p = FactoryGirl.create(:blog_post, :source_url => 'google.com', :source_url_title => 'author')
p.should be_valid
p.source_url.should include('google')
p.source_url_title.should include('author')
end
end
describe ".validate_source_url?" do
context "with Refinery::Setting validate_source_url set to true" do
before do
Refinery::Setting.set(:validate_source_url, { :scoping => 'blog', :value => true })
Refinery::Blog.validate_source_url = true
end
it "should have canonical url" do
p = FactoryGirl.create(:blog_post, :source_url => 'google.com', :source_url_title => 'google')
p.source_url.should include('www')
end
end
context "with Refinery::Setting validate_source_url set to false" do
before do
Refinery::Setting.set(:validate_source_url, { :scoping => 'blog', :value => false })
Refinery::Blog.validate_source_url = false
end
it "should have original url" do
p = FactoryGirl.create(:blog_post, :source_url => 'google.com', :source_url_title => 'google')
p.source_url.should_not include('www')
end
end
end
end
end
end