Custom Gallery

SOLVE
tstrack
Contributor | Platinum Partner

Is there a way to customize the HubL Gallery module? Basically removed all of the styling, wrappers, etc. so it just spits out the images? Then take those images and wrap them in some HubL code like so:

 

<div class="slider">
  <div><img src="this.jpg"></div>
  <div><img src="that.jpg"></div>
  <div><img src="andthis.jpg"></div>
</div>

Then I could trigger the slider with my own custom JS? Like so:

 

$('.slider').slick({
  infinite: true,
  slidesToShow: 3,
  slidesToScroll: 3
});

I'm just not a fan of how the Gallery Module looks out the box. I'd like to do my own thing with it.

 

Has anybody ever did this or know of a way how to? Thanks in advance!

0 Upvotes
1 Accepted solution

Accepted Solutions
Jsum
Solution
Key Advisor

Hi,

You can customize the image gallery/slider modules using HubL:

 

{% gallery "crm_gallery"  label="CRM Gallery", export_to_template_context=True %}

The "export_to_template_context" part releases all of the data for the module into the template for you to play with. The data that is available for the gallery module is: 

"slides": [{
               "img_src": "",
                 "alt_text": "",
                 "href": "",
                 "link_url": "",
                 "open_in_new_tab": true,
                  "show_caption": false,
                  "caption": ""
               }]

You set this data up by adding images to the gallery on the editing page, so you would go to the page editor and add an image, the alt text for the image, a link if needed, and a caption.

 

Then you can fully customize the gallerys markup by looping through it:

{% gallery "crm_gallery"  label="CRM Gallery", export_to_template_context=True %}
{% for item in widget_data.crm_gallery.slides %}

    <img src="{{ item.img_src }}" alt="{{ item.alt_text }}">

{% endfor %}

I create the gallery widget, exporting the data to the template. I then make a for loop that says for each slide in the image gallery I want to output this image tag. 

 

The code inside the for loop can be as simple or complex as you can make it. you can use divs or other wrappers, paragraphs, ids, classes, you name it. It will print whatever you put here per slide, so if you add 100 images to the gallery it will out put the code 100 times on the page. 

 

You can use any of your own js to do what ever you want with the images because you have full control of how the data is output.

 

To use the data just use

{{ item.img_src }}
{{ item.alt_text }}
{{ item.caption }}
{{ item.href }}
etc.

Where Item is the name given in the for loop: 

{% for item in widget_data.crm_gallery.slides %}

You can change "item" to pretty much anything like "slide", "image", "block". just make sure you change that identifier in the data tokens and your good to go.  

 

crm_gallery is my system name for the gallery widget: 

{% gallery "crm_gallery"  label="CRM Gallery", export_to_template_context=True %}

so make sure that 

{% for item in widget_data.crm_gallery.slides %}

reflects what ever you use as a system name for your widget.

 

You can place all of this inside a hubl module in the drag and drop editor or right in the page of a coded page.

View solution in original post

22 Replies 22
stefen
Key Advisor | Partner

I think the easiest way is to use a flex column with image modules. For example, a flex column with a custom class "my-custom-slider" can be used with Flickity by initializing it like so:

$('.my-custom-slider').flickity({
    cellSelector: '.hs_cos_wrapper_type_linked_image'
});

that's how we created the partners carousel on our homepage: https://www.growwithsms.com/

 

The only issue with this is you have to deal with HubSpot's markup. Slick.js requires all slides to be the direct child of the parent category, so you would need to initialize it like this:

$('.my-custom-slider > span').slick({
// options
});
Stefen Phelps, Community Champion, Kelp Web Developer
0 Upvotes
tstrack
Contributor | Platinum Partner

That's an interesting solution. I think it would accomplish what I'm looking to do. And maybe adding the no_wrapper = true to the modules would help alleviate some of the parent/child issues.

 

Thanks, Stefen. I'll give this a try!

0 Upvotes
Jsum
Solution
Key Advisor

Hi,

You can customize the image gallery/slider modules using HubL:

 

{% gallery "crm_gallery"  label="CRM Gallery", export_to_template_context=True %}

The "export_to_template_context" part releases all of the data for the module into the template for you to play with. The data that is available for the gallery module is: 

"slides": [{
               "img_src": "",
                 "alt_text": "",
                 "href": "",
                 "link_url": "",
                 "open_in_new_tab": true,
                  "show_caption": false,
                  "caption": ""
               }]

You set this data up by adding images to the gallery on the editing page, so you would go to the page editor and add an image, the alt text for the image, a link if needed, and a caption.

 

Then you can fully customize the gallerys markup by looping through it:

{% gallery "crm_gallery"  label="CRM Gallery", export_to_template_context=True %}
{% for item in widget_data.crm_gallery.slides %}

    <img src="{{ item.img_src }}" alt="{{ item.alt_text }}">

{% endfor %}

I create the gallery widget, exporting the data to the template. I then make a for loop that says for each slide in the image gallery I want to output this image tag. 

 

The code inside the for loop can be as simple or complex as you can make it. you can use divs or other wrappers, paragraphs, ids, classes, you name it. It will print whatever you put here per slide, so if you add 100 images to the gallery it will out put the code 100 times on the page. 

 

You can use any of your own js to do what ever you want with the images because you have full control of how the data is output.

 

To use the data just use

{{ item.img_src }}
{{ item.alt_text }}
{{ item.caption }}
{{ item.href }}
etc.

Where Item is the name given in the for loop: 

{% for item in widget_data.crm_gallery.slides %}

You can change "item" to pretty much anything like "slide", "image", "block". just make sure you change that identifier in the data tokens and your good to go.  

 

crm_gallery is my system name for the gallery widget: 

{% gallery "crm_gallery"  label="CRM Gallery", export_to_template_context=True %}

so make sure that 

{% for item in widget_data.crm_gallery.slides %}

reflects what ever you use as a system name for your widget.

 

You can place all of this inside a hubl module in the drag and drop editor or right in the page of a coded page.

View solution in original post

tstrack
Contributor | Platinum Partner

Thanks! I will try this out.

0 Upvotes
tstrack
Contributor | Platinum Partner

Brilliant. It worked great! Thanks for your time and the detailed explanation.

 

I used it in two different instances already. The second was actually inside some JS. Turns out HubL works right inside JS like so:

 

{% gallery "floor_plans" label="Floor Plans", export_to_template_context=True %}
<script>
	$('#gallery').click(function(e) {
		e.preventDefault();
		$.swipebox( [
			{% for item in widget_data.floor_plans.slides %}
				{ href:'{{ item.img_src }}', title:'{{ item.alt_text }}' },
			{% endfor %}
		]);
	});
</script>
0 Upvotes
Jsum
Key Advisor

Very Cool! Hubspot is written in python and HubL is a hubspot specific version of Jinja which is a templating language build in python (like jquery is connected to javascript). Python, jinja, and hubl are all server side languages while html, css, and js are all client side. server side code is processed by the server before being sent to the client so those hubl tokens are exchanged for their designated values before hitting the client where the javscript is processed. I haven't had a chance to use hubl tokens in javascript but it is cool to see that it will work like this. THanks!

tstrack
Contributor | Platinum Partner

Hey Jsum,

 

Is there a way to make a re-useable custom module with this code? Or does it have to be in the actual page template?

0 Upvotes
Jsum
Key Advisor

@tstrack Yes you can make a global module out of the hubl module that you have this code in. then you would drag from the global groups section to the each page that needs it. 

0 Upvotes
jobnomade
Participant

Hi,

 

I tried your solution but do not see any success or results as expected.

I have 

 

{% gallery "lc_gallery"  label="LC Gallery", export_to_template_context=True %}

<div class="lc_gallery">
{% for item in widget_data.lc_gallery.slides %}
    
        <img src="{{ item.img_src }}" alt="{{ item.alt_text }}" >

{% endfor %}
</div>

This is included in a custom module, which I added to a template. On the web page, the module has no options like displayed in the screenshot. What am I doing wrong?

Screen Shot 2017-10-16 at 00.31.36.png

0 Upvotes
Jsum
Key Advisor

@jobnomade,

 

You shouldn't use a custom module. You can, and when you place a HubL module in a custom module that is not native to the custom module (isn't added through the drop down of module options in the custom module) then the module will appear outside of the custom module in your main list of modules.

 

The main issue with using export_to_template_context in a custom module is that you can't just use:

 widget_data.lc_gallery.slides

to identify your data. You use this but you also have to identify the custom module that the hubl module is inside of and I believe you have to find the id in the html to do this. Basically it is a pain if you don't have a high level of experience breaking these modules apart and putting them back together.  figuring it out is going to make you a stronger Hubspot developer but I don't think a custom module is the best solution in this situation.


You should try the code in a custom html module or a custom HubL module first, and see if it works. If it works then move onto finding a way to make it global. If you use a custom html module you can literally just click the gear icon and choose to make it global, problem solved. then you just have to drag it into the templates you want it in the same as you would with a custom module but you don't have to work around the custom module itself. 

jobnomade
Participant

Hi, thanks for your reply.
I used the available HUBL module and added my code there. It is working.

This is the code within the module

{% image "image" %}
{% image "reference_image" label='Referenzbild', alt='Ein Logo oder Bild einer Referenz', src='http://via.placeholder.com/200x120', width='200', style='margin: 1vw;' %}

{% gallery "lc_gallery"  label="LC Gallery", export_to_template_context=True %}

<div class="lc-gallery-no-slider module-{{ parent_custom_widget_name }}">
    {% for item in widget_data.lc_gallery.slides %}
    <div class="gallery-item gallery-thumbnail">
            <div class="gallery-item-wrapper">
                <a data-fancybox data-caption="{{ item.caption }}" href="{{ item.img_src }}">
                    <img class="gallery-item-image image-{{ loop.index }}" src="{{ item.img_src }}" alt="{{ item.alt_text }}" >
                </a>
            </div>
    </div>
    {% endfor %}

</div>
<div class="clearfix"></div>
<div class="top-link-wrapper p-t-2vw p-b-1vw">
    <a href="#oben" class="top-link">
        <img src="https://cdn2.hubspot.net/hubfs/3335841/01_Website%20Bilder/Icons/nach-oben-icon.svg" alt="nach-oben-icon.svg" title="nach-oben-icon.svg" caption="false" data-constrained="true" style="width: 52px;" width="52">
    </a>
</div>

If I make this a global module which can be reused. I tested this use case:
I reused the same global module on the same template as the web page has different sections with different galleries. The additional gallery displays the same images from the previous gallery which based on the same HUBL module.
I tested to use a different identifier for the gallery name

{% gallery "lc_gallery_test"  label="LC Gallery", export_to_template_context=True %}

You see "lc_gallery_test" identifier. As soon I changed it, the observation with duplicated image content disappears and I have a fresh empty gallery.
The question is, can I have a unique identifier for the gallery name? Or is there another approach?

0 Upvotes
Jsum
Key Advisor

They are only doing this because your system name for the module is the same for each module. You have to make the system name unique if you are going to use it more than once on the same page.  In this situation I think the easiest thing you could do is try to get it to work in a custom module. 

0 Upvotes
stevenma
Member

Hi Jonathan,

 

