1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-12 09:44:38 +02:00

Fix issue with LanguageTabs module where it wasn't working when in non-default language with the recent Uikit version update.

This commit is contained in:
Ryan Cramer
2021-07-02 12:33:32 -04:00
parent 4167f17235
commit fb7406c3e6
5 changed files with 67 additions and 25 deletions

View File

@@ -23,6 +23,7 @@
* @property string $configPhpHash Hash used internally to detect changes to $config->AdminThemeUikit settings. * @property string $configPhpHash Hash used internally to detect changes to $config->AdminThemeUikit settings.
* @property int $cssVersion Current version number of core CSS/LESS files * @property int $cssVersion Current version number of core CSS/LESS files
* *
* @method string renderBreadcrumbs()
* @method string getUikitCSS() * @method string getUikitCSS()
* *
* *

View File

@@ -18,6 +18,7 @@
/** @var WireInput $input */ /** @var WireInput $input */
/** @var Paths $urls */ /** @var Paths $urls */
/** @var string $layout */ /** @var string $layout */
/** @var Process $process */
if(!defined("PROCESSWIRE")) die(); if(!defined("PROCESSWIRE")) die();

View File

@@ -87,8 +87,12 @@ function setupLanguageTabs($form) {
$openItem.addClass('LanguageSupportCurrent'); $openItem.addClass('LanguageSupportCurrent');
$a.trigger('clicklangtab', [ $openItem, $closeItem ]); $a.trigger('clicklangtab', [ $openItem, $closeItem ]);
} }
// uikit tab (beta 34+) also requires a click on the <li> element // uikit tab also requires the following
if($a.closest('ul.uk-tab').length) $a.closest('li').click(); var $ukTab = $a.closest('ul.uk-tab');
if($ukTab.length) {
$ukTab.find('.uk-active').removeClass('uk-active');
$a.closest('li').addClass('uk-active');
}
}); });
if(!cfg.jQueryUI) { if(!cfg.jQueryUI) {

View File

@@ -1 +1 @@
var clickLanguageTabActive=false;function dblclickLanguageTab(e){if(clickLanguageTabActive)return;clickLanguageTabActive=true;var $tab=$(this);var langID=$tab.attr("data-lang");var $tabs=$tab.closest("form").find("a.langTab"+langID).not($tab);$tab.click();$tabs.click();$tabs.effect("highlight",250);setTimeout(function(){clickLanguageTabActive=false},250)}function setupLanguageTabs($form){var $langTabs;var cfg=ProcessWire.config.LanguageTabs;if($form.hasClass("langTabs"))$langTabs=$form;else $langTabs=$form.find(".langTabs");$langTabs.each(function(){var $this=$(this);if($this.hasClass("langTabsInit")||$this.hasClass("ui-tabs"))return;var $inputfield=$this.closest(".Inputfield");var $content=$inputfield.children(".InputfieldContent");if(!$content.hasClass("langTabsContainer")){if($inputfield.find(".langTabsContainer").length==0)$content.addClass("langTabsContainer")}if(cfg.jQueryUI)$this.tabs({active:cfg.activeTab});$this.addClass("langTabsInit");if($inputfield.length)$inputfield.addClass("hasLangTabs");var $parent=$this.parent(".InputfieldContent");if($parent.length){var $span=$("<span></span>").attr("title",cfg.labelOpen).attr("class","langTabsToggle").append("<i class='fa fa-folder-o'></i>");$parent.prev(".InputfieldHeader").append($span)}var $links=$this.find("a.langTabLink");var timeout=null;var $note=$parent.find(".langTabsNote");if(!$links.length){$links=$this.find("a[data-lang]");if(!$links.length)$links=$this.find("a");$links.addClass("langTabLink")}$links.on("mouseover",function(){if(timeout)clearTimeout(timeout);if($parent.width()<500)return;timeout=setTimeout(function(){$note.fadeIn("fast")},250)}).on("mouseout",function(){if(timeout)clearTimeout(timeout);if($parent.width()<500)return;timeout=setTimeout(function(){$note.fadeOut("fast")},250)}).on("click",function(){var $a=$(this);var $items=$a.closest("ul").siblings(".LanguageSupport");var $closeItem=$items.filter(".LanguageSupportCurrent");var $openItem=$items.filter($a.attr("href"));if($closeItem.attr("id")==$openItem.attr("id")){$a.trigger("dblclicklangtab")}else{$closeItem.removeClass("LanguageSupportCurrent");$openItem.addClass("LanguageSupportCurrent");$a.trigger("clicklangtab",[$openItem,$closeItem])}if($a.closest("ul.uk-tab").length)$a.closest("li").click()});if(!cfg.jQueryUI){$links.eq(cfg.activeTab).click()}})}function toggleLanguageTabs(){var $this=$(this);var $header=$this.closest(".InputfieldHeader");var $content=$header.next(".InputfieldContent");var $inputfield=$header.parent(".Inputfield");var $langTabs=$content.children(".langTabs");var $ul=$langTabs.children("ul");var cfg=ProcessWire.config.LanguageTabs;clickLanguageTabActive=true;if($content.hasClass("langTabsContainer")){$ul.find(".langTabLastActive").removeClass("langTabLastActive");if(cfg.liActiveClass)$ul.find("."+cfg.liActiveClass).addClass("langTabLastActive");$ul.find("a").click();$content.removeClass("langTabsContainer");$inputfield.removeClass("hasLangTabs").addClass("langTabsOff");$this.addClass("langTabsOff");if(cfg.jQueryUI)$langTabs.tabs("destroy");$ul.hide();$this.attr("title",ProcessWire.config.LanguageTabs.labelClose).find("i").removeClass("fa-folder-o").addClass("fa-folder-open-o")}else{$content.addClass("langTabsContainer");$inputfield.addClass("hasLangTabs").removeClass("langTabsOff");$this.removeClass("langTabsOff");if(cfg.jQueryUI)$langTabs.tabs();$ul.show();$(this).attr("title",cfg.labelOpen).find("i").addClass("fa-folder-o").removeClass("fa-folder-open-o");$ul.find(".langTabLastActive").removeClass("langTabLastActive").children("a").click()}clickLanguageTabActive=false;return false}function hideLanguageTabs(){$(".InputfieldContent").each(function(){var n=0;$(this).children(".LanguageSupport").each(function(){if(++n==1){$(this).closest(".Inputfield").addClass("hadLanguageSupport");return}$(this).addClass("langTabsHidden")})});var $tab=$(".langTabs").find("li:eq(0)");var cfg=ProcessWire.config.LanguageTabs;if(cfg.liActiveClass&&!$tab.hasClass(cfg.liActiveClass))$tab.find("a").click();$(".langTabsToggle, .LanguageSupportLabel:visible, .langTabs > ul").addClass("langTabsHidden");$(".hasLangTabs").removeClass("hasLangTabs").addClass("hadLangTabs")}function unhideLanguageTabs(){$(".langTabsHidden").removeClass("langTabsHidden");$(".hadLangTabs").removeClass("hadLangTabs").addClass("hasLangTabs");$(".hadLanguageSupport").removeClass("hadLanguageSupport")}jQuery(document).ready(function($){$(document).on("click",".langTabsToggle",toggleLanguageTabs);$(document).on("dblclicklangtab","a.langTabLink",dblclickLanguageTab);$(document).on("reloaded",".Inputfield",function(){var $inputfield=$(this);setTimeout(function(){setupLanguageTabs($inputfield)},100)});$(document).on("AjaxUploadDone",".InputfieldHasFileList .InputfieldFileList",function(){setupLanguageTabs($(this))})}); var clickLanguageTabActive=false;function dblclickLanguageTab(e){if(clickLanguageTabActive)return;clickLanguageTabActive=true;var $tab=$(this);var langID=$tab.attr("data-lang");var $tabs=$tab.closest("form").find("a.langTab"+langID).not($tab);$tab.click();$tabs.click();$tabs.effect("highlight",250);setTimeout(function(){clickLanguageTabActive=false},250)}function setupLanguageTabs($form){var $langTabs;var cfg=ProcessWire.config.LanguageTabs;if($form.hasClass("langTabs"))$langTabs=$form;else $langTabs=$form.find(".langTabs");$langTabs.each(function(){var $this=$(this);if($this.hasClass("langTabsInit")||$this.hasClass("ui-tabs"))return;var $inputfield=$this.closest(".Inputfield");var $content=$inputfield.children(".InputfieldContent");if(!$content.hasClass("langTabsContainer")){if($inputfield.find(".langTabsContainer").length==0)$content.addClass("langTabsContainer")}if(cfg.jQueryUI)$this.tabs({active:cfg.activeTab});$this.addClass("langTabsInit");if($inputfield.length)$inputfield.addClass("hasLangTabs");var $parent=$this.parent(".InputfieldContent");if($parent.length){var $span=$("<span></span>").attr("title",cfg.labelOpen).attr("class","langTabsToggle").append("<i class='fa fa-folder-o'></i>");$parent.prev(".InputfieldHeader").append($span)}var $links=$this.find("a.langTabLink");var timeout=null;var $note=$parent.find(".langTabsNote");if(!$links.length){$links=$this.find("a[data-lang]");if(!$links.length)$links=$this.find("a");$links.addClass("langTabLink")}$links.on("mouseover",function(){if(timeout)clearTimeout(timeout);if($parent.width()<500)return;timeout=setTimeout(function(){$note.fadeIn("fast")},250)}).on("mouseout",function(){if(timeout)clearTimeout(timeout);if($parent.width()<500)return;timeout=setTimeout(function(){$note.fadeOut("fast")},250)}).on("click",function(){var $a=$(this);var $items=$a.closest("ul").siblings(".LanguageSupport");var $closeItem=$items.filter(".LanguageSupportCurrent");var $openItem=$items.filter($a.attr("href"));if($closeItem.attr("id")==$openItem.attr("id")){$a.trigger("dblclicklangtab")}else{$closeItem.removeClass("LanguageSupportCurrent");$openItem.addClass("LanguageSupportCurrent");$a.trigger("clicklangtab",[$openItem,$closeItem])}var $ukTab=$a.closest("ul.uk-tab");if($ukTab.length){$ukTab.find(".uk-active").removeClass("uk-active");$a.closest("li").addClass("uk-active")}});if(!cfg.jQueryUI){$links.eq(cfg.activeTab).click()}})}function toggleLanguageTabs(){var $this=$(this);var $header=$this.closest(".InputfieldHeader");var $content=$header.next(".InputfieldContent");var $inputfield=$header.parent(".Inputfield");var $langTabs=$content.children(".langTabs");var $ul=$langTabs.children("ul");var cfg=ProcessWire.config.LanguageTabs;clickLanguageTabActive=true;if($content.hasClass("langTabsContainer")){$ul.find(".langTabLastActive").removeClass("langTabLastActive");if(cfg.liActiveClass)$ul.find("."+cfg.liActiveClass).addClass("langTabLastActive");$ul.find("a").click();$content.removeClass("langTabsContainer");$inputfield.removeClass("hasLangTabs").addClass("langTabsOff");$this.addClass("langTabsOff");if(cfg.jQueryUI)$langTabs.tabs("destroy");$ul.hide();$this.attr("title",ProcessWire.config.LanguageTabs.labelClose).find("i").removeClass("fa-folder-o").addClass("fa-folder-open-o")}else{$content.addClass("langTabsContainer");$inputfield.addClass("hasLangTabs").removeClass("langTabsOff");$this.removeClass("langTabsOff");if(cfg.jQueryUI)$langTabs.tabs();$ul.show();$(this).attr("title",cfg.labelOpen).find("i").addClass("fa-folder-o").removeClass("fa-folder-open-o");$ul.find(".langTabLastActive").removeClass("langTabLastActive").children("a").click()}clickLanguageTabActive=false;return false}function hideLanguageTabs(){$(".InputfieldContent").each(function(){var n=0;$(this).children(".LanguageSupport").each(function(){if(++n==1){$(this).closest(".Inputfield").addClass("hadLanguageSupport");return}$(this).addClass("langTabsHidden")})});var $tab=$(".langTabs").find("li:eq(0)");var cfg=ProcessWire.config.LanguageTabs;if(cfg.liActiveClass&&!$tab.hasClass(cfg.liActiveClass))$tab.find("a").click();$(".langTabsToggle, .LanguageSupportLabel:visible, .langTabs > ul").addClass("langTabsHidden");$(".hasLangTabs").removeClass("hasLangTabs").addClass("hadLangTabs")}function unhideLanguageTabs(){$(".langTabsHidden").removeClass("langTabsHidden");$(".hadLangTabs").removeClass("hadLangTabs").addClass("hasLangTabs");$(".hadLanguageSupport").removeClass("hadLanguageSupport")}jQuery(document).ready(function($){$(document).on("click",".langTabsToggle",toggleLanguageTabs);$(document).on("dblclicklangtab","a.langTabLink",dblclickLanguageTab);$(document).on("reloaded",".Inputfield",function(){var $inputfield=$(this);setTimeout(function(){setupLanguageTabs($inputfield)},100)});$(document).on("AjaxUploadDone",".InputfieldHasFileList .InputfieldFileList",function(){setupLanguageTabs($(this))})});

View File

@@ -7,7 +7,7 @@
* *
* By Adamspruijt and Ryan Cramer, Copyright 2013/2014 * By Adamspruijt and Ryan Cramer, Copyright 2013/2014
* *
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer * ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com * https://processwire.com
* *
* @property string $tabField Name of field/property to use for tab labels. * @property string $tabField Name of field/property to use for tab labels.
@@ -20,7 +20,7 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
public static function getModuleInfo() { public static function getModuleInfo() {
return array( return array(
'title' => 'Languages Support - Tabs', 'title' => 'Languages Support - Tabs',
'version' => 114, 'version' => 115,
'summary' => 'Organizes multi-language fields into tabs for a cleaner easier to use interface.', 'summary' => 'Organizes multi-language fields into tabs for a cleaner easier to use interface.',
'author' => 'adamspruijt, ryan', 'author' => 'adamspruijt, ryan',
'singular' => true, 'singular' => true,
@@ -36,10 +36,21 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
* *
*/ */
protected $tabs = array(); protected $tabs = array();
/**
* Cached settings
*
* @var array
*
*/
protected $settings = array(); protected $settings = array();
/**
* Construct
*
*/
public function __construct() { public function __construct() {
parent::__construct();
$this->set('tabField', 'title'); $this->set('tabField', 'title');
} }
@@ -48,13 +59,22 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
* *
*/ */
public function ready() { public function ready() {
if($this->wire('page')->template != 'admin') return; if($this->wire()->page->template->name !== 'admin') return;
$this->addHookAfter('InputfieldForm::render', $this, 'hookRenderInputfieldForm'); $this->addHookAfter('InputfieldForm::render', $this, 'hookRenderInputfieldForm');
} }
/**
* Get language tab settings
*
* @return array
*
*/
public function getSettings() { public function getSettings() {
if(!empty($this->settings)) return $this->settings; if(!empty($this->settings)) return $this->settings;
$language = null; $language = null;
// allow for specifying language in your "edit" page link, from front-end // allow for specifying language in your "edit" page link, from front-end
// so if you want to focus on the Spanish tabs when the user clicks "edit" // so if you want to focus on the Spanish tabs when the user clicks "edit"
// from /es/path/to/page/, then you can by using a page edit link like: // from /es/path/to/page/, then you can by using a page edit link like:
@@ -63,11 +83,11 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
if($id) $language = $this->languages->get($id); if($id) $language = $this->languages->get($id);
// if language is not specified as a GET variable, then use the user's language // if language is not specified as a GET variable, then use the user's language
if(!$language || !$language->id) $language = $this->user->language; if(!$language || !$language->id) $language = $this->wire()->user->language;
// determine the index of the tab for the user's language // determine the index of the tab for the user's language
$activeTab = 0; $activeTab = 0;
foreach($this->languages as $index => $lang) { foreach($this->wire()->languages as $index => $lang) {
if($lang->id == $language->id) $activeTab = $index; if($lang->id == $language->id) $activeTab = $index;
} }
@@ -86,15 +106,17 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
'loadScripts' => true, 'loadScripts' => true,
'tabField' => $this->get('tabField'), 'tabField' => $this->get('tabField'),
); );
$settings = $this->wire('config')->get('LanguageTabs'); $config = $this->wire()->config;
$settings = $config->get('LanguageTabs');
if(is_array($settings)) { if(is_array($settings)) {
$this->settings = array_merge($defaults, $settings); $this->settings = array_merge($defaults, $settings);
} else { } else {
$this->settings = $defaults; $this->settings = $defaults;
} }
$this->wire('config')->js('LanguageTabs', $this->settings); $config->js('LanguageTabs', $this->settings);
return $this->settings; return $this->settings;
} }
@@ -108,7 +130,7 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
public function hookRenderInputfieldForm(HookEvent $e) { public function hookRenderInputfieldForm(HookEvent $e) {
$settings = $this->getSettings(); $settings = $this->getSettings();
$config = $this->wire('config'); $config = $this->wire()->config;
if($settings['jQueryUI']) { if($settings['jQueryUI']) {
$adminTheme = $this->wire('adminTheme'); $adminTheme = $this->wire('adminTheme');
@@ -121,14 +143,18 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
if($settings['loadScripts']) { if($settings['loadScripts']) {
$config->scripts->add($config->urls->LanguageTabs . 'LanguageTabs.js'); $config->scripts->add($config->urls->LanguageTabs . 'LanguageTabs.js');
} }
/** @var JqueryCore $jQueryCore */
$jQueryCore = $this->wire()->modules->get('JqueryCore');
$jQueryCore->use('longclick');
// $this->wire('modules')->loadModuleFileAssets($this);
$this->wire('modules')->get('JqueryCore')->use('longclick');
if(strpos($e->return, 'LanguageSupport') === false) return; if(strpos($e->return, 'LanguageSupport') === false) return;
/** @var InputfieldForm $form */ /** @var InputfieldForm $form */
$form = $e->object; $form = $e->object;
$id = $form->attr('id'); $id = $form->attr('id');
$e->return .= "<script>setupLanguageTabs($('#$id'));</script>"; $func = "setupLanguageTabs($('#$id'));";
$e->return .= "<script>$func</script>";
} }
/** /**
@@ -152,8 +178,8 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
$aClasses = array('langTabLink', 'langTab' . $language->id); $aClasses = array('langTabLink', 'langTab' . $language->id);
$title = $language->get($this->tabField); $title = $language->get($this->tabField);
if(empty($title)) $title = $language->get('name'); if(empty($title)) $title = $language->get('name');
$title = $this->wire('sanitizer')->entities1($title); $title = $this->wire()->sanitizer->entities1($title);
if(!$this->wire('languages')->editable($language)) { if(!$this->wire()->languages->editable($language)) {
$title = "<s>$title</s>"; $title = "<s>$title</s>";
$liClasses[] = 'LanguageNotEditable'; $liClasses[] = 'LanguageNotEditable';
$liClasses[] = $settings['liDisabledClass']; $liClasses[] = $settings['liDisabledClass'];
@@ -166,7 +192,10 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
$liClass = implode(' ', $liClasses); $liClass = implode(' ', $liClasses);
$aClass = implode(' ', $aClasses); $aClass = implode(' ', $aClasses);
/** @noinspection HtmlUnknownAnchorTarget */ /** @noinspection HtmlUnknownAnchorTarget */
$this->tabs[] = "<li class='$liClass'><a data-lang='$language->id' class='$aClass' href='#langTab_$id'>$title</a></li>"; $this->tabs[] =
"<li class='$liClass'>" .
"<a data-lang='$language->id' class='$aClass' href='#langTab_$id'>$title</a>" .
"</li>";
} }
/** /**
@@ -199,20 +228,27 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
$this->resetTabs(); $this->resetTabs();
return $content; return $content;
} }
/**
* Module config
*
* @param InputfieldWrapper $inputfields
*
*/
public function getModuleConfigInputfields(InputfieldWrapper $inputfields) { public function getModuleConfigInputfields(InputfieldWrapper $inputfields) {
$f = $this->wire('modules')->get('InputfieldSelect'); /** @var InputfieldSelect $f */
$f = $this->wire()->modules->get('InputfieldSelect');
$f->attr('name', 'tabField'); $f->attr('name', 'tabField');
$f->label = $this->_('Field to use for tab labels'); $f->label = $this->_('Field to use for tab labels');
$f->addOption('name'); $f->addOption('name');
foreach($this->wire('templates')->get('language')->fieldgroup as $field) { foreach($this->wire()->templates->get('language')->fieldgroup as $field) {
/** @var Field $field */
if($field->type instanceof FieldtypeMulti) continue; if($field->type instanceof FieldtypeMulti) continue;
$f->addOption($field->name); $f->addOption($field->name);
} }
$f->attr('value', $this->tabField); $f->attr('value', $this->tabField);
$f->required = true; $f->required = true;
$inputfields->add($f); $inputfields->add($f);
return $inputfields;
} }
} }