'Languages Support - Tabs', 'version' => 117, 'summary' => 'Organizes multi-language fields into tabs for a cleaner easier to use interface.', 'author' => 'adamspruijt, ryan, flipzoom', 'singular' => true, 'autoload' => "template=admin", 'requires' => 'LanguageSupport' ); } /** * Temporary storage of tabs created from addTab() method * * @var array of strings * */ protected $tabs = array(); /** * Cached settings * * @var array * */ protected $settings = array(); /** * Construct * */ public function __construct() { parent::__construct(); $this->set('tabField', 'title'); } /** * Add hooks, setup JS config, and determine active tab * */ public function ready() { if($this->wire()->page->template->name !== 'admin') return; $this->addHookAfter('InputfieldForm::render', $this, 'hookRenderInputfieldForm'); } /** * Get language tab settings * * @return array * */ public function getSettings() { if(!empty($this->settings)) return $this->settings; $language = null; $input = $this->wire()->input; $languages = $this->wire()->languages; // 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" // from /es/path/to/page/, then you can by using a page edit link like: // Edit $id = (int) $input->get('language'); if($id) $language = $languages->get($id); // if language is not specified as a GET variable, then use the user's language if(!$language || !$language->id) $language = $this->wire()->user->language; // determine the index of the tab for the user's language $activeTab = 0; foreach($languages as $index => $lang) { if($lang->id == $language->id) $activeTab = $index; } $defaults = array( 'jQueryUI' => true, // use jQuery UI tabs? 'labelOpen' => $this->_('Expand Language Tabs'), 'labelClose' => $this->_('Collapse/Convert Back to Tabs'), 'activeTab' => $activeTab, 'ulClass' => '', 'ulAttrs' => '', 'liActiveClass' => '', 'liDisabledClass' => '', 'liEmptyClass' => '', 'aClass' => '', 'loadStyles' => true, 'loadScripts' => true, 'tabField' => $this->get('tabField'), 'requestId' => ((string) $this->wire()->process) . (int) $input->get('id'), ); $config = $this->wire()->config; $settings = $config->get('LanguageTabs'); if(is_array($settings)) { $this->settings = array_merge($defaults, $settings); } else { $this->settings = $defaults; } $config->js('LanguageTabs', $this->settings); return $this->settings; } /** * Init language tabs in form immediately after form render * * @param HookEvent $e * */ public function hookRenderInputfieldForm(HookEvent $e) { $settings = $this->getSettings(); $config = $this->wire()->config; $info = self::getModuleInfo(); if($settings['jQueryUI']) { $adminTheme = $this->wire()->adminTheme; if($adminTheme) $adminTheme->addBodyClass('LanguageTabsJqueryUI'); } if($settings['loadStyles']) { $config->styles->add($config->urls('LanguageTabs') . "LanguageTabs.css?v=$config->version-$info[version]"); } if($settings['loadScripts']) { $config->scripts->add($config->urls('LanguageTabs') . "LanguageTabs.js?v=$config->version-$info[version]"); } /** @var JqueryCore $jQueryCore */ $jQueryCore = $this->wire()->modules->get('JqueryCore'); $jQueryCore->use('longclick'); $jQueryCore->use('cookie'); if(strpos($e->return, 'LanguageSupport') === false) return; /** @var InputfieldForm $form */ $form = $e->object; $id = $form->attr('id'); $func = "setupLanguageTabs($('#$id'));"; $e->return .= ""; } /** * Clear any stored tabs * */ public function resetTabs() { $this->tabs = array(); } /** * Add a new tab, to be later retrieved by renderTabs() * * @param Inputfield $inputfield * @param Language $language * */ public function addTab(Inputfield $inputfield, Language $language) { $settings = $this->getSettings(); $liClasses = array(); $aClasses = array('langTabLink', 'langTab' . $language->id); $title = $language->get(empty($settings['tabField']) ? $this->tabField : $settings['tabField']); if(empty($title)) $title = $language->get("$this->tabField|name"); $title = $this->wire()->sanitizer->entities1($title); if(!$this->wire()->languages->editable($language)) { $title = "$title"; $liClasses[] = 'LanguageNotEditable'; $liClasses[] = $settings['liDisabledClass']; } if($inputfield->isEmpty()) { $liClasses[] = 'langTabEmpty'; $liClasses[] = $settings['liEmptyClass']; } $id = $inputfield->attr('id'); $liClass = implode(' ', $liClasses); $aClass = implode(' ', $aClasses); /** @noinspection HtmlUnknownAnchorTarget */ $this->tabs[] = "
  • " . "$title" . "
  • "; } /** * Render output for all added tabs * * Note that if only 1 tab has been added, tabs won't be displayed (no point in it). * This method automatically calls resetTabs() after rendering. * * @param Inputfield $inputfield * @param string $content Content that will have the tabs * @return string Modified $content with tabs * */ public function renderTabs(Inputfield $inputfield, $content) { $settings = $this->getSettings(); if(count($this->tabs) > 1) { $inputfield->wrapClass .= " hasLangTabs"; $inputfield->contentClass .= " langTabsContainer"; $tabs = implode('', $this->tabs); $id = $inputfield->attr('id'); $note = "" . $this->_('click twice to change all tabs') . ""; $attrs = $settings['ulAttrs']; $attrs .= $settings['ulClass'] ? " class='$settings[ulClass]'" : ""; $attrs = strlen($attrs) ? " " . trim($attrs) : ""; $content = "
    $note$tabs$content
    "; } else { // do nothing, just return content because there was only 1 tab (no render necessary) } $this->resetTabs(); return $content; } /** * Module config * * @param InputfieldWrapper $inputfields * */ public function getModuleConfigInputfields(InputfieldWrapper $inputfields) { /** @var InputfieldSelect $f */ $f = $this->wire()->modules->get('InputfieldSelect'); $f->attr('name', 'tabField'); $f->label = $this->_('Field to use for tab labels'); $f->addOption('name'); foreach($this->wire()->templates->get('language')->fieldgroup as $field) { /** @var Field $field */ if($field->type instanceof FieldtypeMulti) continue; $f->addOption($field->name); } $f->attr('value', $this->tabField); $f->required = true; $inputfields->add($f); } }