Skip to content

Image renderer should integrate with MODX Media Sources #125

Open

Description

@valZho
  • In the site I'm building, I have a Collection of products, i.e. each item/resource in my Collection is a product page.
  • There is a TV in the product template that is an image container. That image TV is tied to a specific, non-standard MODX Media source, and the link (saved TV value) is, of course, relative to the media source base_url.
  • In this case, the media source base_url is actually on a completely different domain from the main site.
  • Collections.renderer.image ignores the media source on the TV and assumes that the link (value) from the TV is relative to the site's base_url ...thus breaking the image link in the Collections list

Activity

  1. theboxer commented on Jan 28, 2015

    @theboxer
    Member

    You can create own image renderer that will have desired base_url.

    I'll try to look into this again how to include media sources, but it will probably not be anytime soon.

  2. knightknight commented on May 20, 2015

    @knightknight

    I had the same issue where I created a new MediaSource for some image TV's for a user with ACL controls. But renderer.image leaves out the MediaSource basePath or baseURL.

    Dirty hack, I've hardcoded my path 'assets/images/' in assets/components/collections/js/mgr/extra/collections.renderers.js and added it as Collections.renderer.imageMedia

     Collections.renderer.imageMedia = function(value, metaData, record, rowIndex, colIndex, store) {
        if (value != '' && value != null) {
           var imgPath = MODx.config['collections.renderer_image_path'];
           return '<img src="' + MODx.config.base_url + 'assets/images/' + imgPath + value + '" width="64">';
       }
     };
    
  3. azeller commented on Nov 19, 2015

    @azeller

    bump :)

    I don't want to do it this way. I love using Collections because it keeps the resource tree clean and simple for clients. But most of our clients need to get restricted to directories where they can't break anything...

    So I would also appreciate it if Collections was media-source aware...

  4. sepiariver commented on Nov 19, 2015

    @sepiariver
    Contributor

    Yea it probably needs to be a snippet renderer that fetches the TV object, gets the media source and fetches the media source object for the base path?

  5. azeller commented on Nov 19, 2015

    @azeller

    @sepiariver yeah, something like that.

    $modx->getObject('sources.modMediaSource',$options)) <- this is the media source.
    You can use prepareOutputUrl($mediaSourceID) to get a good-to-go path to the image.

    it's just that I am not a PHP-person, otherwise I would have fixed it myself :)

    Andreas

  6. sepiariver commented on Nov 19, 2015

    @sepiariver
    Contributor

    The Collections renderers are actually in JS, but they rely on ExtJS methods and config values which, it's hard to know them enough to do anything. Also you may have to register some method to query the media sources, etc.

    The best thing would be to specify a custom snippet renderer in your Collections grid settings, and do something along the lines of what you suggested. It would be more straightforward to do that, then get it in the Extra itself. Although maybe @theboxer will come back from his vacation and feel inspired ;) :P

  7. azeller commented on Nov 19, 2015

    @azeller

    I will check it out myself and see if I can figure it out :) as a J2EE guy, I feel like being lost in a strange land :)

  8. Spheerys commented on Dec 11, 2015

    @Spheerys
    Contributor

    Is someone make a fonctionnal snippet to use media source for the image rendering ?

  9. lukemcd commented on Jan 29, 2016

    @lukemcd

    I am using the Collections snippet renderer for thumbnails in the grid view. I ran into the media source issue and do not see an easy way to dynamically grab the media source path since Collections does not pass that information along.

    There may be a way to do a getObject query by extracting the TV name and get the media source path, but I am not able to figure that out.

    But I am able to get nice thumbnails by hard-coding the path in the snippet and using pThumb. I will post this in the forums as well:

    $imgName = $modx->getOption('value', $scriptProperties, '');
    $imgPath = 'assets/content/images/'; //Collections doesn't pass TV media source, hard-coding path
    $thumb = $modx->runSnippet('pthumb', [ 
        'input' => $imgPath . $imgName, 
        'options' => '&w=120&h=120&zc=C' 
    ]);
    return '<img src="' . $thumb . '" width="120">';
  10. chrisdempsey commented on Oct 8, 2016

    @chrisdempsey

    In case it helps anyone here's an updated version of lukemcd's snippet that assumes the default media source so you don't need to set $imgPath by hand.

    $default_media_source = $modx->getOption('default_media_source');
    $objSource = $modx->getObject('modMediaSource', $default_media_source);
    $properties = $objSource->getProperties();
    $imgPath = $properties['basePath']['value']; //Collections doesn't pass TV media source, hard-coding path
    
    $imgName = $modx->getOption('value', $scriptProperties, '');
    $thumb = $modx->runSnippet('pthumb', [ 
        'input' => $imgPath . $imgName, 
        'options' => '&w=60&h=60&zc=C'
    ]);
    
    return '<img src="' . $thumb . '" width="120">';
    
  11. jcdm commented on Jul 7, 2017

    @jcdm

    +1 for this. Just did it with a custom renderer for now, but it would be wonderful to be able to skip that process just for an image path.

  12. math-u commented on Nov 1, 2018

    @math-u

    +1 for this

  13. math-u commented on Nov 2, 2018

    @math-u

    I've just figured out to get custom media source path inside the Image renderer. Hope it will help someone:

    $imgName = $modx->getOption('value', $scriptProperties, '');
    
    $tvName = $scriptProperties["column"];
    $tvName = substr($tvName, 3);
    
    $tv = $modx->getObject('modTemplateVar', array('name' =>$tvName));
    $tvMediaSourceId = $tv->get('source');
    
    $mediaSource = $modx->getObject('modMediaSource', $tvMediaSourceId);
    $mediaSourceProperties = $mediaSource->getProperties();
    $mediaPath = $mediaSourceProperties['basePath']['value'];
    
    
    if($imgName){
    	$thumb = $modx->runSnippet('pthumb', [ 
        'input' => MODX_BASE_URL.$mediaPath.$imgName, 
        'options' => '&w=120&q=75'
    	]);
    	return '<img src="' . $thumb . '" width="120">';	
    }
    else{
    	return 'null';
    }
    
  14. Jako commented on Nov 27, 2024

    @Jako
    Contributor

    In MODX 3 you can use the following code:

    <?php
    
    use MODX\Revolution\modTemplateVar;
    use MODX\Revolution\Sources\modMediaSource;
    
    $imgName = $modx->getOption('value', $scriptProperties, '');
    
    $tvName = $scriptProperties['column'];
    $tvName = substr($tvName, 3);
    
    $tv = $modx->getObject(modTemplateVar::class, ['name' => $tvName]);
    $tvMediaSourceId = $tv->get('source');
    
    $mediaSource = $modx->getObject(modMediaSource::class, $tvMediaSourceId);
    $mediaSourceProperties = $mediaSource->getProperties();
    $mediaPath = $mediaSourceProperties['basePath']['value'];
    
    if ($imgName) {
        $thumb = $modx->runSnippet('pthumb', [
            'input' => MODX_BASE_URL . $mediaPath . $imgName,
            'options' => '&w=120&q=75'
        ]);
        return '<img src="' . $thumb . '" width="120">';
    }
    else {
        return '';
    }
  15. SilverMabol commented on Feb 23, 2026

    @SilverMabol
    Contributor

    If anyone is interested, I made this renderer that works with any image type (image, image+, and galleryitem).
    Pay attention to the default values ​​and use another thumber instead of Thumb3x if you have another one, adjusting the options.
    The renderer also takes into account any crops performed with Image+ or Galleryitem.

    <?php
    /**
     *  SNIPPET sRenderImgCollections
     *
     * @author          Silver  Mabol
     * @detail          Mostra immagini nella Vista Collezioni, di qualsiasi tipo siano
     * @date            23 feb 2026
     * @project
     * @note            Usa Thumb3x per generare le immagini
     *
     *
     * @var modX $modx
     * @var array $scriptProperties
     *
     */
    use MODX\Revolution\modTemplateVar;
    
    //valore default
    $imgDefault = '< div class="mioContImgSing">< img src="/assets/images/template/noImg-100x70.svg" width="100" height="70" alt="" >< /div>';
    //Prendo i valori della riga della collections, value valore inserito, column il parametro della colonna tv_imgTv, resId id della row che è id risorsa
    $value = $modx->getOption('value', $scriptProperties, '');
    $column = $modx->getOption('column', $scriptProperties, '');
    if (!$value || !$column) return $imgDefault;
    
    // Pulizia nome TV che inizia per tv_ (3)
    $tvName = (str_starts_with($column, 'tv_')) ? substr($column, 3) : $column;
    if (empty($tvName)) return $imgDefault;
    
    // Recupero l'oggetto TV per Nome (Univoco)
    $oTv = $modx->getObject(modTemplateVar::class, ['name' => $tvName]);
    if (!$oTv) return $imgDefault;
    
    //Inizializzazione variabili 
    $sPath = '';
    $srcImg = '';
    $cropParams = '';
    //Controllo se esiste media source della tva e ne calcolo basepath
    $source = $oTv->get('source');
    if($source && $source!==1){
        $mediaSource = $modx->getObject('MODX\Revolution\Sources\modMediaSource', $source);
        $msProps = $mediaSource->getProperties();
        $sPath = $msProps[ 'basePath' ][ 'value' ];
    }
    // Discrimino a seconda dei casi
    if($oTv->get('type') == 'image') {
        $srcImg = $sPath.$value;
    }
    else if($oTv->get('type') == 'imageplus') {
        //Prendo anche eventuali crop
        $arrTvValue = json_decode($value, true);
        if (!empty($arrTvValue['sourceImg']['src'])) {
            $srcImg = $sPath . $arrTvValue['sourceImg']['src'];
        }
        if ($arrTvValue['crop']['x'] || $arrTvValue['crop']['y']) {
            $cropParams = "&crop={$arrTvValue['crop']['width']},{$arrTvValue['crop']['height']},{$arrTvValue['crop']['x']},{$arrTvValue['crop']['y']}";
        }
    }
    else if($oTv->get('type') == 'galleryitem') {
        //Prendo anche eventuali crop
        $arrTvValue = json_decode($value, true);
        if (!empty($arrTvValue['gal_src'])) {
            $srcImg = $sPath . $arrTvValue['gal_src'];
        }
        if ($arrTvValue['gal_cropLeft'] || $arrTvValue['gal_cropTop']) {
            // Glide (motore di Thumb3x) usa il formato: width,height,x,y
            $cropParams = "&crop={$arrTvValue['gal_image_width']},{$arrTvValue['gal_image_height']},{$arrTvValue['gal_cropLeft']},{$arrTvValue['gal_cropTop']}";
        }
    }else {
        return $imgDefault;
    }
    //fit diverso a seconda che ci sia crop originale o che non sia fatto
    $fitParams = $cropParams ? "&fit=crop$cropParams" : "&fit=crop-center";
    //Creo thumb, posso usare anche pThumb al posto di Thumb3x
    $thumb = $modx->runSnippet('Thumb3x', [
        'input' => $srcImg,
        'options' => "w=100&h=70&q=69$fitParams"
    ]);
    if ($thumb) {
        return '< div class="mioContImgSing">< img src="/'.ltrim($thumb, '/').'" width="100" height="70" alt=""></div>';
    }else{
        return $imgDefault;
    }

    It works for me and doesn't seem to give me any errors.
    If you find any or have optimizations that need to be implemented, I'll gladly use them. ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions