#
# This module provides several helper methods for rendering the CMS contents and enabling the
# in-place editing.
#
# @api public
#
module ScrivitoHelper
include Scrivito::RoutingHelper
#
# Returns an HTML block tag containing content from an Obj.
# Add HTML attributes by passing an attributes hash to options.
# The helper method is somewhat similar to (and internally uses)
# http://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag.
#
# @api public
#
# This helper method also renders additional data attributes, which are needed for inplace editing.
# These attributes are only rendered when appropriate, i.e. not for a regular visitor.
#
# @param tag_name [String, Symbol] Name of the html tag (e.g. +:h1+ or +:div+).
# @param obj_or_widget [Scrivito::BasicObj, Scrivito::BasicWidget] A {Scrivito::BasicObj}
# or {Scrivito::BasicWidget} from which the +field_name+ is read.
# @param field_name [String, Symbol] Which field of the Obj should be rendered.
# @param html_options [Hash] HTML options to be passed to +content_tag+.
# @param block [Proc] Optional block to render inner HTML. If none given the value of attribute
# will be rendered instead. +block+ is not allowed for fields of type +widget+.
# @raise ArgumentError if the field behind +field_name+ is of type +widget+ and a +block+ is given.
# @return [String] The rendered html tag
#
# @example Renders an
tag containing the text of the +headline+ attribute of +@obj+ and assigns the tag a css class called +very_important+.
# <%= scrivito_tag :h2, @obj, :headline, class: "very_important" %>
#
# @example Renders an tag containing an escaped +headline+.
# <%= scrivito_tag :h2, @obj, :headline do %>
# <%= strip_tags @obj.headline %>
# <% end %>
#
def scrivito_tag(tag_name, obj_or_widget, field_name, html_options = {}, &block)
Scrivito::CmsFieldTag.new(
self, tag_name, obj_or_widget, field_name.to_s
).render(html_options, &block)
end
#
# @api public
#
# @param tag_name [String, Symbol] Name of the html tag (e.g. +:h1+ or +:div+).
# @param obj [Scrivito::BasicObj] A {Scrivito::BasicObj} from which field_name is read.
# @param field_name [String, Symbol] Which field_name of the Obj should be rendered. Currently
# only +toclist+ is supported
# @param options [Hash] Additional options, which are passed to +content_tag+. Use them to add
# HTML attributes to the tag
#
# @yieldparam [Scrivito::ChildListTag::ObjTag] list An instance, where +tag+ should be called once.
# @yieldparam [Scrivito::BasicObj] child Each child of +toclist+
#
# @return [String] The rendered html tag
#
# @example
# <%= scrivito_tag_list :div, @obj, :toclist, class: "very_important" do |list, child| %>
# <%= list.tag :div, class: "also_important" do %>
# <%= link_to scrivito_path(child) do %>
# <%= scrivito_tag :span, child, :title %>
# <% end %>
# <% end %>
# <% end %>
#
# # results for an obj with two children in
#
#
#
def scrivito_tag_list(tag_name, obj, field_name, options = {}, &block)
Scrivito::ChildListTag.new(tag_name, obj, field_name.to_s, self).render(options, &block)
end
#
# Calculates an HTML image tag of an image stored in the CMS for inplace editing.
#
# @api public
#
# @note If you do not specify an HTML +alt+ attribute, the helper method will use
# +display_title+ of the target object
#
# @param [Obj] obj Obj with a +link_list+, +reference+, +link+ or +binary+ attribute
# @param [String, Symbol, Hash] field_name_or_tag_options Name of +link_list+, +reference+, +link+, or +binary+
# attribute, which contains the image or additional HTML attributes for the tag
# @param [Hash] tag_or_editing_options Additional HTML attributes for the tag or
# the editing options if no +field_name+ was given
# @param [Hash] editing_options Additional options for inplace editing
# @option editing_options [String] :placeholder ('/assets/scrivito/image_placeholder.png') URL
# or path to image to be displayed if target is missing
#
# @example
# scrivito_image_tag @obj, :my_linklist
# scrivito_image_tag @obj, :my_linklist, alt: 'Interesting picture', class: 'my_image'
# scrivito_image_tag @obj, :my_linklist, {}, placeholder: image_path('my_placeholder.png')
# scrivito_image_tag @obj, :my_linklist, {class: 'my_image'}, placeholder: 'http://placehold.it/350x150'
#
# @example Create image tag for a reference attribute.
# scrivito_image_tag @obj, :my_reference
#
# @example Create image tag for a link attribute.
# scrivito_image_tag @obj, :my_link
#
# @example Create image tag for a binary attribute
# scrivito_image_tag @obj, :my_binary
#
# @example Create image tag for a binary object
# scrivito_image_tag @image
#
# @return [String] HTML image tag
#
# @raise [ScrivitoError] if +field_name+ is not set and obj is not binary
#
def scrivito_image_tag(obj, field_name_or_tag_options=nil,
tag_or_editing_options = {}, editing_options = {})
field_name, tag_options, editing_options =
if field_name_or_tag_options.is_a?(Hash)
[nil, field_name_or_tag_options, tag_or_editing_options]
else
[field_name_or_tag_options, tag_or_editing_options, editing_options]
end
options = Scrivito::ImageTagHelper.new(self).options(obj, field_name,
tag_options.with_indifferent_access, editing_options.with_indifferent_access)
scrivito_tag('img', obj, field_name, options)
end
#
# Renders an attribute value of a CMS model.
#
# <%= scrivito_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
#
# @note Content rendered using this method
# will not be editable in the Scrivito UI.
# If you want In-Place-Editing, use {ScrivitoHelper#scrivito_tag} instead.
#
# @api public
#
def scrivito_value(value)
case value
when Scrivito::HtmlString
Scrivito::CmsRouting.new(request, main_app).convert_links(value).html_safe
when String then h(value)
when Time then h(l(value))
when Scrivito::BasicWidget
render(template: value.to_show_view_path, locals: {widget: value})
else value
end
end
#
# Renders a field from the CMS.
#
# @api public
#
# @note Content rendered using this method will not be editable in the Scrivito UI.
# If you want in-place editing, then please use {ScrivitoHelper#scrivito_tag} instead.
#
# @param obj [Scrivito::BasicObj] an +Obj+, whose field should be rendered.
# @param field_name [String, Symbol] the field of +obj+ to be rendered.
#
# @example
# <%= scrivito_field @obj, :title %>
# <%= scrivito_field @obj, 'headline' %>
#
def scrivito_field(obj, field_name)
scrivito_value(obj[field_name])
end
#
# Thumbnail helper generates HTML for the page class selection dialog and the widget class selection dialog.
# The generated HTML has appropriate DOM structure and CSS classes, which are compatible with the CSS of the SDK.
# By using this helper you ensure, that the look of your thumbnails fits into the SDK's design.
#
# @api public
#
# @param title [String] title of the thumbnail, e.g. "Content Page" or "Image Widget".
# @param icon [Symbol, String] icon of the thumbnail.
# You can use one of the built-in icons or specify your own HTML.
# There are following built-in icons: +:content+, +:headline+, +:image+, +:scrivito+ and +:text+.
# If the name of the specyfied icon is unknown, then the default icon (+:scrivito+) will be displayed.
# If you are speifying your own HTML string, then make sure it is HTML safe.
# @param block [Proc] the description of the thumbnail.
#
# @example A simple thumbnail
# <%= scrivito_thumbnail 'Content Page' do %>
# A content page.
# <% end %>
#
# @example A thumbnail with a built-in icon
# <%= scrivito_thumbnail 'Image Widget', :image do %>
# An image widget.
# <% end %>
#
# @example A thumbnail with custom icon HTML
# <%= scrivito_thumbnail 'Blog', content_tag(:i, '', class: 'thumbnail-blog') do %>
# A blog post.
# <% end %>
#
def scrivito_thumbnail(title, icon = :scrivito, &block)
if icon.is_a?(Symbol)
icon_code = {
content: '',
headline: '',
image: '',
scrivito: '',
text: '',
}.fetch(icon, '')
icon = content_tag(:i, icon_code.html_safe, class: 'scrivito_icon')
end
content_tag(:div, class: 'scrivito_editing_widget_preview') do
capture do
concat content_tag(:div, icon, class: 'scrivito_editing_widget_visualization')
concat content_tag(:div, title, class: 'scrivito_editing_widget_title')
concat content_tag(:div, class: 'scrivito_editing_widget_description', &block)
end
end
end
#
# Renders all tags needed in the HTML head.
# @api public
#
def scrivito_head_tags
layout_tags = Scrivito::LayoutTags.new(self)
capture do
concat layout_tags.editing_auth_warning
concat layout_tags.generator_meta_tag
concat layout_tags.reset_stylesheet_tag
end
end
#
# Renders all tags needed in the HTML body.
# @api public
#
def scrivito_body_tags
Scrivito::LayoutTags.new(self).client_config(@obj, @scrivito_resource)
end
{
'cms_image_tag' => 'scrivito_image_tag',
'cms_path' => 'scrivito_path',
'cms_tag' => 'scrivito_tag',
'cms_tag_list' => 'scrivito_tag_list',
'cms_url' => 'scrivito_url',
'display_field' => 'scrivito_field',
'display_value' => 'scrivito_value',
'render_widget' => 'scrivito_value',
'scrivito_after_content_tags' => 'scrivito_body_tags',
'scrivito_header_tags' => 'scrivito_head_tags',
}.each_pair do |old_method_name, new_method_name|
define_method(old_method_name) do |*args|
raise %{
The helper method `#{old_method_name}' has been removed.
Please use `#{new_method_name}' instead.
}
end
end
#
# Returns the current user.
#
# @api public
# @return [Scrivito::User] if the {Scrivito::Configuration.editing_auth} callback returns an
# instance of {Scrivito::User}.
# @return +nil+ otherwise.
#
def scrivito_user
Scrivito::EditingContextHelper.new(request).scrivito_user
end
def inplace_editing_allowed?
raise %{
The helper method `inplace_editing_allowed?' has been removed.
Please use helper method `scrivito_user` instead.
}
end
#
# Returns whether the GUI is in the +editable+ view.
#
# @api public
# @return +true+ if the current visitor is an authenticated editor, the selected workspace is
# editable and the display mode is +editing+.
# @return +false+ otherwise.
#
def scrivito_in_editable_view?
Scrivito::EditingContextHelper.new(request).in_editable_view?
end
end