module RailsConnector # This module contains a helper that can be used to render attributes of the CMS models. # @api public module DisplayHelper # For a consistent look of your site and easy maintenance, only the display helpers # should be used to render an attribute value of a CMS model. # # <%= display_value @obj.title %> # Renders the value, taking its type into account. # * An HtmlString will be exported by converting its links # * A Time will be exported in an international form: Year-Month-Day Hour:Minutes # * A non-HTML String will be quoted # * other values will be rendered unchanged # # @api public def display_value(value) case value when MarkdownString then markdown(convert_links(value)).html_safe when HtmlString then convert_links(value).html_safe when String then html_escape_once(value).html_safe when Time then html_escape_once(l(value)).html_safe else value end end def display_original_value(value) case value when HtmlString then convert_links(value, ignore_body_data_url: true).html_safe else display_value(value) end end # Renders a field from the CMS, including an edit marker for the preview # If the option :marker is +false+, no edit marker will be rendered. # # <%= display_field @obj, :title %> # # When creating an edit marker, all options except :marker are passed to {MarkerHelper#edit_marker}. # # @api public def display_field(obj, attr, options = {}) options.reverse_merge!({ marker: !%i(id path created last_changed version).include?(attr.to_sym) }) if options.delete :marker edit_marker(obj, attr, options) do |obj, attr| display_value obj[attr] end else display_value obj[attr] end end # Legacy method - deprecated # # Use display_value and display_field instead def display(*args) options = if args.last.is_a? Hash args.pop else {} end return display_value(args.first) if args.size == 1 display_field(args[0], args[1], options) end private def markdown(string) require "maruku" Maruku.new(string).to_html end LINK_PATTERN = '?'.freeze LINK_EXPRESSION = /#{LINK_PATTERN}/.freeze def convert_links(content_attribute, cms_path_options = {}) return content_attribute unless content_attribute =~ LINK_EXPRESSION link_map = content_attribute.source.text_links.each_with_object({}) do |link, map| map[link.id.to_s] = link end content_attribute.gsub(/#{LINK_PATTERN}(['"]?)/) do link = link_map[Regexp.last_match(1).to_s] if link.blank? "#{CmsRoutingHelper::LINK_TO_UNREACHABLE}#{Regexp.last_match(2)}" else uri = "#{cms_path(link, cms_path_options)}#{Regexp.last_match(2)}" if link.markdown? markdown_link(link, uri) else html_link(link, uri) end end end end def html_link(link, uri) subst = uri name, value = case link.tag_name when "img", "input" ["alt", link.title || ""] when "a", "link" ["title", begin link.title unless link.title.blank? end] end subst << %( #{name}="#{html_escape_once(value)}") if value subst << %( target="#{html_escape_once(link.target)}") unless link.target.blank? subst end def markdown_link(link, uri) subst = "<#{uri}>" unless link.title.blank? case link.markdown_type when "inline", "reference" subst << %( "#{html_escape_once(link.title)}") end end subst end end end