Logo
Home
Resources

Product

Custom Workflow

Resources

Blog
Youtube
Template
Home
>
Product
>
Template Top
>
detail

HubSpot CMS: A Guide to the Dynamic "Product Listing Module"

The Product Listing Module allows you to leverage product information managed within HubSpot CRM directly as website content. This module enables the simultaneous realization of centralized data management and automated website display.

‍

Demo Video

Over view
Code

Detail

The Product Listing Module allows you to leverage product information managed within HubSpot CRM directly as website content. This module enables the simultaneous realization of centralized data management and automated website display.

1. Objectives

The primary objective of this module is to connect your CRM product database directly to your site, ensuring the latest information is displayed without manual effort.

  • Automatic Updates: When prices or inventory status are changed in the CRM, the website display is updated in real-time.
  • Condition-Based Display: Easily filter products by setting specific criteria, such as "certain categories" or "specific price ranges."
  • Responsive Design: Features an automatic grid adjustment function that adapts the number of columns based on the device's screen width.

2. Use Cases

  • Dynamic Product Lists: Extract and display only products that match specific attributes, such as "New Items" or "Recommended Products," from your entire inventory.
  • Price-Specific Catalogs: Build product lists with minimum and maximum price filters to help users browse within their budget.
  • Enhanced Browsing Experience: Even with a large volume of products, a pagination feature provides a comfortable interface for users to find what they need.

3. Implementation and Operation Steps

This section covers the entire process from creating a new page to applying the provided code and configuring operational settings.

Step 1: Page Creation and Module Placement

Navigate to the "Content" menu in the HubSpot dashboard and create a new page (such as a Landing Page). In the editor's left sidebar, search for the module by name, then drag and drop it into the editing area.

Step 2: Applying Code in the Design Manager

To enable advanced dynamic functionality, perform the following in the Design Manager:

  • File Preparation: Create a new module within the Design Manager.
  • Paste the Code: Simply copy and paste the provided source code into its respective sections (HTML/HubL, CSS, and JS), then save and publish.

Step 3: Editor Configuration and Customization

Once the code is applied, you can fine-tune the details via the no-code side panel in the page editor:

  • Filtering: Set the attributes or conditions (AND/OR) for the products you wish to display.
  • Price Settings: Input minimum and maximum price values to update the list dynamically.
  • Layout and Display Items: Choose between list or grid formats and toggle the visibility of images, titles, descriptions, and prices.
  • Design Adjustments: Fine-tune card background colors, button colors, and font sizes to match your brand, then click "Publish" to finish.

Module Source Code

Create a "New Module" in the HubSpot Design Manager and paste the following code into each respective section.

1. fields.json

This is the field definition. It consists of a repeater field (Items) and style setting fields (Styles).

