Fred tutorials?

I’ve started playing around with Fred and I’m starting to fall in love :heart_eyes: However, I’m finding it difficult to achieve things that aren’t quite basic. I know my way around MODX pretty well I’d say after working with it almost daily for 15 years, but mastering templating with Fred seems to be a bit of a challenge. Is there any chance of a quick tutorial in how to build a gallery element and how to integrate Collections for a news/blog element? :pray:

1 Like

Glad you’re liking Fred, IMO it’s a game changer for how we build certain websites on Modx. I haven’t managed to publish any of our tutorials yet, but here are some options you can do for a gallery:

Option 1
Create two elements, the first one called Gallery container which contains a <div data-fred-dropzone="gallery"></div> and then a second element called Gallery item that holds your item specific code i.e. img, li tag

Option 2
Create a Gallery element, create an option set which allows you to define number of gallery items. Then use a twig loop i.e.

<div class="gallery-wrapper">
{% for i in 0..(items - 1) %}
        <div data-fred-name="gallery-item-{{i}}" data-fred-rte="true">
            <h2 style="text-align:center">Click to edit heading</h2>
            <p style="text-align:center">Click here to edit the content</p>
            <img src="/path/to/holding/img.jpg" alt="" data-fred-name="gallery-image-{{i}}" data-fred-attrs="alt" loading="lazy">
        </div>
{% endfor %}
</div>


JSON

{
    "remote":true,
    "settings": [
    {
        "type": "slider",
        "name": "items",
        "label": "Gallery items",
        "min": 1,
        "max": 25,
        "step": 1,
        "value": 3
    }
]
}

I’ll hopefully get a chance to write up some tutorials now i’m in quarantine :D.

Let us know how you get on

Hi @inside-creative, many thanks for your quick response! I was even quicker though :wink: I managed to find all the pieces related to the Portfolio section from the “Creative One Page Theme” and more or less got a working gallery set up :slight_smile:

It would be great with some more tutorials – and/or perhaps another Theme which can be installed, containing a few more bits than the Creative One Page Theme which is the only one I’ve found so far (however great!).

If you get around to doing some tutorials or themes the next things on my wish list is News/Blog (similar to what can be build with Collections) and multi-language with Babel or similar :slight_smile:

My thoughts exactly with the quarantine which I guess we’re all more or less in – let’s take the opportunity to get some nice work done so at least something good comes out of this mess :pray:

All the best!

Hello again @inside-creative. Hope you’re doing alright in your quarantine!

I tried using your option #2 above to create an element for a basic Bootstrap slider but didn’t get very far :grimacing: This is what I’ve got:

<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
    
  <div class="carousel-inner">
    {% for i in 0..(items - 1) %}
        <div data-fred-name="gallery-item-{{i}}">
            <div class="carousel-item"><!-- Need to add active class for active slide -->
              <img class="d-block w-100" src="https://via.placeholder.com/300x150?text={{i}}" alt="" data-fred-name="gallery-image-{{i}}">
            </div>
        </div>
    {% endfor %}
  </div>

  <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
  
</div>

Options:

{
  "remote": true,
  "settings": [
    {
      "type": "slider",
      "name": "items",
      "label": "Slider items",
      "min": 1,
      "max": 25,
      "step": 1,
      "value": 3
    }
  ]
}

This gives me a slider with one slide with the number 3 on it. The number changes according to what I set the option slider to, which is a start I guess :sweat_smile:

How would I go about so I can add more images etc? If you have the time…

Hey, we’re hanging in there thanks.

Ok, so your issue relates to the way Bootstrap instigates its carousel, you need to add an active class to the first slide and change your markup slightly. This should work for you:

<div class="carousel-inner">
    {% for i in 0..(items - 1) %}
        <div class="carousel-item {{ (i)? : "active"}} ">
          <img class="d-block w-100" src="https://via.placeholder.com/300x150?text={{i}}" alt="" data-fred-name="gallery-image-{{i}}">
        </div>
    {% endfor %}
  </div>

This {{ (i)? : "active"}} is a twig ternary operator, and it’s comparing if i is false, which since 0 == false then the first slide gets the Active class.

Thanks @inside-creative, that’s one problem solved :+1:

The next issue is how to actually get the images in there. At the moment I only have one image and I don’t quite understand what I need to do to get the rest of the images in there? Do I need to create a new image element which I drop into this element/container…? Or can I create options in this element where I can enter image URL etc…?

So the way I updated it, you should be able to click on the image which will bring up the Fred Image editor. You can then use the arrow keys to navigate to each image:

UniConverter_000001

Ok, thats a terrible gif. But hopefully it shows you what I mean. This is your original code:

<div class="carousel-inner">
    {% for i in 0..(items - 1) %}
        <div data-fred-name="gallery-item-{{i}}">
            <div class="carousel-item"><!-- Need to add active class for active slide -->
              <img class="d-block w-100" src="https://via.placeholder.com/300x150?text={{i}}" alt="" data-fred-name="gallery-image-{{i}}">
            </div>
        </div>
    {% endfor %}
  </div>

