             [:div.pswp__caption__center]]]]]
         [:div.gallery {:itemscope ""
                        :itemtype "http://schema.org/ImageGallery"}
-         (for [photo photos
-               :let [caption (format "Submission %s" (:rank photo))]]
-           [:figure {:itemprop "associatedMedia"
-                     :itemscope ""
-                     :itemtype "http://schema.org/ImageObject"}
-            [:a {:href (:src photo)
-                 :itemprop "contentUrl"
-                 :data-size (format "%sx%s" width-px width-px)}
-             [:img {:src (:thumb photo)
-                    :itemprop "thumbnail"
-                    :alt caption}]]
-            [:figcaption {:itemprop "caption description"} caption]])]]))
-    om/IDidMount
-    (did-mount [_]
-      (let [pswp-element (first (.querySelectorAll js/document ".pswp"))
-            options {:index 0 ;; start at the first slide
-                     }
-            gallery (js/PhotoSwipe. pswp-element
-                                    js/PhotoSwipeUI_Default
-                                    (clj->js (om/get-state owner :photos))
-                                    (clj->js options))]
-        (.init gallery)))))
+         (build-photo-gallery photos owner)]]))))

        :rank (get datum constants/_rank)
        :w width-px :h width-px}))))

(defmethod photos-page :default
  [{:keys [dataset-info]} owner]
  "Om component for the photos page."

  [str]
  (remote/make-url (replace str #"/api/v1" "")))

(defn- open-photoswipe
  [index owner]
  (let [pswp-element (first (.querySelectorAll js/document
                                               (str "." pswp-gallery-class)))
        options {:index (int index)
                 :getThumbBoundsFn
                 (fn [index]
                   (let [thumbnail
                         (first (.querySelectorAll
                                 js/document
                                 (format "[%s='%s']"
                                         data-pswp-id
                                         index)))
                         page-y-scroll (+ (.-pageYOffset js/window)
                                          (.. js/document
                                              -documentElement
                                              -scrollTop))
                         rect (.getBoundingClientRect thumbnail)]
                     {:x (.-left rect)
                      :y (+ (.-top rect) page-y-scroll)
                      :w (.-width rect)}))}
        gallery (js/PhotoSwipe. pswp-element
                                js/PhotoSwipeUI_Default
                                (clj->js (om/get-state owner :photos))
                                (clj->js options))]
  (.init gallery)))

(defn- on-thumbnail-click
  [event owner]
  (.preventDefault event)
  (open-photoswipe (.getAttribute (.-target event) data-pswp-id)
                   owner))

(defn- build-photos
  "Build photos for photoswipe from a set of form data."
  [data]
  (flatten
