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. class Link extend ActiveModel::Naming def initialize(link_data, destination_object = nil) #:nodoc: @link_data = link_data.symbolize_keys @destination_object = destination_object 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. def url @link_data[:url] end # The link's title. def title @link_data[:title] end # Returns the link's query string as in "index.html?query_string". # See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt). def query @link_data[:query] end # Depricated: use Link#query instead. # Returns the link's query string as in "index.html?query_string". # See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt). def search query end # Returns the link's anchor as in "index.html#anchor". # See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt). def fragment @link_data[:fragment] 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. def target @link_data[:target] end def id #:nodoc: @link_data[:link_id] end def tag_name # :nodoc: @link_data[:tag_name] end def markdown_type # :nodoc: @link_data[:markdown_type] end def markdown? # :nodoc: 'markdown' == @link_data[:source_format] 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. def file_extension if internal? destination_object ? destination_object.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. def destination_object_id destination 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. def display_title dt = title dt = destination_object.display_title if dt.blank? && !external? dt = url if dt.blank? dt end # Returns true this Link links to a CMS Object. def internal? url.nil? end # Returns true if this Link links to an external URL. def external? !internal? end # An internal Link is active if it's destination object is active. # An external Link is always active. def active? external? || (destination_object && destination_object.active?) end def external_prefix? #:nodoc: nil != (url =~ /\s?external:/) end def resolved? #:nodoc: 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. def destination_object @destination_object ||= Obj.find(destination) if resolved_internal? rescue RailsConnector::ResourceNotFound nil end def to_liquid # :nodoc: LiquidSupport::LinkDrop.new(self) end private def resolved_internal? internal? && !destination.nil? end def destination @link_data[:destination] end end end