module RailsConnector # This class provides an interfaces for handling CMS Links. # To format a link for rendering in an html page, use the +cms_path+ or +cms_url+ methods. # @api public class Link extend ActiveModel::Naming # Create a new link obj # @api public # @param [Hash] link_data # @option link_data [String] url # @option link_data [RailsConnector::BasicObj] obj # @option link_data [String] title # @option link_data [String] query # @option link_data [String] target # @option link_data [String] fragment def initialize(link_data) @link_data = link_data.with_indifferent_access end # The link's external url. Only available for external links. # Warning: Do not output the url directly unless you know what you are doing. # Normally you want to use the +cms_path+ or +cms_url+ methods to format a link. # @api public def url @link_data[:url] end # Set the link's external url. This will lead to an external link. # @api public # @param value [String] the url of the link def url=(value) @link_data[:url] = value end # Returns the (+Obj+) this link is referencing. May be nil if the # link is external. # @api public def obj @link_data[:obj] end # Set the (+Obj+) this link is referencing. May be nil if the # link is external. # @api public # @param value [RailsConnector::BasicObj] the obj this link should be referencing def obj=(value) @link_data[:obj] = value end # The link's title. # @api public def title @link_data[:title] end # Set the link's title. # @api public # @param value [String] the link's title def title=(value) @link_data[:title] = value end # Returns the link's query string as in "index.html?query_string". # See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt). # @api public def query @link_data[:query] end # Set the link's query string as in "index.html?query_string". # See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt). # @api public # @param value [String] the query string of the link def query=(value) @link_data[:query] = value end # Returns the link's anchor as in "index.html#anchor". # See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt). # @api public def fragment @link_data[:fragment] end # Set the link's anchor as in "index.html#anchor". # See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt). # @api public # @param value [String] the anchor or fragement of the link def fragment=(value) @link_data[:fragment] = value end # Returns the browser window or browser frame to be used as a target for this link. # Example: Links that should be opened in a new window will return "_blank" as their target. # @api public def target @link_data[:target] end # Set the browser window or browser frame to be used as a target for this link. # Example: Links that should be opened in a new window will return "_blank" as their target. # @api public # @param value [String] the target of the link def target=(value) @link_data[:target] = value end def id @link_data[:link_id] end def tag_name @link_data[:tag_name] end def tag_name=(value) @link_data[:tag_name] = value end # Returns the file extension (e.g. zip, pdf) of this link's (internal or external) target. # Returns an empty string if the file extension is can not be determined. # @api public def file_extension if internal? obj ? obj.file_extension : "" else path = URI.parse(url).path rescue nil path.blank? ? "" : File.extname(path)[1..-1] || "" end end # Returns the id of the Links' destination_object. # @api public # @deprecated use {#obj}.id instead def destination_object_id deprecation_warning(:destination_object_id, 'obj.id') obj.id end # Returns the title of this Link if it is set. # Otherwise it returns the display_title of the destination object for internal Links # or the URL for external Links. # @api public def display_title dt = title dt = obj.display_title if dt.blank? && !external? dt = url if dt.blank? dt end # Returns true this Link links to a CMS Object. # @api public def internal? url.nil? end # Returns true if this Link links to an external URL. # @api public def external? !internal? end # An internal Link is active if it's destination object is active. # An external Link is always active. # @api public def active? external? || (obj && obj.active?) end def external_prefix? nil != (url =~ /\s?external:/) end def resolved? external? || resolved_internal? end # Returns the destination object (+Obj+) of this Link. May be nil if the # link is external or internal without an existing destination object. # @api public # @deprecated use {#obj} instead def destination_object deprecation_warning(:destination_object, :obj) obj end def html_attribute_snippet parts = [] parts << %{alt="#{title}"} if tag_name == 'img' || tag_name == 'input' parts << %{title="#{title}"} if (tag_name == 'a' || tag_name == 'link') && title.present? parts << %{target="#{target}"} if target.present? parts.join(' ') end def query_and_fragment str = '' str << "?#{query}" if query.present? str << "##{fragment}" if fragment.present? str end def internal_url "objid:#{obj.id}" end def external_url external_prefix? ? url.gsub(/external:/, '').strip : url end private def resolved_internal? internal? && !obj.nil? end def deprecation_warning(method, alternative) ActiveSupport::Deprecation.warn( "[DEPRECATION] The medod #{method} will be removed from the RailsConnector. Please use #{alternative} instead" ) end end end