Module: Tandem::PagesHelper

Includes:
ContentsHelper
Defined in:
app/helpers/tandem/pages_helper.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ContentsHelper

#image_content_tag, #image_content_url, #text_content_text_area_options

Class Method Details

.included(base) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'app/helpers/tandem/pages_helper.rb', line 6

def self.included(base)
  Tandem::Content.subclasses.each do |klass|
    # tandem_#{klass.simple_type}_tag is provided as an alias of tandem_content_tag,
    # specifying the type of content through the method name. For example:
    #
    #    <%= tandem_image_tag(:test_image) %>
    #
    # is equivalent to:
    #
    #    <%= tandem_content_tag(:test_image, :image) %>
    #
    base.send(:define_method, "tandem_#{klass.simple_type}_tag") do |identifier, options = {}, html_options = {}|
       identifier, klass.simple_type, options, html_options
    end
  end
end

Instance Method Details

#tandem_content_tag(identifier, type, options = {}, html_options = {}) ⇒ Object

tandem_content_tag creates an HTML DIV element with id and class parameters that relate to the specified Tandem Content object and contains an internal content element. If a Tandem::Content record doesn’t exist for the unique combination of: request_key, identifier and type, one will be created automatically. For example:

<%= tandem_content_tag(:test_image, :image) %>

would find_or_create a Tandem::Content::Image object and produce the following HTML:

<div class="tandem_content" id="test_image">...<img id="tandem_content_image_test_image" class="tandem_content_image bar"...</div>

If the user is authorized to update content then an edit link will be generated in conjunction with the content. For example:

<%= tandem_content_tag(:test_text, :text) %>

