Jump to:

7937 Posts in 1537 Topics by 944 members

DataObjectManager Module

SilverStripe Forums » DataObjectManager Module » showing images with unique captions

Discuss the DataObjectManager module, and the related ImageGallery module.

Moderators: martimiz, UncleCheese, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1123 Views
  • tonito
    Avatar
    Community Member
    24 Posts

    showing images with unique captions Link to this post

    Is there such thing as a "unique" element function already established in SilverStripe or in ImageGallery or DataObjectManager?

    I am trying to do the following: I have an album associated to a page. If images have the same caption, I would like to show the first one and hide the subsequent ones.

    Something like:
    <% control GalleryItems %>
    <% if Caption.AlreadyDisplayed %>
    <a href="" style="display: none"><img src="" /></a>
    <% else %>
    <a href=""><img src="" /></a>
    <% end_if %>
    <% end_control %>

    I am a complete starter with php or jQuery, if someone has a hint, I would gladly take it.

  • UncleCheese
    Avatar
    4085 Posts

    Re: showing images with unique captions Link to this post

    You're going to have to handle that in your controller.. I assume this is the ImageGallery module?

    Create a subclass called MyImageGalleryPage (or whatever you want)

    and overload the GalleryItems() function.

    public function GalleryItems() {
    $items = parent::GalleryItems();
    $used_captions = array();
    foreach($items as $i) {
    if(in_array($i->Caption, $used_captions)) {
    $i->destroy();
    }
    else {
    $used_captions[] = $i->Caption;
    }
    }
    return $items;
    }

    Something like that should work.

  • tonito
    Avatar
    Community Member
    24 Posts

    Re: showing images with unique captions Link to this post

    Wooaw, thank you. It would have taken me weeks to figure something like that. Yes this is with the Image Gallery Module.
    Thank you for your help and your fantastic modules.

    I created a PressImageGalleryPage.php in image_gallery/code

    <?php

    class PressImageGalleryPage extends ImageGalleryPage {

       public function GalleryItemsUnique() {
       $items = parent::GalleryItems();
       $used_captions = array();
       foreach($items as $i) {
       if(in_array($i->Caption, $used_captions)) {
       $i->destroy();
       }
       else {
       $used_captions[] = $i->Caption;
       }
       }
       return $items;
       }

    }

    ?>

    Changed the page type of my page to Press Image Gallery Page, but I get the following error:

    [User Error] Uncaught Exception: Object->__call(): the method 'handlerequest' does not exist on 'PressImageGalleryPage'
    GET /mywebsite/info/press?flush=1

    Line 724 in /Users/MyComputer/Sites/mywebsite/sapphire/core/Object.php
    Source

    715             
    716             default :
    717                throw new Exception (
    718                   "Object->__call(): extra method $method is invalid on $this->class:" . var_export($config, true)
    719                );
    720          }
    721       } else {
    722          // Please do not change the exception code number below.
    723          
    724          throw new Exception("Object->__call(): the method '$method' does not exist on '$this->class'", 2175);
    725       }
    726    }
    727    
    728    // -----------------------------------------------------------------------------------------------------------------
    729    
    730    /**

    Trace

    * Object->__call(handleRequest,Array)
    * PressImageGalleryPage->handleRequest(SS_HTTPRequest)
    Line 184 of ContentController.php
    * ContentController->handleRequest(SS_HTTPRequest)
    Line 67 of ModelAsController.php
    * ModelAsController->handleRequest(SS_HTTPRequest)
    Line 283 of Director.php
    * Director::handleRequest(SS_HTTPRequest,Session)
    Line 127 of Director.php
    * Director::direct(/info/press)
    Line 127 of main.php

    NOTE:
    The code your offered seems like it will not return (destroy) the GalleryItem that has a same caption as another GalleryItem. If possible I do need to have all GalleryItem displayed in the page, but the ones with a hidden.

    Each elements of the gallery with same captions will be added consecutively by the user, hence I would just need some kind of controller that checks if the previous gallery item has the same caption as the current one and returns true or false.

  • UncleCheese
    Avatar
    4085 Posts

    Re: showing images with unique captions Link to this post

    Did you create a controller for it, as well?

    PressImageGalleryPage_Controller extends ImageGalleryPage_Controller??

  • tonito
    Avatar
    Community Member
    24 Posts

    Re: showing images with unique captions Link to this post

    UncleCheese,

    I still have a way to go to build with silverstripe. Thank you for your help.

    This is how my PressImageGalleryPage.php looks like now:

    <?php

    class PressImageGalleryPage extends ImageGalleryPage {
       
       public function GalleryItems() {
       $items = parent::GalleryItems();
       $used_captions = array();
       foreach($items as $i) {
       if(in_array($i->Caption, $used_captions)) {
       $i->destroy();
       }
       else {
       $used_captions[] = $i->Caption;
       }
       }
       return $items;
       }
    }

    class PressImageGalleryPage_Controller extends ImageGalleryPage_Controller {      
    }

    ?>

    My Press Image Gallery Page doesn't throw errors anymore, however, the <% control GalleryItems %> doesn't return anything (empty). I created a PressImageGalleryPage.ss in image_gallery/templates/Layout with just hello to test, and the page is not parsed and "hello" does not appear.

    Alternatively, I seem to have found a solution with jQuery -- in a mere 6 hours of trial and error .

    Here my markup (in GalleryUI_layout.ss):

    <div class="gallery-layout-wrapper">   
       <% if GalleryItems %>
       <ul class="gallery-layout" id="gallery-list">
          <% control GalleryItems %>
             <li style="list-style: none;" name="$Caption.EscapeXML">$GalleryItem</li>
          <% end_control %>
       </ul>
       
       <script>
        $(document).ready(function() {
        $('ul#gallery-list').find('li').each(function(i) {
          var t = $(this).attr("name");
          if (($('ul#gallery-list').find("li[name="+t+"]").length) > 1) {
             if (t!="") {
                $('ul#gallery-list').find("li[name="+t+"]").nextUntil("li[name!="+t+"]").css("display", "none");
                }
             }
        });   
        });
       </script>
       <% end_if %>
    </div>

    The little jQuery script looks for li elements with specific captions and hides the li elements with following identical captions. Maybe this little code can help someone.

    The idea is to show in the gallery only the first element of an Image Gallery with a given caption, and to hide the other images with the same caption. In the case of a press page, the gallery shows the magazine cover, and hides the subsequent inside pages of the magazine. Once clicked on the cover magazine image, Lightroom or FancyBox (etc) shows the cover image and the inside pages of the magazine in a sequence.

  • UncleCheese
    Avatar
    4085 Posts

    Re: showing images with unique captions Link to this post

    You shouldn't be modifying anything in the core image_gallery directory. Silverstripe allows you to override templates and CSS in your theme dir. You new template belongs there, not in image_gallery. That directory should never change.. otherwise, upgrades would be a pain.

    Anytime you create new templates, make sure you're running a flush=1. Otherwise, they don't get loaded into the manifest.

    What happens when you comment out the $i->destroy(); line?

  • tonito
    Avatar
    Community Member
    24 Posts

    Re: showing images with unique captions Link to this post

    Arrrgh, it makes sense. I will never modify modules ruthlessly the way I used to. Customizing them is so simple, I didn't realize. Once more, thank you.

    Once again, I consider the problem solved, with the jQuery script I made. I am curious to troubleshoot your solution though at your leisure.

    The initial non-rendering problem was because I didn't have a MyImageGalleryPage_album.ss in my Includes in my theme folder. Once I did, the page rendered with custom code, that's with the $i->destroy(); commented. Once I un-comment the $i->destroy(); line, I get new errors:

    array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object
    GET /mywebsite/info/press?flush=1

    Line 2156 in /Users/someuser/Sites/mywebsite/sapphire/core/model/DataObject.php
    Source

    2147     * Returns true if the given field exists
    2148     * in a database column on any of the objects tables,
    2149     * or as a dynamic getter with get<fieldName>().
    2150     *
    2151     * @param string $field Name of the field
    2152     * @return boolean True if the given field exists
    2153     */
    2154    public function hasField($field) {
    2155       return (
    2156          array_key_exists($field, $this->record)
    2157          || $this->db($field)
    2158          || $this->hasMethod("get{$field}")
    2159       );
    2160    }
    2161
    2162    /**

    Trace

    * array_key_exists(Caption,)
    Line 2156 of DataObject.php
    * DataObject->hasField(Caption)
    Line 113 of ViewableData.php
    * ViewableData->__get(Caption)
    Line 371 of ViewableData.php
    * ViewableData->obj(Caption,,1)
    Line 42 of .cache.Users.someuser.Sites.mywebsite.themes.mywebsite.templates.image_gallery.templates.Includes.GalleryUI_layout.ss
    * include(/Users/someuser/Sites/shopshabd/silverstripe-cache/.cache.Users.someuser.Sites.mywebsite.themes.mywebsite.templates.image_gallery.templates.Includes.GalleryUI_layout.ss)
    Line 392 of SSViewer.php

    .....

    1123 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.