[Git][noosfero/noosfero][master] 9 commits: metadata: customize og_type via param and use controllers class

Bráulio Bhavamitra gitlab at gitlab.com
Mon Aug 10 02:14:22 BRT 2015


Bráulio Bhavamitra pushed to branch master at Noosfero / noosfero


Commits:
b859be43 by Braulio Bhavamitra at 2015-08-09T21:02:07Z
metadata: customize og_type via param and use controllers class

- - - - -
f4b390dc by Braulio Bhavamitra at 2015-08-09T21:02:07Z
metadata: use country_name from environment

- - - - -
b018bca7 by Braulio Bhavamitra at 2015-08-09T21:02:08Z
metadata: customize event og:type

- - - - -
1df5fcff by Braulio Bhavamitra at 2015-08-09T21:02:08Z
metadata: add forum og:type

- - - - -
be35b464 by Braulio Bhavamitra at 2015-08-09T21:03:26Z
metadata: give url without redirects for profiles

- - - - -
8dc2e2b6 by Braulio Bhavamitra at 2015-08-09T21:03:26Z
environment: add location fields

- - - - -
8732ba33 by Braulio Bhavamitra at 2015-08-09T21:04:30Z
metadata: use environment data for required fields

- - - - -
fb028d5a by Braulio Bhavamitra at 2015-08-10T01:54:17Z
metadata: fix tests

- - - - -
a067af01 by Bráulio Bhavamitra at 2015-08-10T05:13:15Z
Merge branch 'metadata-plugin' into 'master'

metadata: allow customization of og_type via param

Also:
- define controllers code via class to allow customization via `alias_method_chain` for monkey patching
- define plugin using Base class to avoid conflicts with the `Controllers` class defined by RSpec

See merge request !493

- - - - -


18 changed files:

- app/models/environment.rb
- plugins/metadata/config.yml.dist
- plugins/metadata/lib/ext/article.rb
- plugins/metadata/lib/ext/community.rb
- plugins/metadata/lib/ext/enterprise.rb
- plugins/metadata/lib/ext/environment.rb
- + plugins/metadata/lib/ext/event.rb
- + plugins/metadata/lib/ext/forum.rb
- plugins/metadata/lib/ext/person.rb
- plugins/metadata/lib/ext/product.rb
- plugins/metadata/lib/ext/profile.rb
- plugins/metadata/lib/ext/uploaded_file.rb
- plugins/metadata/lib/metadata_plugin.rb
- + plugins/metadata/lib/metadata_plugin/base.rb
- + plugins/metadata/lib/metadata_plugin/controllers.rb
- + plugins/metadata/lib/metadata_plugin/url_helper.rb
- plugins/metadata/test/functional/home_controller_test.rb
- plugins/metadata/test/functional/manage_products_controller_test.rb


Changes:

=====================================
app/models/environment.rb
=====================================
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -285,7 +285,20 @@ class Environment < ActiveRecord::Base
   settings_items :activation_blocked_text, :type => String
   settings_items :message_for_disabled_enterprise, :type => String,
                  :default => _('This enterprise needs to be enabled.')
-  settings_items :location, :type => String
+
+  settings_items :contact_phone, type: String
+  settings_items :address, type: String
+  settings_items :city, type: String
+  settings_items :state, type: String
+  settings_items :country_name, type: String
+  settings_items :lat, type: Float
+  settings_items :lng, type: Float
+  settings_items :postal_code, type: String
+  settings_items :location, type: String
+
+  alias_method :zip_code=, :postal_code
+  alias_method :zip_code, :postal_code
+
   settings_items :layout_template, :type => String, :default => 'default'
   settings_items :homepage, :type => String
   settings_items :description, :type => String, :default => '<div style="text-align: center"><a href="http://noosfero.org/"><img src="/images/noosfero-network.png" alt="Noosfero"/></a></div>'


=====================================
plugins/metadata/config.yml.dist
=====================================
--- a/plugins/metadata/config.yml.dist
+++ b/plugins/metadata/config.yml.dist
@@ -1,12 +1,17 @@
 open_graph:
   domain: domainregisteredonfacebook.com
   environment_logo: 'http://example.com/designs/themes/environmenttheme/images/logo.png'