[
 {
  "children": [
   {
    "default": {
     "property": null
    },
    "display_width": null,
    "id": "21a1316c-97b0-d7b0-8ee9-f1efd1b620f0",
    "label": "filter_property_1",
    "locked": false,
    "name": "filter_property_1",
    "object_type": "PRODUCT",
    "required": false,
    "type": "crmobjectproperty"
   },
   {
    "allow_new_line": false,
    "display_width": null,
    "id": "ded3e59b-bc30-df2b-c324-df0578a634a3",
    "label": "filter_value_1",
    "locked": false,
    "name": "filter_value_1",
    "required": false,
    "type": "text"
   },
   {
    "default": {
     "property": null
    },
    "display_width": null,
    "id": "fe270e45-324c-4f9c-6830-fe9255855798",
    "label": "filter_property_2",
    "locked": false,
    "name": "filter_property_2",
    "object_type": "PRODUCT",
    "required": false,
    "type": "crmobjectproperty"
   },
   {
    "allow_new_line": false,
    "display_width": null,
    "id": "d2d46f8b-e173-83cb-6342-68f7e591e0d0",
    "label": "filter_value_2",
    "locked": false,
    "name": "filter_value_2",
    "required": false,
    "type": "text"
   },
   {
    "choices": [
     [ "AND", "AND" ],
     [ "OR", "OR" ]
    ],
    "display": "select",
    "display_width": null,
    "id": "8b122895-a6f5-fd3e-2645-9996bad396fb",
    "label": "filter_operator",
    "locked": false,
    "multiple": false,
    "name": "filter_operator",
    "preset": null,
    "reordering_enabled": true,
    "required": false,
    "type": "choice"
   }
  ],
  "default": {
   "filter_property_1": { "property": null },
   "filter_property_2": { "property": null }
  },
  "display_width": null,
  "expanded": false,
  "group_occurrence_meta": null,
  "id": "6c676894-4452-8dcd-d0d5-e8e478880c93",
  "label": "product_filter_group",
  "locked": false,
  "name": "product_filter_group",
  "required": false,
  "tab": "CONTENT",
  "type": "group"
 },
 {
  "children": [
   {
    "default": { "property": null },
    "display_width": null,
    "id": "dbe0096f-2834-624c-7fd2-2da6002978eb",
    "label": "price_property",
    "locked": false,
    "name": "price_property",
    "object_type": "PRODUCT",
    "required": false,
    "type": "crmobjectproperty"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "12722c90-e78d-06aa-7830-cb92a141c7e9",
    "label": "price_min",
    "locked": false,
    "name": "price_min",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "246d9b50-f891-a890-b2f7-7122b46a6818",
    "label": "price_max",
    "locked": false,
    "name": "price_max",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "allow_new_line": false,
    "display_width": null,
    "id": "05ec04ed-0e36-1636-7f64-c9f4945885d3",
    "label": "price-unit",
    "locked": false,
    "name": "price_unit",
    "required": false,
    "type": "text"
   }
  ],
  "default": {
   "price_property": { "property": null }
  },
  "display_width": null,
  "expanded": false,
  "group_occurrence_meta": null,
  "id": "8782bd12-7864-08e6-6f22-145c61d170c2",
  "label": "price_filter_group",
  "locked": false,
  "name": "price_filter_group",
  "required": false,
  "tab": "CONTENT",
  "type": "group"
 },
 {
  "children": [
   {
    "choices": [ [ "list", "List" ], [ "grid", "Grid" ] ],
    "display": "select",
    "display_width": null,
    "id": "87578ceb-e94e-1bc4-8e69-48d06b174075",
    "label": "layout_type",
    "locked": false,
    "multiple": false,
    "name": "layout_type",
    "preset": null,
    "reordering_enabled": true,
    "required": false,
    "type": "choice"
   },
   {
    "choices": [ [ "2", "2列" ], [ "3", "3列" ], [ "4", "4列" ] ],
    "display": "select",
    "display_width": null,
    "id": "73b1c3a2-da54-250c-2b04-02cc44a2d356",
    "label": "grid_columns",
    "locked": false,
    "multiple": false,
    "name": "grid_columns",
    "preset": null,
    "reordering_enabled": true,
    "required": false,
    "type": "choice"
   },
   {
    "default": false,
    "display": "checkbox",
    "display_width": null,
    "id": "74a27f7c-f47b-dad7-b921-af66d047bdcb",
    "label": "show_title",
    "locked": false,
    "name": "show_title",
    "required": false,
    "type": "boolean"
   },
   {
    "default": { "property": null },
    "display_width": null,
    "id": "c456fdc6-bdad-63a1-a815-3564a70c176c",
    "label": "title_property",
    "locked": false,
    "name": "title_property",
    "object_type": "PRODUCT",
    "required": false,
    "type": "crmobjectproperty"
   },
   {
    "default": false,
    "display": "checkbox",
    "display_width": null,
    "id": "b18438bd-b826-0a50-a526-fc6301d9afbf",
    "label": "show_description",
    "locked": false,
    "name": "show_description",
    "required": false,
    "type": "boolean"
   },
   {
    "default": { "property": null },
    "display_width": null,
    "id": "1ba9c3ef-d6c5-89d5-e8f1-6ff0b6e5e2ac",
    "label": "description_property",
    "locked": false,
    "name": "description_property",
    "object_type": "PRODUCT",
    "required": false,
    "type": "crmobjectproperty"
   },
   {
    "default": false,
    "display": "checkbox",
    "display_width": null,
    "id": "b4fa6914-d231-04da-5a0f-4e0da2404ea6",
    "label": "show_price",
    "locked": false,
    "name": "show_price",
    "required": false,
    "type": "boolean"
   },
   {
    "default": false,
    "display": "checkbox",
    "display_width": null,
    "id": "f464ac0f-6414-be32-d65c-b273bfa1bcc5",
    "label": "show_image",
    "locked": false,
    "name": "show_image",
    "required": false,
    "type": "boolean"
   },
   {
    "default": { "property": null },
    "display_width": null,
    "id": "7443ac36-a521-b738-8a30-548f8c4fa6ea",
    "label": "image_property",
    "locked": false,
    "name": "image_property",
    "object_type": "PRODUCT",
    "required": false,
    "type": "crmobjectproperty"
   },
   {
    "choices": [
     [ "1:1", "1:1" ], [ "4:3", "4:3" ], [ "16:9", "16:9" ], [ "3:4", "3:4" ], [ "custom", "custom" ]
    ],
    "display": "select",
    "display_width": null,
    "id": "65cd2a7a-c23b-85a4-0843-893a32095c1e",
    "label": "image_size",
    "locked": false,
    "multiple": false,
    "name": "image_size",
    "preset": null,
    "reordering_enabled": true,
    "required": false,
    "type": "choice",
    "visibility": {
     "controlling_field_path": "display_group.show_image",
     "controlling_value_regex": "true",
     "operator": "EQUAL"
    }
   },
   {
    "default": false,
    "display": "checkbox",
    "display_width": null,
    "id": "aaf6e609-42a1-3a14-c28f-80bc22f07951",
    "label": "show_button",
    "locked": false,
    "name": "show_button",
    "required": false,
    "type": "boolean"
   },
   {
    "allow_new_line": false,
    "display_width": null,
    "id": "37dbbd32-9900-9441-2449-8fa65a91740a",
    "label": "button_text",
    "locked": false,
    "name": "button_text",
    "required": false,
    "type": "text"
   },
   {
    "default": { "property": null },
    "display_width": null,
    "id": "eec8ee75-487f-b2be-fe91-726ae5a899f1",
    "label": "button_url_property",
    "locked": false,
    "name": "button_url_property",
    "object_type": "PRODUCT",
    "required": false,
    "type": "crmobjectproperty"
   },
   {
    "default": false,
    "display": "checkbox",
    "display_width": null,
    "id": "e2151b1d-9f11-39d7-e234-4458a27af46c",
    "label": "show_rating",
    "locked": false,
    "name": "show_rating",
    "required": false,
    "type": "boolean"
   },
   {
    "default": { "property": null },
    "display_width": null,
    "id": "1816232f-8ee0-4d18-df38-7485d4f8d46a",
    "label": "rating_property",
    "locked": false,
    "name": "rating_property",
    "object_type": "PRODUCT",
    "required": false,
    "type": "crmobjectproperty"
   },
   {
    "default": 200,
    "display": "text",
    "display_width": null,
    "id": "3e9d25f9-ac21-3c32-0964-1f86c9251006",
    "label": "image_height",
    "locked": false,
    "max": 500,
    "min": 100,
    "name": "image_height",
    "required": false,
    "step": 1,
    "type": "number",
    "visibility": {
     "controlling_field_path": "display_group.image_size",
     "controlling_value_regex": "custom",
     "operator": "EQUAL"
    }
   }
  ],
  "default": {
   "show_title": false,
   "title_property": { "property": null },
   "show_description": false,
   "description_property": { "property": null },
   "show_price": false,
   "show_image": false,
   "image_property": { "property": null },
   "show_button": false,
   "button_url_property": { "property": null },
   "show_rating": false,
   "rating_property": { "property": null },
   "image_height": 200
  },
  "display_width": null,
  "expanded": false,
  "group_occurrence_meta": null,
  "id": "cf272e81-e968-0b27-0cda-8c982e467642",
  "label": "display_group",
  "locked": false,
  "name": "display_group",
  "required": false,
  "tab": "CONTENT",
  "type": "group"
 },
 {
  "children": [
   {
    "default": { "color": null, "opacity": null },
    "display_width": null,
    "id": "60c1119d-7f87-c270-f434-993283d3d37f",
    "label": "title_color",
    "locked": false,
    "name": "title_color",
    "required": false,
    "type": "color"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "6413ec2e-0eed-1523-6f6d-c8ff72145966",
    "label": "title_font_size",
    "locked": false,
    "name": "title_font_size",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "default": { "color": null, "opacity": null },
    "display_width": null,
    "id": "12dcca28-8f40-9388-fd05-5357e2085b10",
    "label": "description_color",
    "locked": false,
    "name": "description_color",
    "required": false,
    "type": "color"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "b48859e4-238b-7232-d093-6bbbe219d406",
    "label": "description_font_size",
    "locked": false,
    "name": "description_font_size",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "default": { "color": null, "opacity": null },
    "display_width": null,
    "id": "7c51472f-60d4-9076-8dd7-7cb93fceb4d2",
    "label": "price_color",
    "locked": false,
    "name": "price_color",
    "required": false,
    "type": "color"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "27d76c08-d9ed-31c8-c4d3-e735e09314dd",
    "label": "price_font_size",
    "locked": false,
    "name": "price_font_size",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "default": { "color": null, "opacity": null },
    "display_width": null,
    "id": "9c745c5a-240a-3aa0-9429-a2e65ff8a858",
    "label": "card_border_color",
    "locked": false,
    "name": "card_border_color",
    "required": false,
    "type": "color"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "de7dd7b4-9810-344c-ff7f-ede282ea2165",
    "label": "card_border_width",
    "locked": false,
    "name": "card_border_width",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "default": { "color": null, "opacity": null },
    "display_width": null,
    "id": "cc87fa3a-e84a-7f1f-e1d5-6edc648431f3",
    "label": "card_background_color",
    "locked": false,
    "name": "card_background_color",
    "required": false,
    "type": "color"
   },
   {
    "default": { "color": null, "opacity": null },
    "display_width": null,
    "id": "23b4f959-7d5e-859a-41df-e472ce9927b0",
    "label": "button_background_color",
    "locked": false,
    "name": "button_background_color",
    "required": false,
    "type": "color"
   },
   {
    "default": { "color": null, "opacity": null },
    "display_width": null,
    "id": "f6e6c5e2-20af-303f-67a7-8b928236fd96",
    "label": "button_text_color",
    "locked": false,
    "name": "button_text_color",
    "required": false,
    "type": "color"
   },
   {
    "allow_new_line": false,
    "display_width": null,
    "id": "992e0bc9-9f2d-b9ac-adf0-9d19ad7cc20e",
    "label": "card-min-width",
    "locked": false,
    "name": "card_min_width",
    "required": false,
    "type": "text"
   },
   {
    "allow_new_line": false,
    "display_width": null,
    "id": "c497ac8d-2ca1-5e35-f945-4c5888e6d158",
    "label": "card-min-height",
    "locked": false,
    "name": "card_min_height",
    "required": false,
    "type": "text"
   }
  ],
  "default": {
   "title_color": { "color": null, "opacity": null },
   "description_color": { "color": null, "opacity": null },
   "price_color": { "color": null, "opacity": null },
   "card_border_color": { "color": null, "opacity": null },
   "card_background_color": { "color": null, "opacity": null },
   "button_background_color": { "color": null, "opacity": null },
   "button_text_color": { "color": null, "opacity": null }
  },
  "display_width": null,
  "expanded": false,
  "group_occurrence_meta": null,
  "id": "f0838e20-1194-3a8b-bcbc-266f097f8276",
  "label": "style_group",
  "locked": false,
  "name": "style_group",
  "required": false,
  "tab": "CONTENT",
  "type": "group"
 },
 {
  "display": "text",
  "display_width": null,
  "id": "91126f3c-411d-92e9-440e-53f662bda0ad",
  "label": "products_limit",
  "locked": false,
  "name": "products_limit",
  "required": false,
  "step": 1,
  "type": "number"
 },
 {
  "children": [
   {
    "default": false,
    "display": "checkbox",
    "display_width": null,
    "id": "8b0f7adc-48da-ac5f-63db-a2ad6962ac32",
    "label": "show_pagination",
    "locked": false,
    "name": "show_pagination",
    "required": false,
    "type": "boolean"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "49e2b49e-26ce-e5e0-c20e-0247d4deb39b",
    "label": "items_per_page",
    "locked": false,
    "name": "items_per_page",
    "required": false,
    "step": 1,
    "type": "number"
   }
  ],
  "default": { "show_pagination": false },
  "display_width": null,
  "expanded": false,
  "group_occurrence_meta": null,
  "id": "cf3fe3d9-26f9-e23e-7f5c-c43df4bc70e4",
  "label": "pagination_group",
  "locked": false,
  "name": "pagination_group",
  "required": false,
  "tab": "CONTENT",
  "type": "group"
 }
]

