feat(main): Introduce USP block type and custom classes for HTML groups
This release adds a new "USP" (Unique Selling Proposition) block type, allowing for flexible display of image-based selling points with optional links. Additionally, administrators can now assign custom CSS classes to Custom HTML Groups, enhancing layout and styling capabilities. Includes a refinement to the FAQ accordion template to ensure questions without answers do not display a collapse button, improving usability. Updates module version to 1.13.0 with a database upgrade script for the new `custom_class` column.
This commit is contained in:
@@ -15,6 +15,7 @@ class Config
|
|||||||
'faq' => 'FAQ Accordion',
|
'faq' => 'FAQ Accordion',
|
||||||
'banner' => 'Banner',
|
'banner' => 'Banner',
|
||||||
'alert' => 'Alert',
|
'alert' => 'Alert',
|
||||||
|
'usp' => 'USP',
|
||||||
];
|
];
|
||||||
|
|
||||||
const ALERT_STYLES = [
|
const ALERT_STYLES = [
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ final class CustomHtmlGroupDataHandler implements FormDataHandlerInterface
|
|||||||
public function create(array $formData)
|
public function create(array $formData)
|
||||||
{
|
{
|
||||||
$group = new CustomHtmlGroup();
|
$group = new CustomHtmlGroup();
|
||||||
$group->title = (string) $formData['title'];
|
$group->title = (string) $formData['title'];
|
||||||
$group->hook_name = (string) $formData['hook_name'];
|
$group->hook_name = (string) $formData['hook_name'];
|
||||||
$group->active = (int) $formData['active'];
|
$group->custom_class = (string) ($formData['custom_class'] ?? '');
|
||||||
$group->ordering = $this->getNextOrdering();
|
$group->active = (int) $formData['active'];
|
||||||
|
$group->ordering = $this->getNextOrdering();
|
||||||
|
|
||||||
if (!$group->add()) {
|
if (!$group->add()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -46,9 +47,10 @@ final class CustomHtmlGroupDataHandler implements FormDataHandlerInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$group->title = (string) $formData['title'];
|
$group->title = (string) $formData['title'];
|
||||||
$group->hook_name = (string) $formData['hook_name'];
|
$group->hook_name = (string) $formData['hook_name'];
|
||||||
$group->active = (int) $formData['active'];
|
$group->custom_class = (string) ($formData['custom_class'] ?? '');
|
||||||
|
$group->active = (int) $formData['active'];
|
||||||
|
|
||||||
if (!$group->update()) {
|
if (!$group->update()) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -17,18 +17,20 @@ final class CustomHtmlGroupDataProvider implements FormDataProviderInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'title' => $group->title,
|
'title' => $group->title,
|
||||||
'hook_name' => $group->hook_name,
|
'hook_name' => $group->hook_name,
|
||||||
'active' => (bool) $group->active,
|
'custom_class' => $group->custom_class,
|
||||||
|
'active' => (bool) $group->active,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultData()
|
public function getDefaultData()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'title' => '',
|
'title' => '',
|
||||||
'hook_name' => '',
|
'hook_name' => '',
|
||||||
'active' => true,
|
'custom_class' => '',
|
||||||
|
'active' => true,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ class CustomHtmlBlockType extends AbstractType
|
|||||||
'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-html'],
|
'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-html'],
|
||||||
])
|
])
|
||||||
->add('image', FileType::class, [
|
->add('image', FileType::class, [
|
||||||
'label' => $this->translator->trans('Banner image', [], 'Modules.Wscustomhtml.Admin'),
|
'label' => $this->translator->trans('Image', [], 'Modules.Wscustomhtml.Admin'),
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-banner'],
|
'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-banner customhtmlblock-type-usp'],
|
||||||
])
|
])
|
||||||
->add('faqs', CollectionType::class, [
|
->add('faqs', CollectionType::class, [
|
||||||
'entry_type' => CustomHtmlFaqType::class,
|
'entry_type' => CustomHtmlFaqType::class,
|
||||||
@@ -97,7 +97,7 @@ class CustomHtmlBlockType extends AbstractType
|
|||||||
'label' => $this->translator->trans('Link', [], 'Modules.Wscustomhtml.Admin'),
|
'label' => $this->translator->trans('Link', [], 'Modules.Wscustomhtml.Admin'),
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'attr' => ['placeholder' => 'https://example.com or /internal-page'],
|
'attr' => ['placeholder' => 'https://example.com or /internal-page'],
|
||||||
'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-banner'],
|
'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-banner customhtmlblock-type-usp'],
|
||||||
])
|
])
|
||||||
->add('custom_class', TextType::class, [
|
->add('custom_class', TextType::class, [
|
||||||
'label' => $this->translator->trans('Custom classes', [], 'Modules.Wscustomhtml.Admin'),
|
'label' => $this->translator->trans('Custom classes', [], 'Modules.Wscustomhtml.Admin'),
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ class CustomHtmlGroupType extends AbstractType
|
|||||||
'label' => $this->translator->trans('Hook name', [], 'Modules.Wscustomhtml.Admin'),
|
'label' => $this->translator->trans('Hook name', [], 'Modules.Wscustomhtml.Admin'),
|
||||||
'required' => true,
|
'required' => true,
|
||||||
])
|
])
|
||||||
|
->add('custom_class', TextType::class, [
|
||||||
|
'label' => $this->translator->trans('Custom classes', [], 'Modules.Wscustomhtml.Admin'),
|
||||||
|
'required' => false,
|
||||||
|
'attr' => ['placeholder' => 'col-md-6'],
|
||||||
|
])
|
||||||
->add('active', SwitchType::class, [
|
->add('active', SwitchType::class, [
|
||||||
'label' => $this->translator->trans('Active', [], 'Modules.Wscustomhtml.Admin'),
|
'label' => $this->translator->trans('Active', [], 'Modules.Wscustomhtml.Admin'),
|
||||||
'required' => false,
|
'required' => false,
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ final class CustomHtmlGroupGridDefinitionFactory extends AbstractGridDefinitionF
|
|||||||
->setName($this->trans('Hook', [], 'Modules.Wscustomhtml.Admin'))
|
->setName($this->trans('Hook', [], 'Modules.Wscustomhtml.Admin'))
|
||||||
->setOptions(['field' => 'hook_name'])
|
->setOptions(['field' => 'hook_name'])
|
||||||
)
|
)
|
||||||
|
->add(
|
||||||
|
(new DataColumn('custom_class'))
|
||||||
|
->setName($this->trans('Custom classes', [], 'Modules.Wscustomhtml.Admin'))
|
||||||
|
->setOptions(['field' => 'custom_class'])
|
||||||
|
)
|
||||||
->add(
|
->add(
|
||||||
(new DataColumn('blocks_count'))
|
(new DataColumn('blocks_count'))
|
||||||
->setName($this->trans('Blocks', [], 'Modules.Wscustomhtml.Admin'))
|
->setName($this->trans('Blocks', [], 'Modules.Wscustomhtml.Admin'))
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ final class CustomHtmlGroupQueryBuilder extends AbstractDoctrineQueryBuilder
|
|||||||
'wchg.`id_ws_customhtml_group`',
|
'wchg.`id_ws_customhtml_group`',
|
||||||
'wchg.`title`',
|
'wchg.`title`',
|
||||||
'wchg.`hook_name`',
|
'wchg.`hook_name`',
|
||||||
|
'wchg.`custom_class`',
|
||||||
'wchg.`active`',
|
'wchg.`active`',
|
||||||
'wchg.`ordering`',
|
'wchg.`ordering`',
|
||||||
'wchg.`date_add`',
|
'wchg.`date_add`',
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ class CustomHtmlGroup extends ObjectModel
|
|||||||
/** @var string */
|
/** @var string */
|
||||||
public $title = '';
|
public $title = '';
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
public $custom_class = '';
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
public $active = 1;
|
public $active = 1;
|
||||||
|
|
||||||
@@ -34,6 +37,7 @@ class CustomHtmlGroup extends ObjectModel
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'hook_name' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 64],
|
'hook_name' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 64],
|
||||||
'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 256],
|
'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 256],
|
||||||
|
'custom_class' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 128],
|
||||||
'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
|
'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
|
||||||
'ordering' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
|
'ordering' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
|
||||||
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
|
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
|
||||||
@@ -44,7 +48,7 @@ class CustomHtmlGroup extends ObjectModel
|
|||||||
public static function getActiveByHookName(string $hookName): array
|
public static function getActiveByHookName(string $hookName): array
|
||||||
{
|
{
|
||||||
$result = Db::getInstance()->executeS(
|
$result = Db::getInstance()->executeS(
|
||||||
'SELECT `id_ws_customhtml_group`, `title`, `active`, `ordering`
|
'SELECT `id_ws_customhtml_group`, `title`, `active`, `custom_class`, `ordering`
|
||||||
FROM `' . _DB_PREFIX_ . 'ws_customhtml_group`
|
FROM `' . _DB_PREFIX_ . 'ws_customhtml_group`
|
||||||
WHERE `hook_name` = \'' . pSQL($hookName) . '\'
|
WHERE `hook_name` = \'' . pSQL($hookName) . '\'
|
||||||
AND `active` = 1
|
AND `active` = 1
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ trait DisplayHooks
|
|||||||
|
|
||||||
$blocksByGroup = CustomHtmlBlock::getActiveByGroupIds(array_column($groups, 'id_ws_customhtml_group'));
|
$blocksByGroup = CustomHtmlBlock::getActiveByGroupIds(array_column($groups, 'id_ws_customhtml_group'));
|
||||||
$blocksByGroup = $this->attachFaqsToBlocks($blocksByGroup);
|
$blocksByGroup = $this->attachFaqsToBlocks($blocksByGroup);
|
||||||
$blocksByGroup = $this->attachBannerImageUrls($blocksByGroup);
|
$blocksByGroup = $this->attachImageUrls($blocksByGroup);
|
||||||
|
|
||||||
$groups = array_map(static function (array $group) use ($blocksByGroup) {
|
$groups = array_map(static function (array $group) use ($blocksByGroup) {
|
||||||
$group['blocks'] = $blocksByGroup[(int) $group['id_ws_customhtml_group']] ?? [];
|
$group['blocks'] = $blocksByGroup[(int) $group['id_ws_customhtml_group']] ?? [];
|
||||||
@@ -95,11 +95,11 @@ trait DisplayHooks
|
|||||||
}, $blocksByGroup);
|
}, $blocksByGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function attachBannerImageUrls(array $blocksByGroup): array
|
private function attachImageUrls(array $blocksByGroup): array
|
||||||
{
|
{
|
||||||
return array_map(static function (array $blocks) {
|
return array_map(static function (array $blocks) {
|
||||||
return array_map(static function (array $block) {
|
return array_map(static function (array $block) {
|
||||||
if ($block['type'] === 'banner') {
|
if (in_array($block['type'], ['banner', 'usp'], true)) {
|
||||||
$block['image_url'] = CustomHtmlBlock::getBannerImageUrl($block['image']);
|
$block['image_url'] = CustomHtmlBlock::getBannerImageUrl($block['image']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ trait Install
|
|||||||
`id_ws_customhtml_group` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
`id_ws_customhtml_group` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
`hook_name` VARCHAR(64) NOT NULL,
|
`hook_name` VARCHAR(64) NOT NULL,
|
||||||
`title` VARCHAR(256) NOT NULL DEFAULT \'\',
|
`title` VARCHAR(256) NOT NULL DEFAULT \'\',
|
||||||
|
`custom_class` VARCHAR(128) NOT NULL DEFAULT \'\',
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT 1,
|
`active` TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
`ordering` INT(11) NOT NULL DEFAULT 0,
|
`ordering` INT(11) NOT NULL DEFAULT 0,
|
||||||
`date_add` DATETIME NOT NULL,
|
`date_add` DATETIME NOT NULL,
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (!defined('_PS_VERSION_')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function upgrade_module_1_13_0($module)
|
||||||
|
{
|
||||||
|
$existing = Db::getInstance()->executeS(
|
||||||
|
'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml_group` LIKE \'custom_class\''
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!empty($existing)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Db::getInstance()->execute(
|
||||||
|
'ALTER TABLE `' . _DB_PREFIX_ . 'ws_customhtml_group`
|
||||||
|
ADD COLUMN `custom_class` VARCHAR(128) NOT NULL DEFAULT \'\' AFTER `title`'
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -48,6 +48,21 @@
|
|||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.customhtml-usp {
|
||||||
|
gap: 0.5rem;
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customhtml-usp-icon img {
|
||||||
|
max-height: 32px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customhtml-usp-text {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
/* FAQ */
|
/* FAQ */
|
||||||
.accordion-icon-minus {
|
.accordion-icon-minus {
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
{{ form_row(customHtmlBlockForm.content) }}
|
{{ form_row(customHtmlBlockForm.content) }}
|
||||||
|
|
||||||
{% if currentImageUrl is defined and currentImageUrl %}
|
{% if currentImageUrl is defined and currentImageUrl %}
|
||||||
<div class="customhtmlblock-type-field customhtmlblock-type-banner customhtmlblock-current-image">
|
<div class="customhtmlblock-type-field customhtmlblock-type-banner customhtmlblock-type-usp customhtmlblock-current-image">
|
||||||
<label class="form-control-label">{{ 'Current image'|trans({}, 'Modules.Wscustomhtml.Admin') }}</label>
|
<label class="form-control-label">{{ 'Current image'|trans({}, 'Modules.Wscustomhtml.Admin') }}</label>
|
||||||
<div><img src="{{ currentImageUrl }}" alt="" style="max-width: 200px; max-height: 200px;"></div>
|
<div><img src="{{ currentImageUrl }}" alt="" style="max-width: 200px; max-height: 200px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
$('.customhtmlblock-type-faq').hide();
|
$('.customhtmlblock-type-faq').hide();
|
||||||
$('.customhtmlblock-type-banner').hide();
|
$('.customhtmlblock-type-banner').hide();
|
||||||
$('.customhtmlblock-type-alert').hide();
|
$('.customhtmlblock-type-alert').hide();
|
||||||
|
$('.customhtmlblock-type-usp').hide();
|
||||||
$('.customhtmlblock-type-' + type).show();
|
$('.customhtmlblock-type-' + type).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
$('.customhtmlblock-type-faq').hide();
|
$('.customhtmlblock-type-faq').hide();
|
||||||
$('.customhtmlblock-type-banner').hide();
|
$('.customhtmlblock-type-banner').hide();
|
||||||
$('.customhtmlblock-type-alert').hide();
|
$('.customhtmlblock-type-alert').hide();
|
||||||
|
$('.customhtmlblock-type-usp').hide();
|
||||||
$('.customhtmlblock-type-' + type).show();
|
$('.customhtmlblock-type-' + type).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,57 @@
|
|||||||
{if !empty($block.faqs)}
|
{if !empty($block.faqs)}
|
||||||
<div class="accordion customhtml-faq-accordion" id="customhtml-faq-{$block.id_ws_customhtml|intval}">
|
<div class="accordion customhtml-faq-accordion" id="customhtml-faq-{$block.id_ws_customhtml|intval}">
|
||||||
{foreach from=$block.faqs item="faq" name="customhtmlFaqLoop"}
|
{foreach from=$block.faqs item="faq" name="customhtmlFaqLoop"}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header" id="customhtml-faq-heading-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}">
|
<div class="card-header" id="customhtml-faq-heading-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}">
|
||||||
<button
|
|
||||||
class="btn btn-link col-12 d-flex text-left {if !$smarty.foreach.customhtmlFaqLoop.first} collapsed{/if}"
|
{if !empty($faq.answer)}
|
||||||
type="button"
|
<button
|
||||||
data-toggle="collapse"
|
class="btn btn-link col-12 d-flex text-left{if !$smarty.foreach.customhtmlFaqLoop.first} collapsed{/if}"
|
||||||
data-target="#customhtml-faq-collapse-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}"
|
type="button"
|
||||||
aria-expanded="{if $smarty.foreach.customhtmlFaqLoop.first}true{else}false{/if}"
|
data-toggle="collapse"
|
||||||
aria-controls="customhtml-faq-collapse-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}"
|
data-target="#customhtml-faq-collapse-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}"
|
||||||
>
|
aria-expanded="{if $smarty.foreach.customhtmlFaqLoop.first}true{else}false{/if}"
|
||||||
<div class="col">
|
aria-controls="customhtml-faq-collapse-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}"
|
||||||
{$faq.question|escape:'html':'UTF-8'}
|
>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="faq-question col pl-0">
|
||||||
|
{$faq.question|escape:'html':'UTF-8'}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{if !empty($faq.answer)}
|
||||||
|
<div class="col-auto d-flex align-items-center">
|
||||||
|
<span class="accordion-icons accordion-icon-minus">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="2" viewBox="0 0 28 2">
|
||||||
|
<line id="Line_18" data-name="Line 18" x2="26" transform="translate(1 1)" fill="none" stroke="#272727" stroke-linecap="round" stroke-width="2"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span class="accordion-icons accordion-icon-plus">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28">
|
||||||
|
<g id="Group_31" data-name="Group 31" transform="translate(-1615 -4031.5)">
|
||||||
|
<line id="Line_21" data-name="Line 21" x2="26" transform="translate(1616 4045.5)" fill="none" stroke="#272727" stroke-linecap="round" stroke-width="2"/>
|
||||||
|
<line id="Line_22" data-name="Line 22" x2="26" transform="translate(1629 4032.5) rotate(90)" fill="none" stroke="#272727" stroke-linecap="round" stroke-width="2"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-auto d-flex align-items-center ">
|
|
||||||
<span class="accordion-icons accordion-icon-minus">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="2" viewBox="0 0 28 2">
|
|
||||||
<line id="Line_18" data-name="Line 18" x2="26" transform="translate(1 1)" fill="none" stroke="#272727" stroke-linecap="round" stroke-width="2"/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
<span class="accordion-icons accordion-icon-plus">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28">
|
|
||||||
<g id="Group_31" data-name="Group 31" transform="translate(-1615 -4031.5)">
|
|
||||||
<line id="Line_21" data-name="Line 21" x2="26" transform="translate(1616 4045.5)" fill="none" stroke="#272727" stroke-linecap="round" stroke-width="2"/>
|
|
||||||
<line id="Line_22" data-name="Line 22" x2="26" transform="translate(1629 4032.5) rotate(90)" fill="none" stroke="#272727" stroke-linecap="round" stroke-width="2"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
{if !empty($faq.answer)}
|
||||||
</div>
|
<div
|
||||||
<div
|
id="customhtml-faq-collapse-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}"
|
||||||
id="customhtml-faq-collapse-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}"
|
class="collapse{if $smarty.foreach.customhtmlFaqLoop.first} show{/if}"
|
||||||
class="collapse{if $smarty.foreach.customhtmlFaqLoop.first} show{/if}"
|
aria-labelledby="customhtml-faq-heading-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}"
|
||||||
aria-labelledby="customhtml-faq-heading-{$block.id_ws_customhtml|intval}-{$faq.id_ws_customhtml_faq|intval}"
|
data-parent="#customhtml-faq-{$block.id_ws_customhtml|intval}"
|
||||||
data-parent="#customhtml-faq-{$block.id_ws_customhtml|intval}"
|
>
|
||||||
>
|
<div class="card-body">
|
||||||
<div class="card-body">
|
{$faq.answer nofilter}
|
||||||
{$faq.answer nofilter}
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/foreach}
|
||||||
</div>
|
</div>
|
||||||
{/foreach}
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{if !empty($block.image_url) || ($block.show_title && !empty($block.title))}
|
||||||
|
{if !empty($block.link)}
|
||||||
|
<a href="{$block.link|escape:'html':'UTF-8'}" class="customhtml-usp d-flex align-items-center">
|
||||||
|
{else}
|
||||||
|
<div class="customhtml-usp d-flex align-items-center">
|
||||||
|
{/if}
|
||||||
|
{if !empty($block.image_url)}
|
||||||
|
<span class="customhtml-usp-icon">
|
||||||
|
<img src="{$block.image_url|escape:'html':'UTF-8'}" alt="">
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
{if $block.show_title && !empty($block.title)}
|
||||||
|
<span class="customhtml-usp-text">{$block.title|escape:'html':'UTF-8'}</span>
|
||||||
|
{/if}
|
||||||
|
{if !empty($block.link)}
|
||||||
|
</a>
|
||||||
|
{else}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{if !empty($groupList)}
|
{if !empty($groupList)}
|
||||||
<div class="customhtml-container {$hookName|escape:'html':'UTF-8'}--container">
|
<div class="customhtml-container {$hookName|escape:'html':'UTF-8'}--container">
|
||||||
{foreach from=$groupList item="group"}
|
{foreach from=$groupList item="group"}
|
||||||
<div class="customhtml-group customhtml-group-{$group.id_ws_customhtml_group|intval} row">
|
<div class="customhtml-group customhtml-group-{$group.id_ws_customhtml_group|intval} row{if !empty($group.custom_class)} {$group.custom_class|escape:'html':'UTF-8'}{/if}">
|
||||||
{foreach from=$group.blocks item="block"}
|
{foreach from=$group.blocks item="block"}
|
||||||
<div class="customhtml-block col{if !empty($block.custom_class)} {$block.custom_class|escape:'html':'UTF-8'}{/if}">
|
<div class="customhtml-block col{if !empty($block.custom_class)} {$block.custom_class|escape:'html':'UTF-8'}{/if}">
|
||||||
{assign var="customhtmlOverridePath" value="{$smarty.const._PS_THEME_DIR_}modules/ws_customhtml/views/templates/hook/{$hookName}/{$block.type}.tpl"}
|
{assign var="customhtmlOverridePath" value="{$smarty.const._PS_THEME_DIR_}modules/ws_customhtml/views/templates/hook/{$hookName}/{$block.type}.tpl"}
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
{include file="module:ws_customhtml/views/templates/hook/_banner.tpl" block=$block}
|
{include file="module:ws_customhtml/views/templates/hook/_banner.tpl" block=$block}
|
||||||
{elseif $block.type == 'alert'}
|
{elseif $block.type == 'alert'}
|
||||||
{include file="module:ws_customhtml/views/templates/hook/_alert.tpl" block=$block}
|
{include file="module:ws_customhtml/views/templates/hook/_alert.tpl" block=$block}
|
||||||
|
{elseif $block.type == 'usp'}
|
||||||
|
{include file="module:ws_customhtml/views/templates/hook/_usp.tpl" block=$block}
|
||||||
{else}
|
{else}
|
||||||
{if $block.show_title && !empty($block.title)}
|
{if $block.show_title && !empty($block.title)}
|
||||||
<div class="customhtml-title">{$block.title|escape:'html':'UTF-8'}</div>
|
<div class="customhtml-title">{$block.title|escape:'html':'UTF-8'}</div>
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ class Ws_CustomHtml extends Module implements WidgetInterface
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->name = 'ws_customhtml';
|
$this->name = 'ws_customhtml';
|
||||||
$this->version = '1.11.0';
|
$this->version = '1.13.0';
|
||||||
$this->author = 'Isabelle Oving-Anno | De Websmid BV';
|
$this->author = 'Isabelle Oving-Anno | De Websmid BV';
|
||||||
$this->need_instance = 0;
|
$this->need_instance = 0;
|
||||||
$this->bootstrap = true;
|
$this->bootstrap = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user