I am new to Hubspot and was asked by my boss to find a wy to remove the arrows at the end of the carousels.   I read your reponse (article 6141) and am a little lost as I do not know Java or Hubl (I know C#...not much use).

 

This is the code of my carousel:

 

{% set slides = [] %}

{% for slide in module.slides %}

{% if (slide.link_url is string_startingwith "http") or (slide.link_url is string_startingwith "/") %}
{% set link = slide.link_url %}
{% elif !slide.link_url %}
{% set link = none %}
{% else %}
{% set link = "//" ~ slide.link_url %}
{% endif %}

{{ slides.append({ "caption": slide.caption,
"show_caption": slide.show_caption,
"link_url": link,
"alt_text": slide.img.alt,
"img_src": slide.img.src,
"open_in_new_tab": slide.open_in_new_tab
}) | string | replace('true', '')
}}
{% endfor %}

{% gallery
"Gallery"
display_mode='{{ module.display_mode }}'
sizing='{{ module.sizing }}',
transition='{{ module.transition }}',
caption_position='{{ module.caption_position }}',
auto_advance='{{ module.auto_advance }}',
overrideable=True,
description_text='',
show_pagination='{{ module.show_pagination }}',
label='{{title}}',
slides='{{ slides }}',
loop_slides='{{ module.loop_slides }}',
num_seconds='{{ module.num_seconds }}',
lightboxRows='{{ module.lightboxRows }}'
%}

 

Considering your article, can you advise what needs to be done to remove the "<"  and ">" that surround our carousel images?

 

 

Thanks in advance for your help.

 

Take Care,

Steven Maki

0 Upvotes
Jsum
Key Advisor

Hi @stevenma ,

 

a couple of things to note:

 

1. My answer to this question is almost 2 years old, and there have been some awesome updates to the custom module editor that make using "export_to_template_context" obsolite. 

 

2. Your question is more related to slick.js than HubL. The arrows are generated from the slick.js script, not from anything hubspot related. check out the slick.js docs.

 

That being said, here is an example of removing the arrows from a slick.js carousel:

$('.slider-container').slick({
    arrows: false
});
0 Upvotes
stevenma
Member

Hi @Jsum 

 

My apologies in advance if this is not an apropriate question.   I went to the template and looked at all the code and I did not find any reference to slick.js.   Where should Ibe able to locate that reference?

 

I understand that slick.js is not related to Hubspot but wouldn't it have been added by the Hubspot team?  Do templates by default make use of slick.js?

 

Thanks in advance for your help.   🙂 . And if inappropriate, please delete this post an email me directly if that is possible.

 

Take care,

Steven Maki

0 Upvotes
Jsum
Key Advisor

Hi @stevenma ,

 

not at all, this is still Hubspot development.

 

This is how a basic slick.js set up looks:

<div class="slide-container">
    <div class="slide"></div>
    <div class="slide"></div>
    <div class="slide"></div>
</div>

<script src="jquery.js"></script>
<script src="slick.js"></script>

<script>
    $('.slide-container').slick({
        option: value
    });
</script>

Jquery is loaded, slick.js then loads (dependent on jquery), then you can call the slick function that loads from slick.js.

The custom slick reference can exist in a separate .js file though, as long as it is called after slick.js loads. While the above is the most basic setup, depending on how your site is developed, it could be much more complicated. I just recently rebuilt a site where the original developers took the entire slick.js script, plugged it into their own custom js framework, and customized it to where the docs for slick.js were pretty much useless. 99% of the time that isn't the case though.

 

You most likely have a .js file attached to your page, and that .js file would contain the custom slick reference:

    $('.slide-container').slick({
        option: value,
option: value });

See what scripts are connected to your page, open in them in the design manager, and you can use ctrl+f (cmd+f) to search the file for "slick". You will find it if it exists in that file. 

You can also view the source code for the page and use ctr+f to search the source code for any references to "slick". that might give you a clue.

stevenma
Member

Hi JSum,

 

I am having a difficult time figuring out something seemingly basic.  I have a blog template in Hubspot and am trying to access the souce code but do not know how to get there.   I previewed my template and then click on the inspect via a right click and see the code.   How do I access this code?   The seems to be a script tag with the arrows but no reference to external slick.js file.   Oh, yeah, as it has been a while, all I am trying to do is remove the arrows from the carrousel.

 

BTW, I went on Hubspot Developer and spent several hours reading and could not figure it out.   Thanks in advance for your help.

 

Take care,

Steven Maki

0 Upvotes
stevenma
Member

Hi JSum,

 

You replied to my question ‎06-12-2019 and I cannot figure out how to make the change (re:my post from 2 weeks ag0).   Do I need to contact customer service or can you guide me?

 

Thanks in advance.

Best regards,

Steven Maki (StevenMa)

0 Upvotes
mateomm22
Participant

Hi there, 

I'm triyng to set the properties of the slick like this: 

$('.slick-slider').slick({
    infinite: true,
    slidesToShow: 5,
    centerMode: true,
    responsive: [{
      breakpoint: 600,
      settings: {
        slidesToShow: 3
      }
    }]
  });


I figured out that the script that initializes the script is located at the bottom of the page, below my custom script and it's overwriting mine, what I'm doing wrong?

0 Upvotes
Jsum
Key Advisor

js libraries work like this:

 

first you place the library/api/script. This will contain the rules and functions that make the feature work.

 

then you place your javascript. This javascript that you reference the above library with, changing rules or adding functions, etc. 

 

The browser reads an html document from top to bottom. That's why when there are two css rules to the same element, the css rule at the bottom is the one that is applied in the end.

 

scripts work the same way. You can't reference a function that hasn't been created yet, and the function can't be created until after the browser has read the js file containing that function. Typically you will find "____ not defined as a function" errors in your console if this is your issue. 

0 Upvotes
mateomm22
Participant

I need to customize my slider settings to show and scroll 5 slides at once, is that possible?
No matter what I do or where I put my custom script, when the code gets rendered in the browser, the script that inits the slider is placed at the very bottom of the <body>  tag below mine.

Position of the scriptPosition of the script
I need to overwrite this settings, and customize the slider.


0 Upvotes
VNuccio
Member

 

mateomm22,

 

 

did you ever figure this out? struggling with it now

0 Upvotes