Skip to content

Instantly share code, notes, and snippets.

@ExileofAranei
Created March 26, 2021 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ExileofAranei/053748f7005a8feaa1497073e99a7b9e to your computer and use it in GitHub Desktop.
Save ExileofAranei/053748f7005a8feaa1497073e99a7b9e to your computer and use it in GitHub Desktop.
MODx snippet for fast creating tabs
<?php
$tplOuter = $modx->getOption('tplOuter', $scriptProperties);
if (!$tplOuter) { return 'Error: \'tplOuter\' is not provided.'; }
$tabs = $modx->getOption('tabs', $scriptProperties);
$tplTab = $modx->getOption('tplTab', $scriptProperties);
if (!$tplTab) { return 'Error: \'tplTab\' is not provided.'; }
$tplContent = $modx->getOption('tplContent', $scriptProperties);
if (!$tplContent) { return 'Error: \'tplContent\' is not provided.'; }
$prefix = $modx->getOption('prefix', $scriptProperties);
if (!$pdo = $modx->getService('pdoTools')) { return 'Couldn\'t load pdoTools!'; }
$tabTpls = '';
$tabContents = '';
$idx = 0;
$active = false;
foreach ($tabs as $key => $tab) {
if ($tab['active']) {
$active = $key;
break;
}
}
foreach ($tabs as $key => $tab) {
if ((empty($tab['title']) && empty($tab['tplTab'])) || (empty($tab['content']) && empty($tab['tplContent'])) || !empty($tab['skip'])) {
if ($key == $active) {
$active = false;
}
continue;
}
if (!$active) { $active = $key; }
$tabTpls .= $pdo->getChunk($tplTab, [
'key' => $key,
'title' => $tab['tplTab'] ? $pdo->getChunk($tab['tplTab']) : $tab['title'] ?: '',
'active' => $key == $active,
'prefix' => $prefix,
'idx' => $idx,
]);
$tabContents .= $pdo->getChunk($tplContent, [
'key' => $key,
'content' => $tab['tplContent'] ? $pdo->getChunk($tab['tplContent']) : $tab['content'] ?: '',
'active' => $key == $active,
'prefix' => $prefix,
'idx' => $idx,
]);
$idx += 1;
}
$output = $pdo->getChunk($tplOuter, [
'tabs' => $tabTpls,
'content' => $tabContents,
]);
if (!$output) { return 'Failed to parse \'tplOuter\' chunk!'; }
return $output;
@R2m0x94
Copy link

R2m0x94 commented Dec 13, 2021

PHP warning: Illegal string offset 'key'
PHP warning: Illegal string offset 'active'

+tabs on tplOuter not readings cose what array use on getOption &tabs?

[[!tabs? &tplOuter=`tplOuter` &tplTab=`tplTab` &tplContent=`tplContent` &tabs=`` &prefix=``]]

tplOuter:

<div class="items">
    <ul id="items-tabs" role="tablist">
        [[+tabs]]
        <li class="add-item">
            <a href="#addTab" id="add" aria-disabled="true">Add</a>
        </li>
    </ul>
    <div id="items-content">
        [[+content]]
    </div>
</div>

i have prepare item:

<li id="item-1" class="item">
    <span>Item 1</span>
</li>

and i have prepare content:

<div class="content" id="item-content-1">
    <p>Content Item 1</p>
</div>

@ExileofAranei
Copy link
Author

I am using fenom parser provided by pdoTools package, so I am not sure that this code could work with default MODx parser.
Honestly I used this only once with bootstrap 4 tabs. Code is working, but isn't tested well. I wrote this to prevent hardcode active tab because my website has different tabs depends on resource displayed, so active tab is sometimes differs.
Each entry of multidimensional array with key tabs has id => config structure. content means inline string. If tplContent is provided, fenom will try to parse chunk by it's name and pass result to tabs_content.
Example how I used it:

{'createTabsLayout' | snippet : [
  'tplOuter' => 'product_tabs_outer',
  'tplTab' => 'tabs_tab',
  'tplContent' => 'tabs_content',
  'prefix' => 'product',
  'tabs' => [
    'paymentAndDelivery' => [
      'title' => 'Example tab 1',
      'tplContent' => 'product_tab_delivery_and_payment',
    ],
    'warranty' => [
      'title' => 'Example tab 2',
      'content' => 'test2',
    ],
    'reviews' => [
      'title' => 'Example tab 3',
      'tplContent' => 'product_tab_reviews',
    ],
    'clock' => [
      'title' => 'Example tab 4',
      'content' => 'test4',
    ],
    'custom' => [
      'title' => 'Не нашли свой размер?',
      'tplContent' => 'product_tab_custom_size',
    ],
  ],
]}

product_tabs_outer chunk:

// product_tabs_outer
<div class="product-tabs__tabs">
	<div class="tab-controls" data-tabs-slider="init">
		<div class="tab-controls__slider js-tabs-slider is-hidden"></div>
		<ul class="tab-controls__list" id="productTabs" role="tablist" data-instance="tabs">
			{$tabs}
		</ul>
	</div>
</div>
<div class="product-tabs__content">
	<div class="tab-content" id="productTabsContent">
		{$content}
	</div>
</div>

tab_tpl chunk:

<li class="tab-controls__item">
	<a class="tab-controls__link{if $active} active is-start{/if}" id="tab_{$prefix}_{$key}_trigger" rel="nofollow noopener noreferrer" data-toggle="tab" href="#tab_{$prefix}_{$key}" role="tab" aria-controls="tab_{$prefix}_{$key}" aria-selected="{$active ? 'true' : 'false'}" data-tab-scroll="mobile">{$title}</a>
</li>

tabs_content chunk

<div class="tab-content__item fade{if $active} active show{/if}" id="tab_{$prefix}_{$key}" role="tabpanel" aria-labelledby="tab_{$prefix}_{$key}_trigger">
  {if !$custom}
	<div class="content">
	  {$content}
	</div>
  {else}
  {$content}
  {/if}
</div>

Idk if this would help you, but I tried x)

@R2m0x94
Copy link

R2m0x94 commented Dec 13, 2021

Ou thanks! Its very helpful me a lot in solving this issue.

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