I changed it to remove the first <div data-fred-name="gallery-item-{{i}}"> as that will cause problems with the tag on your image.

OMG I think I’ve got it :grin: Gotta dash but I’ll take a closer look when I’m back at my desk. Thanks a million!!

Right, still a few questions remaining I’m afraid to get that slider fully working…

  1. I need to crop the images to size, so I’m using pthumb on the placeholder. However, how do I apply pthumb to the image which the user replaces the placeholder with?

  2. Say I also want to add an alt-tag to each image, how do I set the option for this?

Many thanks!

The first part of your question requires a bigger write up (working on it now). The second point is simple. Add the following attribute to your img tag attrs="" i.e.

<img src="/path/to/img.jpg" alt="alt desc" loading="lazy" data-aos="fade" data-fred-name="image" data-fred-attrs="alt,data-aos,loading">

So this is the tricky part. Unfortunately, pthumbs doesn’t work with FRED yet. So you have two options:

  1. Use the FRED image editor when you select the image you want. You can right-click the image and select Resize and Rotate or click this symbol Screen Shot 2563-03-27 at 18.25.52

I normally save the image as a new file and just append the file name with slider-

  1. Redevelop how your slider works.

This is the tricky part, the way you’ve currently built your slider means each image has to be selected using the FRED image modal. However, you can create a Slider container element that holds a dropzone and a slide element that can be dropped into that zone. The benefit of this is, each slide element has it’s own options which will give you better control and allow you to use pthumbs, but it also means you have to find a new way of presenting your slides during editing as the dropzone will become inaccessible.

Try this

  1. Create slider-container element with dropzone
<div id="carouselExampleControls" class="carousel slide"> <!-- remove data-ride="carousel" -->
    
  <div class="carousel-inner" data-fred-dropzone="slider" data-fred-min-height-"250px">
    
  </div>

  <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>
  1. Create a slide element with your options
 <div class="carousel-item {{is_active? "active"}}">
    <img class="d-block w-100" src="[[phpthumbof? &input=`{{img}}` &options=`&w={{width}}&h={{height}}&q={{quality}}&zc={{zoom_crop}}&aoe=0&far=0`]]" alt="{{alt}}">
 </div>

{
    "remote":true,
    "settings": [
    {
        "type": "toggle",
        "name": "is_active",
        "label": "Is first slide?",
        "value": false
    },
    {
        "type": "image",
        "name": "img",
        "label": "Image",
        "mediaSource": "",
        "showPreview": true,
        "value": "https://via.placeholder.com/300x150"
    },
    {
        "type": "text",
        "name": "alt",
        "label": "Alt description",
        "value": "Enter a description for this item"
    },
    {
        "type": "slider",
        "name": "width",
        "label": "Width of image",
        "min": 0,
        "max": 1900,
        "step": 1,
        "value": 1440
    },
    {
        "type": "slider",
        "name": "height",
        "label": "Height of image",
        "min": 0,
        "max": 1080,
        "step": 1,
        "value": 960
    },
    {
        "type": "slider",
        "name": "quality",
        "label": "Image Quality",
        "min": 1,
        "max": 100,
        "step": 1,
        "value": 85
    },
    {
        "type": "select",
        "name": "zoom_crop",
        "label": "Zoom crop location",
        "value": "c",
        "options": {
            "C": "Center",
            "T": "Top",
            "L": "Left",
            "B": "Bottom",
            "R": "Right",
            "TL": "Top left",
            "TR": "Top Right",
            "BL": "Bottom left",
            "BR": "Bottom right"
        }
    }
]
}
  1. Drop the slider-container on the page first, then drop in your slides. However, here is where you run into rendering issues. What I typically do is stack the images using CSS and only instigate the slider when fred is not active. So to achieve this do something like this:
.carousel-inner {
        height:400px;
    }
    
    .fred--active .carousel-item {
        flex-basis: 50%;
        display: block; // this is required to show the image as Bootstrap displays none on all .carousel-items that dont have an active class
        max-height:385px;
    }
    .fred--active .carousel-inner {
        display:flex;
        flex-direction:row;
        flex-wrap: wrap;
        overflow-y: scroll;
    }

And then manually call your slider with something like:

if(!$('html').hasClass('fred--active')) {
    $('.carousel').carousel()
}

That should get you started. Good luck :smiley:

Hi @inside-creative, thank you so much for taking the time, it’s really helping me understand Fred and its possibilities a lot better!

The alt tag worked fine, I just had to add data-fred-name=“gallery-item-{{i}}” to the image.

As for pthumbs I think I’ll resort to your option #1 for now, and keep my fingers crossed for pthumbs support in the near future :wink:

Thanks again!

Very nice!! this help me a lot.

pThumb works just fine now, I’m using it for a lightbox effect, I put this in an image-type Element’s markup

<div data-fred-block-class="col-lg-4 col-sm-6">
<a class="portfolio-box" href="{{ image }}" title="{{ title }}" data-lightbox="{{ title }}" data-title="{{ title }}">
 <img class="img-fluid" src="[[pThumb? &input=`{{ image }}` &options=`w=600&h=350&q=45&far=1`]]" alt="{{ alt }}">
 </a>
