Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit f74a0d4932290b6b696cadea5194892a22df3ab8 @rubenrails committed Feb 23, 2011
@@ -0,0 +1,6 @@
+pkg/*
+*.gem
+.bundle
+doc/*
+Gemfile.lock
+.yardoc
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in acts_as_opengraph.gemspec
+gemspec
@@ -0,0 +1,19 @@
+Copyright (c) 2011 Ruben Ascencio
+
+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.
@@ -0,0 +1,137 @@
+# acts\_as\_opengraph
+
+ActiveRecord extension that turns your models into [facebook opengraph](http://developers.facebook.com/docs/opengraph/) objects.
+
+## Installation
+
+ gem install acts_as_opengraph
+
+Now just add the gem dependency in your projects configuration.
+
+## Usage
+
+### Adding acts\_as\_opengraph
+
+ # app/models/movie.rb
+ class Movie < ActiveRecord::Base
+ acts_as_opengraph
+ end
+
+### Generating the opengraph meta tags
+
+ # app/views/layouts/application.html.erb
+ <head>
+ <%= yield :opengraph_meta_tags %>
+ </head>
+
+ # app/views/movies/show.html.erb
+ <% content_for :opengraph_meta_tags, opengraph_meta_tags_for(@movie) %>
+
+### Displaying the Like Button
+ # app/views/movies/show.html.erb
+ <%= like_button_for @movie %>
+
+\* Notice that the Like Button will retrieve the required `href` attribute by calling `@movie.opengraph_url`. Read below for more options.
+
+
+## Options
+
+### Database columns
+
+Even when the names of these columns can be changed with configuration, `acts_as_opengraph` tries to guess these names by checking for the existence of common names. Chances are that your model already has some of the opengraph defined properties.
+
+This is the list of supported opengraph protocol properties and their possible column names (in precedence order):
+
+* __title__ - og\_title, title, name
+* __type__ - og\_type, kind, category
+* __image__ - og\_image, image, photo, picture, thumb, thumbnail
+* __url__ - og\_url, url, uri, link
+* __description__ - og\_description, description, summary
+* __site\_name__ - og\_site, website, web
+* __latitude__ - og\_latitude, latitude
+* __longitude__ - og\_longitude, longitude
+* __street\_address__ - og\_street\_address, street_address, address, street
+* __locality__ - og\_locality, locality
+* __region__ - og\_region, region
+* __postal\_code__ - og\_postal\_code, postal\_code, zip\_code, zip
+* __country\_name__ - og\_country_name, country\_name, country
+* __email__ - og\_email, email, mail
+* __phone\_number__ - og\_phone\_number, phone\_number, phone
+* __fax\_number__ - og\_fax\_number, fax\_number, fax
+
+### Using a different column name
+
+If you need to use a different column then use the __columns__ option. For example, if you store the url of your movies using the `imdb_url` column in your movies table, then do this:
+
+ # app/models/movie.rb
+ acts_as_opengraph :columns => { :url => :imdb_url }
+
+### What about using a custom method?
+
+If you wish to use a custom method for some opengraph field, then all you need to do is to define a method with the prefix `opengraph_`.
+For example, if you are using [Paperclip](https://github.com/thoughtbot/paperclip) for your image attachments, you can do this:
+
+ # app/models/movie.rb
+ class Movie < ActiveRecord::Base
+
+ has_attached_file :picture, :styles => { :small => "160x130>"}
+
+ acts_as_opengraph
+
+ def opengraph_image
+ picture.url(:small)
+ end
+
+ end
+
+### Default values
+
+Use the __values__ option for passing default opengraph values. For our Movie example we can specify that all of our records are movies by doing this:
+
+ acts_as_opengraph :values => { :type => "movie" }
+
+\* Notice that `acts_as_opengraph` only accepts an options hash argument, so if you want to combine default values and column names you'd do this:
+
+ acts_as_opengraph :columns => { :url => :imdb_url, :email => :contact },
+ :values => { :type => "movie", :site_name => "http://example.com" }
+
+## Like Button options
+
+Along with the object for which you want to display the Like button, you can pass an options hash to configure its appearance:
+
+ # app/views/layouts/application.html.erb
+ <%= like_button_for @movie, :layout => :box_count, :show_faces => true %>
+
+### Using url helpers
+
+By default, `acts_as_opengraph` will try to retrieve your object's url by calling `opengraph_url` on it. You could override it by defining a custom method, like this:
+
+ # app/models/movie.rb
+ def opengraph_url
+ "http://example.com/movies/#{self.id}"
+ end
+
+But that's not the Rails way, so instead of doing that, you can pass an `href` option from your views, which means you can easily take advantage of the url helpers, like this:
+
+ # app/views/movies/show.html.erb
+ <%= like_button_for @movie, :href => movie_path(@movie) %>
+
+See the complete list of allowed attributes and options [here](http://developers.facebook.com/docs/reference/plugins/like/).
+
+## Note on Patches/Pull Requests
+
+* Fork the project.
+* Make your feature addition or bug fix.
+* Add tests for it. This is important so I don’t break it in a future version unintentionally.
+* Send me a pull request. Bonus points for topic branches.
+
+
+## Copyright
+
+Copyright &copy; 2011 Ruben Ascencio, released under the MIT license
+
+
+
+
+
+
@@ -0,0 +1,2 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "acts_as_opengraph/version"
+
+Gem::Specification.new do |s|
+ s.name = "acts_as_opengraph"
+ s.version = ActsAsOpengraph::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Ruben Ascencio"]
+ s.email = ["galateaweb@gmail.com"]
+ s.homepage = "https://github.com/rubenrails/acts_as_opengraph"
+ s.summary = %q{ActiveRecord extension that turns your models into graph objects}
+ s.description = %q{ActiveRecord extension that turns your models into graph objects. Includes helper methods for adding <meta> tags and the Like Button to your views.}
+
+ s.rubyforge_project = "acts_as_opengraph"
+
+ s.add_development_dependency('sqlite3')
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+end
@@ -0,0 +1,10 @@
+if defined? ActiveRecord::Base
+ require File.join(File.dirname(__FILE__), 'acts_as_opengraph', 'active_record', 'acts', 'opengraph')
+ ActiveRecord::Base.send :include, ActiveRecord::Acts::Opengraph
+end
+
+if defined? ActionView::Base
+ require File.join(File.dirname(__FILE__), 'acts_as_opengraph', 'helper', 'acts_as_opengraph_helper')
+ ActionView::Base.send :include, ActsAsOpengraphHelper
+end
+
@@ -0,0 +1,121 @@
+module ActiveRecord
+ module Acts
+ module Opengraph
+
+ def self.included(base)
+ base.extend ActMethods
+ end
+
+ module ActMethods
+ def acts_as_opengraph(options = {})
+ # don't allow multiple calls
+ return if included_modules.include? InstanceMethods
+
+ extend ClassMethods
+
+ opengraph_atts = %w(title type image url description site_name latitude longitude street_address locality region postal_code country_name email phone_number fax_number)
+
+ options[:columns] ||= {}
+ options[:values] ||= {}
+
+ opengraph_atts.each do |att_name|
+ options[:columns]["#{att_name}".to_sym] ||= alternative_column_name_for("og_#{att_name}".to_sym)
+ end
+
+ write_inheritable_attribute :opengraph_atts, opengraph_atts
+ class_inheritable_reader :opengraph_atts
+
+ write_inheritable_attribute :options, options
+ class_inheritable_reader :options
+
+ opengraph_atts.each do |att_name|
+ define_method "opengraph_#{att_name}" do
+ return_value_or_default att_name.to_sym
+ end
+ end
+
+ include InstanceMethods
+
+ end
+
+ end
+
+ module ClassMethods
+
+ private
+
+ # Returns a list of possible column names for a given attribute.
+ #
+ # @param [Symbol] att_name An opengraph attribute name prefixed with 'og_', i.e. :og_title, :og_type, etc
+ # @return [Array] A list of possible names for the given opengraph attribute
+ def alternative_names_for(att_name)
+ case att_name
+ when :og_title then [:title, :name]
+ when :og_type then [:kind, :category]
+ when :og_image then [:image, :photo, :picture, :thumb, :thumbnail]
+ when :og_url then [:url, :uri, :link]
+ when :og_description then [:description, :summary]
+ when :og_site_name then [:site, :website, :web]
+ when :og_latitude then [:latitude]
+ when :og_longitude then [:longitude]
+ when :og_street_address then [:street_address, :address, :street]
+ when :og_locality then [:locality]
+ when :og_region then [:region]
+ when :og_postal_code then [:postal_code, :zip_code, :zip]
+ when :og_country_name then [:country_name, :country]
+ when :og_email then [:email, :mail]
+ when :og_phone_number then [:phone_number, :phone]
+ when :og_fax_number then [:fax_number, :fax]
+ else []
+ end
+ end
+
+ # Tries to guess the column name for the given attribute. If it can't find any column (or similar) then it will create a virtual attribute
+ # for the object called: ATT_NAME_placeholder, so the object responds to that column.
+ #
+ # @param [Symbol] att_name An opengraph attribute name prefixed with 'og_', i.e. :og_title, :og_type, etc
+ # @return [String] The final name (found or created) for the opengraph attribute
+ def alternative_column_name_for(att_name)
+ alt_names = alternative_names_for(att_name)
+ columns_to_check = [att_name] + alt_names
+ columns_to_check.each do |column_name|
+ return column_name.to_sym if column_names.include?(column_name.to_s)
+ end
+
+ # Define placeholder method
+ ph_method_name = "#{alt_names.first}_placeholder"
+ define_method(ph_method_name) { "" }
+ ph_method_name
+ end
+
+ end
+
+ module InstanceMethods
+ # Returns an array of hashes representing the opengraph attribute/values for the Object.
+ #
+ # @return [Array] List of hashes representing opengraph attribute/values
+ # @example
+ # @movie.opengraph_data #=> {name=> "og:title", :value => "The Rock"}, {:name => "og:type", :value=> "movie"}
+ def opengraph_data
+ data_list = opengraph_atts.map do |att_name|
+ {:name => "og:#{att_name}", :value => self.send("opengraph_#{att_name}")}
+ end
+ data_list.delete_if{ |el| el[:value].blank? }
+ end
+
+
+ private
+
+ def return_value_or_default(att_name)
+ if options[:values].has_key?(att_name.to_sym)
+ options[:values][att_name]
+ else
+ self.send options[:columns]["#{att_name}".to_sym]
+ end
+ end
+
+ end
+
+ end
+ end
+end
@@ -0,0 +1,48 @@
+module ActsAsOpengraphHelper
+ # Generates the opengraph meta tags for your views
+ #
+ # @param [Object, #opengraph_data] obj An instance of your ActiveRecord model that responds to opengraph_data
+ # @return [String] A set of meta tags describing your graph object based on the {http://ogp.me/ opengraph protocol}
+ # @raise [ArgumentError] When you pass an instance of an object that doesn't responds to opengraph_data (maybe you forgot to add acts_as_opengraph in your model)
+ # @example
+ # opengraph_meta_tags_for(@movie)
+ def opengraph_meta_tags_for(obj)
+ raise(ArgumentError.new, "You need to call acts_as_opengraph on your #{obj.class} model") unless obj.respond_to?(:opengraph_data)
+ tags = obj.opengraph_data.map do |att|
+ %(<meta name="#{att[:name].dasherize}" content="#{Rack::Utils.escape_html(att[:value])}"/>)
+ end
+ tags = tags.join("\n")
+ tags.respond_to?(:html_safe) ? tags.html_safe : tags
+ end
+
+ # Displays the Facebook Like Button in your views.
+ #
+ # @param [Object, #opengraph_data] obj An instance of your ActiveRecord model that responds to opengraph_data
+ # @param [Hash] options A Hash of {http://developers.facebook.com/docs/reference/plugins/like/ supported attributes}. Defaults to { :layout => :standard, :show_faces => false, :width => 450, :action => :like, :colorscheme => :light }
+ # @return [String] An iFrame version of the Facebook Like Button
+ # @raise [ArgumentError] When you pass an instance of an object that doesn't responds to opengraph_data (maybe you forgot to add acts_as_opengraph in your model)
+ # @example
+ # like_button_for(@movie)
+ # like_button_for(@movie, :layout => :button_count, :display_faces => true)
+ # @example Specifying href using rails helpers
+ # like_button_for(@movie, :href => movie_url(@movie))
+ def like_button_for(obj, options = {})
+ raise(ArgumentError.new, "You need to call acts_as_opengraph on your #{obj.class} model") unless obj.respond_to?(:opengraph_data)
+ href = options[:href] ? options[:href] : obj.opengraph_url
+ return unless href.present?
+
+ config = { :layout => :standard, :show_faces => false, :width => 450, :action => :like, :colorscheme => :light }
+ config.update(options) if options.is_a?(Hash)
+
+ o_layout = config[:layout].to_sym
+ if o_layout == :standard
+ config[:height] = config[:show_faces].to_s.to_sym == :true ? 80 : 35
+ elsif o_layout == :button_count
+ config[:height] = 21
+ elsif o_layout == :box_count
+ config[:height] = 65
+ end
+
+ %(<iframe src="http://www.facebook.com/plugins/like.php?href=#{CGI.escape(href)}&amp;layout=#{config[:layout]}&amp;show_faces=#{config[:show_faces]}&amp;width=#{config[:width]}&amp;action=#{config[:action]}&amp;colorscheme=#{config[:colorscheme]}&amp;height=#{config[:height]}" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:#{config[:width]}px; height:#{config[:height]}px;" allowTransparency="true"></iframe>)
+ end
+end
@@ -0,0 +1,3 @@
+module ActsAsOpengraph
+ VERSION = "0.0.1"
+end
Oops, something went wrong.

0 comments on commit f74a0d4

Please sign in to comment.