would produce the following HTML (assuming ‘can? :update, tandem_content` => true):

<div class="tandem_content" id="test_text">
  <div class="tandem_toolbar" id="tandem_toolbar_test_text">
    <a href="#" id="tandem_edit_link_test_text" title="Edit test_text" class="tandem_edit_link" editor_options="{&quot;identifier&quot;:&quot;test_text&quot;,&quot;type&quot;:&quot;text&quot;}">Edit</a>
  </div>
  ....
</div>

If a user specifies link information for the corresponding Tandem::Content object, then an A HTML element will be generated surrounding the content. For example:

<%= tandem_content_tag(:test_image, :image) %>

produces (assuming that tandem_content.link? => true):

<div class="tandem_content" id="test_image">
  ...
  <a id="tandem_content_link_test_image" class="tandem_content_link" ...
    <img id="tandem_content_image_test_image" class="tandem_content_image" ...
  </a>
</div>

tandem_content_tag accepts a hash of html_options, which will be converted to additional HTML attributes of the generated container div. If you specify a :class value, it will be combined with the default class name for your object. For example:

<%= tandem_content_tag(:test_image, :image, {}, :class => "bar", :style => 'display:none') %>...

produces:

<div class="tandem_content bar" id="test_image" style = "display:none">...

tandem_content_tag also accepts a hash of options, which will be converted to additional HTML attributes of the internal asset type. If you specify a :class value, it will be combined with the default class name for your object. For example:

<%= tandem_content_tag(:test_image, :image, :class => "bar", :width => 80) %>...

produces:

...<img id="tandem_content_image_test_image" class="tandem_content_image bar" width = "80"...

Finally, text tandem_content_tags support an :editor option, which defaults to :plain, but can also be changed to :wysiwyg to enable a WYSIWYG editor, e.g.

<%= tandem_content_tag(:main_body, :text, editor: :wysiwyg) %>


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'app/helpers/tandem/pages_helper.rb', line 86

def (identifier, type, options = {}, html_options = {})
  options[:editor] ||= :plain

  using_tandem_abilities do
    tandem_content = Content.scoped_type(type).constantize.find_or_create_by_request_key_and_tag(request_key, identifier)

    content = case tandem_content
      when Content::Text
        (:div, tandem_content, options.merge(
            id: "#{dom_class(tandem_content)}_#{identifier}",
            class: "#{dom_class(tandem_content)} #{options[:class]}".strip
        )) {
          tandem_content.formatted_content.html_safe
        }
      when Content::Image
        (tandem_content,options.merge(
            id: "#{dom_class(tandem_content)}_#{identifier}",
            class: "#{dom_class(tandem_content)} #{options[:class]}".strip
        ))
      else
        raise "Unable to create #{tandem_content.class.name}: #{tandem_content.errors.inspect}" if tandem_content.new_record?
        raise "Rendering behavior not defined for: #{tandem_content.class.name}"
    end

    content = link_to(content,tandem_content.link_url,{
        id: "tandem_content_link_#{identifier}",
        class: "tandem_content_link",
        target: tandem_content.link_target
    }) if tandem_content.link?

    content = (:div, tandem_content, {
        id: "tandem_toolbar_#{identifier}",
        class: "tandem_toolbar #{options[:class]}".strip
    }) {
      link_to("Edit", tandem.edit_content_path(tandem_content.id, editor: options[:editor]),{
          id: "tandem_edit_link_#{identifier}",
          class: "tandem_edit_link #{options[:class]}".strip,
          title: "editing #{identifier}"
      })
    } + content if can? :update, tandem_content

    html_options.merge! id: identifier
    html_options[:class] ||= ''
    html_options[:class] << ' tandem_content' if can? :update, tandem_content
    html_options[:class].strip!

    (:div, tandem_content, html_options) { content }
  end
end

#tandem_navigation_tag(active_page, pages_collection = nil, html_options = {}) ⇒ Object

todo… document this



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'app/helpers/tandem/pages_helper.rb', line 137

def tandem_navigation_tag(active_page, pages_collection = nil, html_options = {})
  html_options, pages_collection = pages_collection, nil if pages_collection.is_a?(Hash)

  html_options[:class] ||= 'nav'

  page_groups = (pages_collection || Page.all).inject({}) do |groups, page|
    if groups[page.parent_id.to_s]
      groups[page.parent_id.to_s] << page
    else
      groups[page.parent_id.to_s] = [page]
    end
    groups
  end

  # generate must be in scope for the iterate proc declaration, but must be defined below iterate, so that iterate is recursively in scope
  generate = nil

  iterate = Proc.new do |parent_id|
    #very important to delete the group from the collection, or it is possible users can create looping relationships
    (page_groups.delete(parent_id.to_s) || {}).inject(''.html_safe) do |buffer, page|
      buffer + generate.call(page)
    end
  end

  generate = Proc.new do |page|
    (:li, page, :tandem, class: "#{page == active_page ? 'active' : ''}") do
      link_to(page.link_label, tandem.page_path(page), class: "#{page == active_page ? 'active' : ''}") +
      (:ul) do
        iterate.call(page.id)
      end
    end
  end

  (:ul, html_options) do
    iterate.call(page_groups.keys.first)
  end
end


175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'app/helpers/tandem/pages_helper.rb', line 175

def tandem_page_links(options = {})
  using_tandem_abilities do
    return if cannot?(:create, @page) && cannot?(:update, @page) && cannot?(:destroy, @page) && cannot?(:index, ::Tandem::Page)

    options[:id] ||= 'tandem_page_links'

    (:ul, options) do
      links = []
      
      if can?(:create, ::Tandem::Page)
        links << link_to('New Page', tandem.new_page_path(parent_id: @page.try(:id)), :class => :page_link, :id => :page_new_link)
      end

      if @page.present?
        if @page.persisted? && can?(:update, @page)
          links << link_to('Edit Page', tandem.edit_page_path(@page), :class => :page_link, :id => :page_edit_link)
        end

        if @page.persisted? && can?(:destroy, @page)
          links << link_to('Destroy Page', tandem.page_path(@page), :confirm => 'Are you sure?', :method => :delete)
        end
      end

      if can?(:index, ::Tandem::Page)
        links << link_to('Page Listing', tandem.pages_path)
      end

      links.collect! do |link|
        (:li, link)
      end

      raw(links.join)
    end
  end
end

#valid_layoutsObject



211
212
213
214
215
216
217
218
219
220
221
# File 'app/helpers/tandem/pages_helper.rb', line 211

def valid_layouts
  @valid_layouts ||= Dir["#{::Rails.root}/app/views/layouts/**/*.html*"].collect do |layout|
    name_match = layout.match(/layouts\/([\w\-\/]*)((\.\w*){2})$/)
    if name_match
      name = name_match[1]
      name unless name == 'application'
    else
      nil
    end
  end.compact
end

#valid_templatesObject



223
224
225
226
227
228
# File 'app/helpers/tandem/pages_helper.rb', line 223

def valid_templates
  @valid_templates ||= Dir["#{::Rails.root}/app/views/tandem/pages/**/*.*.*"].collect do |template|
    template_name = File.basename(template).split('.').first
    template_name if valid_custom_template?(template_name)
  end.compact
end