Skip to content
This repository has been archived by the owner on Aug 15, 2018. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
added slugs to the blog plugin, added ability to modify a page that g…
…ets shown after each blog post
  • Loading branch information
Josh Adams committed Dec 27, 2008
1 parent 2e7d812 commit 18d6417
Show file tree
Hide file tree
Showing 205 changed files with 47,272 additions and 13 deletions.
2 changes: 1 addition & 1 deletion config/environment.rb
Expand Up @@ -51,7 +51,7 @@
# Only load the plugins named here, in the order given. By default, all plugins
# in vendor/plugins are loaded in alphabetical order.
# :all can be used as a placeholder for all plugins not explicitly named
config.plugins = [ :has_settings, :all ]
config.plugins = [ :has_settings, :stringex, :all ]

# Add additional load paths for your own custom dirs
# config.load_paths += %W( #{RAILS_ROOT}/extras )
Expand Down
4 changes: 4 additions & 0 deletions public/themes/isotope11/stylesheets/base.css
Expand Up @@ -272,6 +272,10 @@ ul#top-nav{
font-size: 200%;
}

.blog_post h2.title a{
color: #559096;
}

.blog_post h3.time{
position: absolute;
left: -100px;
Expand Down
Expand Up @@ -8,7 +8,7 @@ class Admin::BlogPostsController < Admin::BaseController

protected
def load_blog_post
@blog_post = Ansuz::JAdams::BlogPost.find(params[:id])
@blog_post = Ansuz::JAdams::BlogPost.find_by_url(params[:id])
end

def load_new_blog_post
Expand Down
Expand Up @@ -10,7 +10,7 @@ def load_blog_posts
end

def load_blog_post
@blog_post = Ansuz::JAdams::BlogPost.find(params[:id])
@blog_post = Ansuz::JAdams::BlogPost.find_by_url(params[:id])
end

public
Expand Down
7 changes: 7 additions & 0 deletions vendor/plugins/ansuz_blog/app/models/blog_post.rb
Expand Up @@ -2,6 +2,9 @@ module Ansuz
module JAdams
class BlogPost < ActiveRecord::Base
acts_as_taggable
acts_as_url :title
validates_uniqueness_of :url

belongs_to :author, :class_name => "User", :foreign_key => 'created_by'
has_many :blog_comments, :class_name => "Ansuz::JAdams::BlogComment", :order => "created_at DESC"

Expand All @@ -16,6 +19,10 @@ def self.view_partial
def to_s
title
end

def to_param
url
end
end
end
end
@@ -1,5 +1,6 @@
<%= title "Edit Blog Post: #{@blog_post}" -%>
<% content_for :sidebar do -%>
<%= link_to "View On Site", article_path(@blog_post), :class => 'button icon forward' -%>
<%= link_to "All Blog Posts", admin_blog_posts_path, :class => 'button icon back' -%>
<% end -%>
<% form_for :blog_post, :url => admin_blog_post_path(@blog_post), :html => { :method => :put, :class => 'blog-post-form' } do |f| -%>
Expand Down
@@ -1,6 +1,7 @@
<%= title @blog_post.title -%>
<% content_for :sidebar do -%>
<ul class='toolbar'>
<li><%= link_to "View On Site", article_path(@blog_post), :class => 'button icon forward' -%></li>
<li><%= link_to "Edit Blog Post", edit_admin_blog_post_path(@blog_post), :class => 'button icon edit' -%></li>
<li><%= link_to "All Blog Posts", admin_blog_posts_path, :class => 'button icon back' -%></li>
</ul>
Expand Down
@@ -0,0 +1,6 @@
<div class='blog_post' id='<%= dom_id(article) -%>'>
<h2><%=h article.title -%></h2>
<div class='contents'>
<%= article.contents -%>
</div>
</div>
7 changes: 1 addition & 6 deletions vendor/plugins/ansuz_blog/app/views/articles/index.html.erb
Expand Up @@ -3,10 +3,5 @@
<%= tag_cloud -%>
<% end -%>
<% @blog_posts.each do |blog_post| -%>
<div class='blog_post'>
<h2><%=h blog_post.title -%></h2>
<div class='contents'>
<%= blog_post.contents -%>
</div>
</div>
<%= render :partial => 'articles/article', :locals => { :article => blog_post } %>
<% end -%>
5 changes: 5 additions & 0 deletions vendor/plugins/ansuz_blog/app/views/articles/show.html.erb
@@ -0,0 +1,5 @@
<%= render :partial => 'articles/article', :locals => { :article => @blog_post } %>
<div class='post-blog-post'>
<%= render_special "post_blog_post" %>
</div>
<%= link_to "All Blog Posts", articles_path -%>
@@ -0,0 +1,9 @@
class AddUrlToBlogPosts < ActiveRecord::Migration
def self.up
add_column :blog_posts, :url, :string
end

def self.down
remove_column :blog_posts, :url
end
end
@@ -1,9 +1,12 @@
class CreateHasSettingsSettings < ActiveRecord::Migration
def self.up
create_table :has_settings_settings do |t|
t.text :settings
t.integer :configurable_id
t.string :configurable_type
begin
create_table :has_settings_settings do |t|
t.text :settings
t.integer :configurable_id
t.string :configurable_type
end
rescue
end
end

Expand Down
4 changes: 4 additions & 0 deletions vendor/plugins/stringex/.gitignore
@@ -0,0 +1,4 @@
.DS_Store
doc
github-test.rb
test/*.sqlite3
20 changes: 20 additions & 0 deletions vendor/plugins/stringex/MIT-LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2008 Lucky Sneaks

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
76 changes: 76 additions & 0 deletions vendor/plugins/stringex/README.rdoc
@@ -0,0 +1,76 @@
= Stringex

Some [hopefully] useful extensions to Ruby's String class. It is made up of three libraries: ActsAsUrl, Unidecoder, and StringExtensions.

== ActsAsUrl

This library is designed to create URI-friendly representations of an attribute, for use in generating urls from your attributes. Basic usage is just calling the method:

acts_as_url :title

which will populate the <tt>url</tt> attribute on the object with the converted contents of the <tt>title</tt> attribute. This behavior can be customized by adding the following options to the arguments of the <tt>acts_as_url</tt> method:

<tt>:url_attribute</tt>:: The name of the attribute to use for storing the generated url string.
Default is <tt>:url</tt>
<tt>:scope</tt>:: The name of model attribute to scope unique urls to. There is no default here.
<tt>:only_when_blank</tt>:: If true, the url generation will only happen when <tt>:url_attribute</tt> is
blank. Default is false (meaning url generation will happen always)
<tt>:sync_url</tt>:: If set to true, the url field will be updated when changes are made to the
attribute it is based on. Default is false.

In order to use the generated url attribute, you will probably want to override <tt>to_param</tt> like so, in your Model:

def to_param
url # or whatever you set :url_attribute to
end

Routing called via named routes like <tt>foo_path(@foo)</tt> will automatically use the url. In your controllers you will need to call <tt>Foo.find_by_url(params[:id])</tt> instead of the regular find. Don't look for <tt>params[:url]</tt> unless you set it explicitly in the routing, <tt>to_param</tt> will generate <tt>params[:id]</tt>.

Unlike other permalink solutions, ActsAsUrl doesn't rely on Iconv (which is inconsistent across platforms and doesn't provide great transliteration as is) but instead uses a transliteration scheme (see the code for Unidecoder) which produces much better results for Unicode characters. It also mixes in some custom helpers to translate common characters into a more URI-friendly format rather than just dump them completely. Examples:

# A simple prelude
"simple English".to_url => "simple-english"
"it's nothing at all".to_url => "its-nothing-at-all"
"rock & roll".to_url => "rock-and-roll"

# Let's show off
"$12 worth of Ruby power".to_url => "12-dollars-worth-of-ruby-power"
"10% off if you act now".to_url => "10-percent-off-if-you-act-now"

# You don't even wanna trust Iconv for this next part
"kick it en Français".to_url => "kick-it-en-francais"
"rock it Español style".to_url => "rock-it-espanol-style"
"tell your readers 你好".to_url => "tell-your-readers-ni-hao"

Compare those results with the ones produced on my Intel Mac by a leading permalink plugin:

"simple English" # => "simple-english"
"it's nothing at all" # => "it-s-nothing-at-all"
"rock & roll" # => "rock-roll"

"$12 worth of Ruby power" # => "12-worth-of-ruby-power"
"10% off if you act now" # => "10-off-if-you-act-now"

"kick it en Français" # => "kick-it-en-francais"
"rock it Español style" # => "rock-it-espan-ol-style"
"tell your readers 你好" # => "tell-your-readers"

Not so great, actually.

Note: No offense is intended to the author[s] of whatever plugins might produce such results. It's not your faults Iconv sucks.

== Unidecoder

This library converts Unicode [and accented Ascii] characters to their plain-text Ascii equivalents. This is a port of Perl's Unidecode and provides eminently superior and more reliable results than Iconv. (Seriously, Iconv... A plague on both your houses! [sic])

You probably won't ever need to run Unidecoder by itself. StringExtensions adds String#to_ascii which wraps all of Unidecoder's functionality. For anyone interested, details of the implementation can be read about in the original implementation of Text::Unidecode[http://interglacial.com/~sburke/tpj/as_html/tpj22.html]. Extensive examples can be found in the tests.

== StringExtensions

A collection of extensions on Ruby's String class. Please see the documentation for string_extensions module for more information. There's not much to explain about them really.

== Thanks & Acknowledgements

If it's not obvious, some of the code for ActsAsUrl is based on Rick Olsen's permalink_fu[http://svn.techno-weenie.net/projects/plugins/permalink_fu/] plugin. Unidecoder is a Ruby port of Sean Burke's Text::Unidecode[http://interglacial.com/~sburke/tpj/as_html/tpj22.html] module for Perl. And, finally, the bulk of strip_html_tags[link:classes/LuckySneaks/StringExtensions.html#M000005] in StringExtensions was stolen from Tobias Lütke's Regex in Typo[http://typosphere.org/].

copyright (c) 2008 Lucky Sneaks, released under the MIT license
28 changes: 28 additions & 0 deletions vendor/plugins/stringex/Rakefile
@@ -0,0 +1,28 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'

desc 'Default: run unit tests.'
task :default => [:refresh_db, :test]

desc 'Remove old sqlite file'
task :refresh_db do
`rm -f #{File.dirname(__FILE__)}/test/acts_as_url.sqlite3`
end

desc 'Test the stringex plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end

desc 'Generate documentation for the stringex plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'doc'
rdoc.title = 'Stringex: A String Extension Pack'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.options << '--charset' << 'utf-8'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end
1 change: 1 addition & 0 deletions vendor/plugins/stringex/init.rb
@@ -0,0 +1 @@
require "stringex"
87 changes: 87 additions & 0 deletions vendor/plugins/stringex/lib/lucky_sneaks/acts_as_url.rb
@@ -0,0 +1,87 @@
module LuckySneaks
module ActsAsUrl # :nodoc:
def self.included(base)
base.extend ClassMethods
end

module ClassMethods # :doc:
# Creates a callback to automatically create an url-friendly representation
# of the <tt>attribute</tt> argument. Example:
#
# act_as_url :title
#
# will use the string contents of the <tt>title</tt> attribute
# to create the permalink. <strong>Note:</strong> you can also use a non-database-backed
# method to supply the string contents for the permalink. Just use that method's name
# as the argument as you would an attribute.
#
# The default attribute <tt>acts_as_url</tt> uses to save the permalink is <tt>url</tt>
# but this can be changed in the options hash. Available options are:
#
# <tt>:url_attribute</tt>:: The name of the attribute to use for storing the generated url string.
# Default is <tt>:url</tt>
# <tt>:scope</tt>:: The name of model attribute to scope unique urls to. There is no default here.
# <tt>:only_when_blank</tt>:: If true, the url generation will only happen when <tt>:url_attribute</tt> is
# blank. Default is false (meaning url generation will happen always)
# <tt>:sync_url</tt>:: If set to true, the url field will be updated when changes are made to the
# attribute it is based on. Default is false.
def acts_as_url(attribute, options = {})
cattr_accessor :attribute_to_urlify
cattr_accessor :scope_for_url
cattr_accessor :url_attribute # The attribute on the DB
cattr_accessor :only_when_blank

if options[:sync_url]
before_validation :ensure_unique_url
else
before_validation_on_create :ensure_unique_url
end

self.attribute_to_urlify = attribute
self.scope_for_url = options[:scope]
self.url_attribute = options[:url_attribute] || "url"
self.only_when_blank = options[:only_when_blank] || false
end

# Initialize the url fields for the records that need it. Designed for people who add
# <tt>acts_as_url</tt> support once there's already development/production data they'd
# like to keep around.
#
# Note: This method can get very expensive, very fast. If you're planning on using this
# on a large selection, you will get much better results writing your own version with
# using pagination.
def initialize_urls
find(:all, :conditions => {self.url_attribute => nil}).each do |instance|
instance.send :ensure_unique_url
instance.save
end
end
end

private
def ensure_unique_url
url_attribute = self.class.url_attribute
base_url = self.send(url_attribute)
base_url = self.send(self.class.attribute_to_urlify).to_s.to_url if base_url.blank? || !self.only_when_blank
conditions = ["#{url_attribute} LIKE ?", base_url+'%']
unless new_record?
conditions.first << " and id != ?"
conditions << id
end
if self.class.scope_for_url
conditions.first << " and #{self.class.scope_for_url} = ?"
conditions << send(self.class.scope_for_url)
end
url_owners = self.class.find(:all, :conditions => conditions)
if url_owners.size > 0
n = 1
while url_owners.detect{|u| u.send(url_attribute) == "#{base_url}-#{n}"}
n = n.succ
end
write_attribute url_attribute, "#{base_url}-#{n}"
else
write_attribute url_attribute, base_url
end
end
end
end

0 comments on commit 18d6417

Please sign in to comment.