Source Code

HTML
{# ==========================================
   動的スタイル
   ========================================== #}
<style>
  #product-listing-{{ name }} .product-card {
    {% if module.style_group.card_background_color.color %}
      background-color: {{ module.style_group.card_background_color.color }};
    {% endif %}
    {% if module.style_group.card_border_width %}
      border-width: {{ module.style_group.card_border_width }}px;
    {% endif %}
    {% if module.style_group.card_border_color.color %}
      border-color: {{ module.style_group.card_border_color.color }};
    {% endif %}
    {% if module.style_group.card_min_width %}
      min-width: {{ module.style_group.card_min_width }}px;
    {% endif %}
    {% if module.style_group.card_min_height %}
      min-height: {{ module.style_group.card_min_height }}px;
    {% endif %}
    {% if module.style_group.card_max_width %}
      max-width: {{ module.style_group.card_max_width }}px;
    {% endif %}
  }
  
  #product-listing-{{ name }} .product-card__title {
    {% if module.style_group.title_font_size %}
      font-size: {{ module.style_group.title_font_size }}px;
    {% endif %}
    {% if module.style_group.title_color.color %}
      color: {{ module.style_group.title_color.color }};
    {% endif %}
  }
  
  #product-listing-{{ name }} .product-card__description {
    {% if module.style_group.description_font_size %}
      font-size: {{ module.style_group.description_font_size }}px;
    {% endif %}
    {% if module.style_group.description_color.color %}
      color: {{ module.style_group.description_color.color }};
    {% endif %}
  }
  
  #product-listing-{{ name }} .product-card__price-val,
  #product-listing-{{ name }} .product-card__price-unit,
  #product-listing-{{ name }} .product-card__shipping {
    {% if module.style_group.price_font_size %}
      font-size: {{ module.style_group.price_font_size }}px;
    {% endif %}
    {% if module.style_group.price_color.color %}
      color: {{ module.style_group.price_color.color }};
    {% endif %}
  }
  
  #product-listing-{{ name }} .product-card__button {
    {% if module.style_group.button_background_color.color %}
      background-color: {{ module.style_group.button_background_color.color }};
    {% endif %}
    {% if module.style_group.button_text_color.color %}
      color: {{ module.style_group.button_text_color.color }};
    {% endif %}
  }
  
  {% if module.display_group.layout_type == 'grid' and module.display_group.grid_columns %}
  #product-listing-{{ name }} .product-listing--grid .product-listing__container {
    grid-template-columns: repeat({{ module.display_group.grid_columns }}, 1fr);
  }
  {% endif %}