+  namespace: app_scope
   types:
     article: article
-    product: facebook_app:sse_product
-    uploaded_file: facebook_app:document
-    image: facebook_app:picture
-    profile: facebook_app:profile
-    person: facebook_app:user
-    community: facebook_app:community
-    enterprise: facebook_app:sse_initiative
+    event: app_scope:event
+    forum: app_scope:discussion
+    uploaded_file: app_scope:document
+    image: app_scope:picture
+
+    product: app_scope:sse_product
+
+    profile: app_scope:profile
+    person: app_scope:user
+    community: app_scope:community
+    enterprise: app_scope:sse_initiative


=====================================
plugins/metadata/lib/ext/article.rb
=====================================
--- a/plugins/metadata/lib/ext/article.rb
+++ b/plugins/metadata/lib/ext/article.rb
@@ -3,14 +3,19 @@ require_dependency 'article'
 class Article
 
   metadata_spec namespace: :og, key_attr: :property, tags: {
-    type: MetadataPlugin.og_types[:article] || :article,
-    url: proc{ |a, plugin| plugin.og_url_for a.url },
+    type: proc do |a, plugin|
+      plugin.context.params[:og_type] || MetadataPlugin.og_types[:article] || :article
+    end,
+    url: proc do |a, plugin|
+      url = a.url.merge! profile: a.profile.identifier, og_type: plugin.context.params[:og_type]
+      plugin.og_url_for url
+    end,
     title: proc{ |a, plugin| "#{a.title} - #{a.profile.name}" },
     image: proc do |a, plugin|
-      result = a.body_images_paths
-      result = "#{a.profile.environment.top_url}#{a.profile.image.public_filename}" if a.profile.image if result.blank?
-      result ||= MetadataPlugin.config[:open_graph][:environment_logo] rescue nil if result.blank?
-      result
+      img = a.body_images_paths
+      img = "#{a.profile.environment.top_url}#{a.profile.image.public_filename}" if a.profile.image if img.blank?
+      img ||= MetadataPlugin.config[:open_graph][:environment_logo] rescue nil if img.blank?
+      img
     end,
     see_also: [],
     site_name: proc{ |a, c| a.profile.name },


=====================================
plugins/metadata/lib/ext/community.rb
=====================================
--- a/plugins/metadata/lib/ext/community.rb
+++ b/plugins/metadata/lib/ext/community.rb
@@ -4,7 +4,7 @@ require_dependency "#{File.dirname __FILE__}/profile"
 class Community
 
   metadata_spec namespace: :og, tags: {
-    type: MetadataPlugin.og_types[:community] || :community,
+    type: proc{ |c, plugin| plugin.context.params[:og_type] || MetadataPlugin.og_types[:community] || :community },
   }
 
 end


=====================================
plugins/metadata/lib/ext/enterprise.rb
=====================================
--- a/plugins/metadata/lib/ext/enterprise.rb
+++ b/plugins/metadata/lib/ext/enterprise.rb
@@ -4,17 +4,24 @@ require_dependency "#{File.dirname __FILE__}/profile"
 class Enterprise
 
   metadata_spec namespace: :og, tags: {
-    type: MetadataPlugin.og_types[:enterprise] || :enterprise,
+    type: proc{ |e, plugin| plugin.context.params[:og_type] || MetadataPlugin.og_types[:enterprise] || :enterprise },
+  }
+
+  # required for businness
+  metadata_spec namespace: 'place:location', tags: {
+    latitude: proc{ |e, plugin| if e.lat.present? then e.lat else e.environment.lat end },
+    longitude: proc{ |e, plugin| if e.lng.present? then e.lng else e.environment.lng end },
   }
 
   metadata_spec namespace: 'business:contact_data', tags: {
-    email: proc{ |e, plugin| e.contact_email },
-	  phone_number: proc{ |e, plugin| e.contact_phone },
-	  street_address: proc{ |e, plugin| e.address },
-	  locality: proc{ |e, plugin| e.city },
-	  region: proc{ |e, plugin| e.state },
-	  postal_code: proc{ |e, plugin| e.zip_code },
-	  country_name: proc{ |e, plugin| e.country },
+    # all required
+    email: proc{ |e, plugin| if e.contact_email.present? then e.contact_email else e.environment.contact_email end },
+    phone_number: proc{ |e, plugin| if e.contact_phone.present? then e.contact_phone else e.environment.contact_phone end },
+    street_address: proc{ |e, plugin| if e.address.present? then e.address else e.environment.address end },
+    locality: proc{ |e, plugin| if e.city.present? then e.city else e.environment.city end },
+    region: proc{ |e, plugin| if e.state.present? then e.state else e.environment.state end },
+    postal_code: proc{ |e, plugin| if e.zip_code.present? then e.zip_code else e.environment.postal_code end },
+    country_name: proc{ |e, plugin| if e.country.present? then e.country else e.environment.country_name end },
   }
 
 end


=====================================
plugins/metadata/lib/ext/environment.rb
=====================================
--- a/plugins/metadata/lib/ext/environment.rb
+++ b/plugins/metadata/lib/ext/environment.rb
@@ -7,7 +7,7 @@ class Environment
   }
 
   metadata_spec namespace: :og, tags: {
-    type: 'website',
+    type: proc{ |e, plugin| plugin.context.params[:og_type] || 'website' },
     title: proc{ |e, plugin| e.name },
     site_name: proc{ |e, plugin| e.name },
     description: proc{ |e, plugin| e.name },


=====================================
plugins/metadata/lib/ext/event.rb
=====================================
--- /dev/null
+++ b/plugins/metadata/lib/ext/event.rb
@@ -0,0 +1,9 @@
+require_dependency 'event'
+
+class Event
+
+  metadata_spec namespace: :og, tags: {
+    type: proc{ |p, plugin| plugin.context.params[:og_type] || MetadataPlugin.og_types[:event] || :event },
+  }
+
+end


=====================================
plugins/metadata/lib/ext/forum.rb
=====================================
--- /dev/null
+++ b/plugins/metadata/lib/ext/forum.rb
@@ -0,0 +1,9 @@
+require_dependency 'forum'
+
+class Forum
+
+  metadata_spec namespace: :og, tags: {
+    type: proc{ |p, plugin| plugin.context.params[:og_type] || MetadataPlugin.og_types[:forum] || :forum },
+  }
+
+end


=====================================
plugins/metadata/lib/ext/person.rb
=====================================
--- a/plugins/metadata/lib/ext/person.rb
+++ b/plugins/metadata/lib/ext/person.rb
@@ -4,7 +4,7 @@ require_dependency "#{File.dirname __FILE__}/profile"
 class Person
 
   metadata_spec namespace: :og, tags: {
-    type: MetadataPlugin.og_types[:person] || :person,
+    type: proc{ |p, plugin| plugin.context.params[:og_type] || MetadataPlugin.og_types[:person] || :person },
   }
 
 end


=====================================
plugins/metadata/lib/ext/product.rb
=====================================
--- a/plugins/metadata/lib/ext/product.rb
+++ b/plugins/metadata/lib/ext/product.rb
@@ -3,14 +3,22 @@ require_dependency 'product'
 class Product
 
   metadata_spec namespace: :og, tags: {
-    type: MetadataPlugin.og_types[:product] || :product,
-    url: proc{ |p, plugin| plugin.og_url_for p.url },
+    type: proc{ |p, plugin| plugin.context.params[:og_type] || MetadataPlugin.og_types[:product] || :product },
+    url: proc do |p, plugin|
+      url = p.url.merge! profile: p.profile.identifier, og_type: plugin.context.params[:og_type]
+      plugin.og_url_for url
+    end,
     gr_hascurrencyvalue: proc{ |p, plugin| p.price.to_f },
     gr_hascurrency: proc{ |p, plugin| p.environment.currency_unit },
     title: proc{ |p, plugin| "#{p.name} - #{p.profile.name}" if p },
     description: proc{ |p, plugin| ActionView::Base.full_sanitizer.sanitize p.description },
 
-    image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image },
+    image: proc do |p, plugin|
+      img = "#{p.environment.top_url}#{p.image.public_filename}" if p.image
+      img = "#{p.environment.top_url}#{p.profile.image.public_filename}" if img.blank? and p.profile.image
+      img ||= MetadataPlugin.config[:open_graph][:environment_logo] rescue nil if img.blank?
+      img
+    end,
     'image:type' => proc{ |p, plugin| p.image.content_type if p.image },
     'image:height' => proc{ |p, plugin| p.image.height if p.image },
     'image:width' => proc{ |p, plugin| p.image.width if p.image },


=====================================
plugins/metadata/lib/ext/profile.rb
=====================================
--- a/plugins/metadata/lib/ext/profile.rb
+++ b/plugins/metadata/lib/ext/profile.rb
@@ -3,13 +3,14 @@ require_dependency 'profile'
 class Profile
 
   metadata_spec namespace: :og, tags: {
-    type: MetadataPlugin.og_types[:profile] || :profile,
-    image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image },
-    title: proc{ |p, plugin| if p.nickname.present? then p.nickname else p.name end },
-    url: proc do |p, plugin|
-      #force profile identifier for custom domains and fixed host. see og_url_for
-      plugin.og_url_for p.url.merge(profile: p.identifier)
+    type: proc{ |p, plugin| plugin.context.params[:og_type] || MetadataPlugin.og_types[:profile] || :profile },
+    image: proc do |p, plugin|
+      img = "#{p.environment.top_url}#{p.image.public_filename}" if p.image
+      img ||= MetadataPlugin.config[:open_graph][:environment_logo] rescue nil if img.blank?
+      img
     end,
+    title: proc{ |p, plugin| if p.nickname.present? then p.nickname else p.name end },
+    url: proc{ |p, plugin| plugin.og_url_for plugin.og_profile_url(p) },
     description: proc{ |p, plugin| p.description },
 	  updated_time: proc{ |p, plugin| p.updated_at.iso8601 },
     'locale:locale' => proc{ |p, plugin| p.environment.default_language },


=====================================
plugins/metadata/lib/ext/uploaded_file.rb
=====================================
--- a/plugins/metadata/lib/ext/uploaded_file.rb
+++ b/plugins/metadata/lib/ext/uploaded_file.rb
@@ -6,9 +6,12 @@ class UploadedFile
   metadata_spec namespace: :og, tags: {
     type: proc do |u, plugin|
       type = if u.image? then :image else :uploaded_file end
-      MetadataPlugin.og_types[type] || type
+      plugin.context.params[:og_type] || MetadataPlugin.og_types[type] || type
+    end,
+    url: proc do |u, plugin|
+      url = u.url.merge! profile: u.profile.identifier, view: true, og_type: plugin.context.params[:og_type]
+      plugin.og_url_for url
     end,
-    url: proc{ |u, plugin| plugin.og_url_for u.url.merge(view: true) },
     title: proc{ |u, plugin| u.title },
     image: proc{ |u, plugin| "#{u.environment.top_url}#{u.public_filename}" if u.image? },
     description: proc{ |u, plugin| u.abstract || u.title },


=====================================
plugins/metadata/lib/metadata_plugin.rb
=====================================
--- a/plugins/metadata/lib/metadata_plugin.rb
+++ b/plugins/metadata/lib/metadata_plugin.rb
@@ -1,5 +1,7 @@
 
-class MetadataPlugin < Noosfero::Plugin
+module MetadataPlugin
+
+  extend Noosfero::Plugin::ParentMethods
 
   def self.plugin_name
     _('Export metadata')
@@ -13,89 +15,14 @@ class MetadataPlugin < Noosfero::Plugin
     @config ||= HashWithIndifferentAccess.new(YAML.load File.read("#{File.dirname __FILE__}/../config.yml")) rescue {}
   end
 
-  def self.og_types
-    @og_types ||= self.config[:open_graph][:types] rescue {}
-  end
-
-  CONTROLLERS = {
-    manage_products: {
-      variable: :@product,
-    },
-    content_viewer: {
-      variable: proc do
-        if profile and @page and profile.home_page_id == @page.id
-          @profile
-        elsif @page.respond_to? :encapsulated_file
-          @page.encapsulated_file
-        else
-          @page
-        end
-      end,
-    },
-    profile: {
-      variable: :@profile,
-    },
-    # fallback
-    environment: {
-      variable: :@environment,
-    },
-  }
-
-  def head_ending
-    plugin = self
-    lambda do
-      options = MetadataPlugin::CONTROLLERS[controller.controller_path.to_sym]
-      options ||= MetadataPlugin::CONTROLLERS[:profile] if controller.is_a? ProfileController
-      options ||= MetadataPlugin::CONTROLLERS[:environment]
-      return unless options
-
-      return unless object = case variable = options[:variable]
-        when Proc then instance_exec(&variable)
-        else instance_variable_get variable
-        end
-      return if object.respond_to? :public? and not object.public?
-      return unless specs = (object.class.metadata_specs rescue nil)
-
-      r = []
-      specs.each do |namespace, spec|
-        namespace = "#{namespace}:" if namespace.present?
-        key_attr = spec[:key_attr] || :property
-        value_attr = spec[:value_attr] || :content
-        tags = spec[:tags]
-
-        tags.each do |key, values|
-          key = "#{namespace}#{key}"
-          values = values.call(object, plugin) if values.is_a? Proc
-          next if values.blank?
-
-          Array(values).each do |value|
-            value = value.call(object, plugin) if value.is_a? Proc
-            next if value.blank?
-            r << tag(:meta, key_attr => key, value_attr => value)
-          end
-        end
-      end
-      r.join
-    end
-  end
-
-  # context HELPERS
-  def og_url_for options
-    options.delete :port
-    options[:host] = self.class.config[:open_graph][:domain] rescue context.send(:environment).default_hostname
-    Noosfero::Application.routes.url_helpers.url_for options
+  def self.og_config
+    @og_config ||= self.config[:open_graph] rescue {}
   end
-
-  def helpers
-    self.context.class.helpers
+  def self.og_types
+    @og_types ||= self.og_config[:types] rescue {}
   end
 
-  protected
-
-end
+  mattr_accessor :controllers
+  self.controllers = MetadataPlugin::Controllers.new
 
-ActiveSupport.run_load_hooks :metadata_plugin, MetadataPlugin
-ActiveSupport.on_load :active_record do
-  ActiveRecord::Base.extend MetadataPlugin::Specs::ClassMethods
 end
-


=====================================
plugins/metadata/lib/metadata_plugin/base.rb
=====================================
--- /dev/null
+++ b/plugins/metadata/lib/metadata_plugin/base.rb
@@ -0,0 +1,75 @@
+
+class MetadataPlugin::Base < Noosfero::Plugin
+
+  def self.plugin_name
+    _('Export metadata')
+  end
+
+  def self.plugin_description
+    _('Export metadata for models on meta tags')
+  end
+
+  def self.config
+    @config ||= HashWithIndifferentAccess.new(YAML.load File.read("#{File.dirname __FILE__}/../config.yml")) rescue {}
+  end
+
+  def self.og_types
+    @og_types ||= self.config[:open_graph][:types] rescue {}
+  end
+
+  class_attribute :controllers
+  self.controllers = MetadataPlugin::Controllers.new
+
+  def head_ending
+    plugin = self
+    lambda do
+      variable = plugin.class.controllers.send controller.controller_path rescue nil
+      variable ||= plugin.class.controllers.send :profile if controller.is_a? ProfileController
+      variable ||= plugin.class.controllers.send :home
+      return unless variable
+
+      return unless object = case variable
+        when Proc then instance_exec(&variable)
+        else instance_variable_get variable
+        end
+      return if object.respond_to? :public? and not object.public?
+      return unless specs = (object.class.metadata_specs rescue nil)
+
+      r = []
+      specs.each do |namespace, spec|
+        namespace = "#{namespace}:" if namespace.present?
+        key_attr = spec[:key_attr] || :property
+        value_attr = spec[:value_attr] || :content
+        tags = spec[:tags]
+
+        tags.each do |key, values|
+          key = "#{namespace}#{key}"
+          values = values.call(object, plugin) if values.is_a? Proc rescue nil
+          next if values.blank?
+
+          Array(values).each do |value|
+            value = value.call(object, plugin) if value.is_a? Proc rescue nil
+            next if value.blank?
+            r << tag(:meta, key_attr => key, value_attr => CGI.escape_html(value.to_s))
+          end
+        end
+      end
+      r.join
+    end
+  end
+
+  include MetadataPlugin::UrlHelper
+
+  def helpers
+    self.context.class.helpers
+  end
+
+  protected
+
+end
+
+ActiveSupport.run_load_hooks :metadata_plugin, MetadataPlugin
+ActiveSupport.on_load :active_record do
+  ActiveRecord::Base.extend MetadataPlugin::Specs::ClassMethods
+end
+


=====================================
plugins/metadata/lib/metadata_plugin/controllers.rb
=====================================
--- /dev/null
+++ b/plugins/metadata/lib/metadata_plugin/controllers.rb
@@ -0,0 +1,27 @@
+class MetadataPlugin::Controllers
+
+  def manage_products
+    :@product
+  end
+
+  def content_viewer
+    lambda do
+      if profile and @page and profile.home_page_id == @page.id
+        @profile
+      elsif @page.respond_to? :encapsulated_file
+        @page.encapsulated_file
+      else
+        @page
+      end
+    end
+  end
+
+  def profile
+    :@profile
+  end
+
+  def home
+    :@environment
+  end
+
+end


=====================================
plugins/metadata/lib/metadata_plugin/url_helper.rb
=====================================
--- /dev/null
+++ b/plugins/metadata/lib/metadata_plugin/url_helper.rb
@@ -0,0 +1,23 @@
+module MetadataPlugin::UrlHelper
+
+  def og_domain
+    MetadataPlugin.config[:open_graph][:domain] rescue context.send(:environment).default_hostname
+  end
+
+  def og_url_for options
+    options.delete :port
+    options[:host] = self.og_domain
+    Noosfero::Application.routes.url_helpers.url_for options
+  end
+
+  def og_profile_url profile
+    # open_graph client don't like redirects, give the exact url
+    if profile.home_page_id.present?
+      # force profile identifier for custom domains and fixed host. see og_url_for
+      profile.url.merge profile: profile.identifier
+    else
+      {controller: :profile, profile: profile.identifier}
+    end
+  end
+
+end


=====================================
plugins/metadata/test/functional/home_controller_test.rb
=====================================
--- a/plugins/metadata/test/functional/home_controller_test.rb
+++ b/plugins/metadata/test/functional/home_controller_test.rb
@@ -11,8 +11,9 @@ class HomeControllerTest < ActionController::TestCase
     @request    = ActionController::TestRequest.new
     @response   = ActionController::TestResponse.new
 
-    Noosfero::Plugin.stubs(:all).returns([MetadataPlugin.name])
-    Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([MetadataPlugin.new(@controller)])
+    @environment = Environment.default
+    @environment.enabled_plugins += ['MetadataPlugin']
+    @environment.save!
   end
 
   should 'display meta tags for social media' do


=====================================
plugins/metadata/test/functional/manage_products_controller_test.rb
=====================================
--- a/plugins/metadata/test/functional/manage_products_controller_test.rb
+++ b/plugins/metadata/test/functional/manage_products_controller_test.rb
@@ -16,8 +16,8 @@ class ManageProductsControllerTest < ActionController::TestCase
     @environment.enable('products_for_enterprises')
     login_as :test_user
 
-    Noosfero::Plugin.stubs(:all).returns([MetadataPlugin.name])
-    Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([MetadataPlugin.new(@controller)])
+    @environment.enabled_plugins += ['MetadataPlugin']
+    @environment.save!
   end
 
   should "not crash on new products" do



View it on GitLab: https://gitlab.com/noosfero/noosfero/compare/945956c1e3fe5e232e2b6ea6425be13b94155c7a...a067af0109ddb54ee05fbbf3f4ca588e28eac23b
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listas.softwarelivre.org/pipermail/noosfero-dev/attachments/20150810/99da42c1/attachment-0001.html>


More information about the Noosfero-dev mailing list