</div>

You can see it in action here on my site

Actually, I copied this from the one-page theme, so some of those attributes probably aren’t necessary.

I am now using TinyMCE to edit the entire content area, including inserting and editing the images. When you use TinyMCE’s image editing tool to resize the image, it replaces the image path with the resized image’s base64 encoding. No more need for pThumb or for dragging in individual image and paragraph elements for large areas of content, such as a blog post.

I’ve created a custom rte configuration that allows me to add classes to the image, and also added the code view option to the TinyMCE menu.

"image_class_list": [
{
  "title": "None",
  "value": ""
},
{
  "title": "Left",
  "value": "rounded float-left mr-5 p-1 border border-secondary img-fluid"
}
],

Then I found a Bootstrap lightbox extension.

Now I can insert my image with the classes I want, then open the area in code view. I just add the lightbox a tags around the image tags, taking care not to disturb the image tags. I insert the image, then copy the src path before editing the image, so I can easily paste that back into the link tag.

<a href="path/to/the/image.jpg" data-toggle="lightbox">
<img ...>
</a>

I’m not sure I’m following how you use TinyMCE. Can you use it to make pThumb work for a carousel with a flexible number of images such as below?

<div id="bootstrapCarousel" class="carousel slide" data-ride="carousel">
  <div class="carousel-inner">
    {% for i in 0..(items - 1) %}
            <div class="carousel-item {{ (i)? : "active"}}">
              <img class="d-block w-100" src="[[pthumb? &input=`[[++fred.theme.mytheme.theme_dir]]images/placehold.jpg` &options=`aoe=1&w=1200&h=600&dpi=72&f=jpg&zc=c`]]" alt="Description" data-fred-name="image-{{i}}" data-fred-attrs="alt">
            </div>
    {% endfor %}
  </div>
  {% if items > 1 %}
  <a class="carousel-control-prev" href="#bootstrapCarousel" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#bootstrapCarousel" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
  {% endif %}
</div>

I scrapped the above and replaced it with two elements instead, one for the carousel container and one for the carousel images, which works with pThumb. It would be awesome though if a single element could be used such as above with pThumb still working.

Here’s what I use instead of the above to make pThumb work. However, for the site owner the above single element would be preferable since you don’t have to drag-and-drop the images into the container like you do with the below. If only it worked with pThumb so the site owner doesn’t have to do manual cropping…

Carousel container element:

<div id="{{carouselID}}" class="carousel slide" data-ride="carousel">
    
  <div class="carousel-inner" data-fred-dropzone="slider" data-fred-min-height="300px">
    
  </div>
  
{% if showControls == true %}
  <a class="carousel-control-prev" href="#{{carouselID}}" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#{{carouselID}}" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
{% endif %}
  
</div>

<style>
    .fred--active .carousel-item {
      /*  flex-basis: 50%;*/
        display: block; // this is required to show the image as Bootstrap displays none on all .carousel-items that dont have an active class
      /*  max-height:385px;*/
    }
    .fred--active .carousel-inner {
        display:flex;
        flex-direction:row;
        flex-wrap: wrap;
        overflow-y: scroll;
    }
</style>

Image element:

 <div class="carousel-item {{is_active? "active"}}">

    <picture> 
        <source srcset="[[pthumb? &input=`{{bild}}` &options=`aoe=1&w=2000&h={{sliderHeight}}&q={{quality}}&dpi=72&f=jpg&zc=c`]]" media="(min-width: 1400px)">
        <source srcset="[[pthumb? &input=`{{bild}}` &options=`aoe=1&w=1400&h={{sliderHeight}}&q={{quality}}&dpi=72&f=jpg&zc=c`]]" media="(min-width: 768px)">
        <source srcset="[[pthumb? &input=`{{bild}}` &options=`aoe=1&w=800&h={{sliderHeight}}&q={{quality}}&dpi=72&f=jpg&zc=c`]]" media="(min-width: 576px)">
        <img src="[[pthumb? &input=`{{bild}}` &options=`aoe=1&w=600&h={{sliderHeight}}&q={{quality}}&dpi=72&f=jpg&zc=c`]]" alt="{{alt}}" class="d-block img-fluid" style="width:100%;height:100%">
    </picture>
    
</div>

No, that’s another matter. I’m just using the TinyMCE image insertion to insert single images that get slightly modified in code for a lightbox effect.

For carousels and rotators, I give each page a thumbnail TV configured to work with Fred, then I can use a listing snippet to gather the thumbnails and output them with a formatting chunk as usual. A Fred element with the snippet call can get dropped into a dropzone where you need it.

No, that’s another matter. I’m just using the TinyMCE image insertion to insert single images that get slightly modified in code for a lightbox effect.

I see, that will really come in handy when you want to give the site owner the option to insert images into a text area easily.

For carousels and rotators, I give each page a thumbnail TV configured to work with Fred, then I can use a listing snippet to gather the thumbnails and output them with a formatting chunk as usual. A Fred element with the snippet call can get dropped into a dropzone where you need it.

How do you configure a TV to work with Fred? Can the site owner use the Fred interface to add the images or do they have to go into the Manager?