</style>

{# ==========================================
   Product Listing Module
   ========================================== #}
{% set per_page = module.products_limit|default(100) %}
{% set price_min = module.price_filter_group.price_min|default(0) %}
{% set price_max = module.price_filter_group.price_max|default(0) %}
{% set price_unit = module.price_filter_group.price_unit|default('円') %}
{% set layout = module.display_group.layout_type|default('grid') %}
{% set columns = module.display_group.grid_columns|default('3') %}

{% set title_prop = module.display_group.title_property.property|default('name') %}
{% set desc_prop = module.display_group.description_property.property|default('description') %}
{% set image_prop = module.display_group.image_property.property|default('hs_images') %}
{% set url_prop = module.display_group.button_url_property.property|default('hs_url') %}
{% set rating_prop = module.display_group.rating_property.property|default('rating') %}

{% set filter_prop_1 = module.product_filter_group.filter_property_1.property|default('') %}
{% set filter_val_1 = module.product_filter_group.filter_value_1|default('') %}
{% set filter_prop_2 = module.product_filter_group.filter_property_2.property|default('') %}
{% set filter_val_2 = module.product_filter_group.filter_value_2|default('') %}
{% set filter_op = module.product_filter_group.filter_operator|default('AND') %}

{% set props_str = "name,price,description,hs_images,hs_sku,hs_url" %}
{% if title_prop and title_prop != 'name' %}{% set props_str = props_str ~ "," ~ title_prop %}{% endif %}
{% if desc_prop and desc_prop != 'description' %}{% set props_str = props_str ~ "," ~ desc_prop %}{% endif %}
{% if image_prop and image_prop != 'hs_images' %}{% set props_str = props_str ~ "," ~ image_prop %}{% endif %}
{% if url_prop and url_prop != 'hs_url' %}{% set props_str = props_str ~ "," ~ url_prop %}{% endif %}
{% if rating_prop %}{% set props_str = props_str ~ "," ~ rating_prop %}{% endif %}
{% if filter_prop_1 %}{% set props_str = props_str ~ "," ~ filter_prop_1 %}{% endif %}
{% if filter_prop_2 %}{% set props_str = props_str ~ "," ~ filter_prop_2 %}{% endif %}

{% set query = "limit=" ~ per_page %}
{% set products = crm_objects("product", query, props_str) %}

{% if products.results and products.results|length > 0 %}
<div class="product-listing-wrapper" id="product-listing-{{ name }}">
  <div class="product-listing product-listing--{{ layout }}" 
       data-layout="{{ layout }}" 
       data-columns="{{ columns }}"
       data-per-page="{{ module.pagination_group.items_per_page|default(12) }}">
    
    <div class="product-listing__container">
      {% for product in products.results %}
        {% set raw_price = product.price|default('0') %}
        {% set no_comma = raw_price|split(',')|join('') %}
        {% set clean_price = no_comma|split('¥')|join('')|split('¥')|join('')|split('$')|join('') %}
        {% set product_price = clean_price|int %}
        
        {% set passes_price = true %}
        {% if price_min and product_price < price_min|int %}{% set passes_price = false %}{% endif %}
        {% if price_max and product_price > price_max|int %}{% set passes_price = false %}{% endif %}

        {% set passes_filter_1 = true %}{% set passes_filter_2 = true %}
        {% if filter_prop_1 and filter_val_1 and product[filter_prop_1]|string != filter_val_1|string %}{% set passes_filter_1 = false %}{% endif %}
        {% if filter_prop_2 and filter_val_2 and product[filter_prop_2]|string != filter_val_2|string %}{% set passes_filter_2 = false %}{% endif %}

        {% set passes_props = true %}
        {% if filter_prop_1 and filter_val_1 and filter_prop_2 and filter_val_2 %}
          {% if filter_op == "AND" %}
            {% if not passes_filter_1 or not passes_filter_2 %}{% set passes_props = false %}{% endif %}
          {% else %}
            {% if not passes_filter_1 and not passes_filter_2 %}{% set passes_props = false %}{% endif %}
          {% endif %}
        {% elif filter_prop_1 %}{% set passes_props = passes_filter_1 %}
        {% elif filter_prop_2 %}{% set passes_props = passes_filter_2 %}
        {% endif %}

        {% if passes_price and passes_props %}
          <div class="product-card" data-product-item>
            {% set image_size = module.display_group.image_size|default('1:1') %}
            {% set image_height = module.display_group.image_height|default(200) %}

            {% if module.display_group.show_image %}
              <div class="product-card__image product-card__image--{{ image_size|split(':')|join('-') }}"
                   {% if image_size == 'custom' %}style="height: {{ image_height }}px;"{% endif %}>
                {% set img_url = product[image_prop]|default('') %}
                {% if img_url %}<img src="{{ img_url }}" alt="{{ product[title_prop]|default('製品') }}" loading="lazy">
                {% else %}<div class="product-card__no-image">No Image</div>{% endif %}
              </div>
            {% endif %}

            <div class="product-card__content">
              {% if module.display_group.show_title %}<h3 class="product-card__title">{{ product[title_prop]|default(product.name)|default('製品名なし') }}</h3>{% endif %}
              {% if module.display_group.show_description %}
                {% set desc_text = product[desc_prop]|default(product.description)|default('') %}
                {% if desc_text %}<p class="product-card__description">{{ desc_text|truncate(100) }}</p>{% endif %}
              {% endif %}
              
              {% if module.display_group.show_rating %}
                {% set rating = product[rating_prop]|default(0)|float %}
                {% if rating > 0 %}
                  <div class="product-card__rating">
                    <span class="product-card__stars" style="--rating: {{ rating }};"></span>
                    <span class="product-card__rating-value">{{ rating }}</span>
                  </div>
                {% endif %}
              {% endif %}

              {% if module.display_group.show_price %}
                <div class="product-card__price">
                  <span class="product-card__price-val">{{ product_price|format_number }}</span>
                  <span class="product-card__price-unit">{{ price_unit }}</span>
                </div>
              {% endif %}

              {% if module.display_group.show_button %}
                {% set btn_url = product[url_prop]|default('#') %}
                <div class="product-card__footer">
                  <a href="{{ btn_url }}" class="product-card__button">{{ module.display_group.button_text|default('詳細を見る') }}</a>
                </div>
              {% endif %}
            </div>
          </div>
        {% endif %}
      {% endfor %}
    </div>
  </div>

  {% if module.pagination_group.show_pagination %}
    <nav class="product-pagination" id="product-pagination-{{ name }}" aria-label="製品一覧のページネーション">
      <ul class="product-pagination__list"></ul>
    </nav>
  {% endif %}
</div>
{% endif %}
CSS
.product-listing-wrapper { width: 100%; }
.product-listing { width: 100%; padding: 20px 0; box-sizing: border-box; }
.product-listing__container { display: flex; flex-wrap: wrap; gap: 20px; width: 100%; }

/* Layouts */
.product-listing--grid .product-listing__container {
  display: grid;
  grid-template-columns: repeat({{ module.display_group.grid_columns|default(3) }}, 1fr);
  gap: 20px;
}
.product-listing--list .product-card { display: flex; flex-direction: row; align-items: flex-start; }
.product-listing--list .product-card__image { flex: 0 0 200px; max-width: 200px; }
.product-listing--list .product-card__content { flex: 1; padding: 0 0 0 20px; }

/* Product Card */
.product-card {
  background-color: {{ module.style_group.card_background_color.color|default('#ffffff') }};
  border: {{ module.style_group.card_border_width|default(1) }}px solid {{ module.style_group.card_border_color.color|default('#e0e0e0') }};
  border-radius: 8px;
  overflow: hidden;
  transition: transform 0.2s ease;
  display: flex;
  flex-direction: column;
  height: 100%;
}
.product-card:hover { transform: translateY(-2px); box-shadow: 0 8px 16px rgba(0,0,0,0.1); }

/* Card Components */
.product-card__image { width: 100%; background-color: #f5f5f5; position: relative; overflow: hidden; aspect-ratio: 1/1; }
.product-card__image--4-3 { aspect-ratio: 4/3; }
.product-card__image--16-9 { aspect-ratio: 16/9; }
.product-card__image img { width: 100%; height: 100%; object-fit: cover; }
.product-card__content { padding: 16px; flex-grow: 1; display: flex; flex-direction: column; }
.product-card__title { font-size: {{ module.style_group.title_font_size|default(16) }}px; color: {{ module.style_group.title_color.color|default('#333333') }}; font-weight: bold; margin-bottom: 8px; }
.product-card__price-val { font-size: {{ module.style_group.price_font_size|default(20) }}px; color: {{ module.style_group.price_color.color|default('#e60012') }}; font-weight: bold; }

/* Button */
.product-card__button {
  display: block; width: 100%; padding: 10px 16px; text-align: center; border-radius: 4px;
  background-color: {{ module.style_group.button_background_color.color|default('#007a87') }};
  color: {{ module.style_group.button_text_color.color|default('#ffffff') }};
  text-decoration: none; font-weight: bold;
}

/* Pagination */
.product-pagination__list { display: flex; justify-content: center; gap: 8px; list-style: none; margin-top: 40px; }
.product-pagination__link { padding: 8px 12px; border: 1px solid #e0e0e0; text-decoration: none; color: #333; border-radius: 4px; }
.product-pagination__link--current { background: #007a87; color: #fff; border-color: #007a87; }

/* Responsive */
@media (max-width: 992px) { .product-listing--grid .product-listing__container { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 576px) { 
  .product-listing--grid .product-listing__container { grid-template-columns: 1fr; }
  .product-listing--list .product-card { flex-direction: column; }
}
Javascript

FAQ

Search

Search more

Related Template

Need Customization?

We can customize this sample to match your specific business requirements.

Book Free Consultation

Got a quick dev request?

Put it on Trello!Need a fix for HubSpot, CMS, or GAS? Post it on Trello.

Development Requests Here

HubSpot CMS: Implementing the Data Type Conversion Action

HubSpot CMS: Implementing a Professional "Pricing Table Module"

HubSpot CMS: Implementing the "Login Check & Redirect Module" for Secure Page Access

HubSpot CMS: Implementing the "Carousel Card Module" for Smart Content Organization

HubSpot CMS: Implementation Guide for Video Hero Banners (Video Above-the-Fold)

Company Info
Name : SweetsVillage .Inc
CEO :
‍
Tomoo Motoyama

HomeTemplateCustomWorkflow
Terms & ConditionsPrivacy PolicyContact us

Copyright ©SweetsVillage .Inc

Back To Top Image