Picture gallery

This example (source file can be found in lib/examples/picture gallary) will show how to add picture gallery to page document. The idea is to use parts (dc_part) documents embedded in page document for defining picture gallery. Since parts can be used to hold all kind of data, we must define which parts will hold pictures information. We will accomplish this by setting dc_part.div_id field to pre-agreed value. For example 'gallery'.

 

Lets explain source code by lines.

 

Gallery may be called with page as parameter and will default to currently active page document. If page.gallery field is blank, empty string is returned. After that we initialize returned html code. Picture gallery div will use picture-gallery class. 

def gallery(page=@parent.page)
  return '' if page.gallery.blank? 
  html = '<div class="picture-gallery">'

 

At the top we put link for adding new image to gallery. Link will be created only when in edit mode. 

  if @parent.dc_edit_mode?
    opts = { controller: 'cmsedit', action: 'create', formname: 'gallery',
             table: "#{@parent.site.page_table};dc_part", ids: page._id,
             'dc_part.div_id' => page.gallery, 'dc_part.name' => page.subject,
             title: 'Add new picture to gallery.' }
    html << @parent.dc_link_for_create(opts)   
  end

 

We will create and use new form named 'gallery' for entering data. We could use default dc_part form, but dc_part form is using all fields of DcPart model, which may confuse user, While gallery form will expose only fields that are used by gallery. These field are name (used as image title), description (used as descriptive text under the image), big image and thumbnail image. You will notice that form also defines div_id field which is hidden. Field will be initialized by providing 'dc_part.div_id' parameter. 'dc_part.name' will also be initialized with page.subject value.

 

Table parameter needs some more explanation. Since dc_part is embedded in dc_page document both model names must be defined. They are separated by semicolon. If dc_part would have another embedded document its name would be added to the end of table parameter. Separated by semicolon of course. @parent.site.page_table defines name of main document model and mostly value 'dc_page'. 

 

Ids parameter holds id's of all parents of embedded document. Id's are also separated by semicolon if document is embedded deeper than single level.

 

Title will be displayed when mouse is put over link icon.

 

Finally we call dc_link_for_create helper method which will return code for adding new picture to gallery. 

 

Continue with gallery data:

  html << '<h2>Picture gallery:</h2>'
  page.dc_parts.where(:div_id => page.gallery).order(order: 1).each do |part|
    html << '<span class="gallery-pic">'
    if @parent.dc_edit_mode?
      opts.merge!({ action: 'edit', ids: page._id, id: part._id, title: 'Edit picture.' })
      html << @parent.dc_link_for_edit(opts)   
    end

 

Our gallery starts with title 'Picture gallery:'

 

In loop we collect all parts which have value of field page.gallery in div_id field and iterate each of them.

 

Before we paint image we create link for editing image data document. We just merge additional data into opts hash and call dc_link_for_edit method.

 

Finally image data. 

    pic = part.thumbnail.blank? ? part.picture : part.thumbnail
# Use part.name as title. If not use page title (subject) field
    title = part.name.blank? ? page.subject : part.name
    html << @parent.link_to(@parent.image_tag(pic, title: title), part.picture)
# Description under picture
    html << "<h6>#{part.description}</h6>" unless part.description.blank?
    html << '</span>'

 

First picture. If thumbnail is not defined then picture is used as thumbnail. 

 

Below comes description. Since images are enclosed in span, they will be displayed side by side.

 

And for grand finale we add code for calling baquetteBox javascript library which will provide nice interface for browsing images.

  html << @parent.javascript_tag( "baguetteBox.run('.picture-gallery', {});" )
  html << '</div>'
end

 

 BuggetBox project can be found on this https://github.com/feimosi/baguetteBox.js GitHub page. Preferred, unobtrusive way, would be to place javascript code into assets source file.

 


Last update: 08.05.2018