mirror of
https://github.com/processwire/processwire.git
synced 2025-08-17 20:11:46 +02:00
Various minor tweaks and documentation improvements
This commit is contained in:
@@ -110,6 +110,7 @@ class AdminThemeDefaultHelpers extends WireData {
|
||||
if($page->name != 'page' || $this->wire('input')->urlSegment1) return '';
|
||||
$user = $this->wire('user');
|
||||
if($this->wire('user')->isGuest() || !$user->hasPermission('page-edit')) return '';
|
||||
/** @var ProcessPageAdd $module */
|
||||
$module = $this->wire('modules')->getModule('ProcessPageAdd', array('noInit' => true));
|
||||
$data = $module->executeNavJSON(array('getArray' => true));
|
||||
$items = array();
|
||||
@@ -143,7 +144,7 @@ class AdminThemeDefaultHelpers extends WireData {
|
||||
|
||||
if($this->wire('user')->isLoggedin() && $this->wire('modules')->isInstalled('SystemNotifications')) {
|
||||
$systemNotifications = $this->wire('modules')->get('SystemNotifications');
|
||||
if(!$systemNotifications->placement) return;
|
||||
if(!$systemNotifications->placement) return '';
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
@@ -232,7 +233,9 @@ class AdminThemeDefaultHelpers extends WireData {
|
||||
$info = $this->wire('modules')->getModuleInfo($p->process);
|
||||
if(!empty($info['icon'])) $icon = $info['icon'];
|
||||
}
|
||||
if($p->page_icon) $icon = $p->page_icon; // allow for option of an admin field overriding the module icon
|
||||
// allow for option of an admin field overriding the module icon
|
||||
$pageIcon = $p->get('page_icon');
|
||||
if($pageIcon) $icon = $pageIcon;
|
||||
if(!$icon) switch($p->id) {
|
||||
case 22: $icon = 'gears'; break; // Setup
|
||||
case 21: $icon = 'plug'; break; // Modules
|
||||
@@ -360,6 +363,7 @@ class AdminThemeDefaultHelpers extends WireData {
|
||||
// ProcessPageAdd: avoid showing this menu item if there are no predefined family settings to use
|
||||
$numAddable = $this->wire('session')->getFor('ProcessPageAdd', 'numAddable');
|
||||
if($numAddable === null) {
|
||||
/** @var ProcessPageAdd $processPageAdd */
|
||||
$processPageAdd = $this->wire('modules')->getModule('ProcessPageAdd', array('noInit' => true));
|
||||
if($processPageAdd) {
|
||||
$addData = $processPageAdd->executeNavJSON(array("getArray" => true));
|
||||
@@ -529,9 +533,11 @@ class AdminThemeDefaultHelpers extends WireData {
|
||||
*
|
||||
*/
|
||||
public function renderJSConfig() {
|
||||
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->wire('config');
|
||||
|
||||
|
||||
/** @var array $jsConfig */
|
||||
$jsConfig = $config->js();
|
||||
$jsConfig['debug'] = $config->debug;
|
||||
|
||||
|
@@ -10,12 +10,26 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/** @var Config $config */
|
||||
/** @var AdminThemeDefault $adminTheme */
|
||||
/** @var User $user */
|
||||
/** @var Modules $modules */
|
||||
/** @var Notices $notices */
|
||||
/** @var Page $page */
|
||||
|
||||
if(!defined("PROCESSWIRE")) die();
|
||||
|
||||
if(!isset($content)) $content = '';
|
||||
|
||||
$searchForm = $user->hasPermission('page-edit') ? $modules->get('ProcessPageSearch')->renderSearchForm() : '';
|
||||
$version = $adminTheme->version . 'h';
|
||||
|
||||
if($user->hasPermission('page-edit')) {
|
||||
/** @var ProcessPageSearch $searchForm */
|
||||
$searchForm = $modules->get('ProcessPageSearch');
|
||||
$searchForm = $searchForm->renderSearchForm();
|
||||
} else {
|
||||
$searchForm = '';
|
||||
}
|
||||
|
||||
$version = $adminTheme->version . 'i';
|
||||
|
||||
$config->styles->prepend($config->urls->root . "wire/templates-admin/styles/AdminTheme.css?v=$version");
|
||||
$config->styles->prepend($config->urls->adminTemplates . "styles/" . ($adminTheme->colors ? "main-$adminTheme->colors" : "main-classic") . ".css?v=$version");
|
||||
@@ -27,6 +41,7 @@ $config->scripts->append($config->urls->root . "wire/templates-admin/scripts/mai
|
||||
$config->scripts->append($config->urls->adminTemplates . "scripts/main.$ext?v=$version");
|
||||
|
||||
require_once(dirname(__FILE__) . "/AdminThemeDefaultHelpers.php");
|
||||
/** @var AdminThemeDefaultHelpers $helpers */
|
||||
$helpers = $this->wire(new AdminThemeDefaultHelpers());
|
||||
$extras = $adminTheme->getExtraMarkup();
|
||||
|
||||
@@ -94,7 +109,9 @@ $extras = $adminTheme->getExtraMarkup();
|
||||
<div class="pw-container container">
|
||||
|
||||
<?php
|
||||
if($page->body) echo $page->body;
|
||||
$body = $page->get('body');
|
||||
if($body) echo $body;
|
||||
unset($body);
|
||||
echo $content;
|
||||
echo $extras['content'];
|
||||
?>
|
||||
@@ -120,7 +137,9 @@ $extras = $adminTheme->getExtraMarkup();
|
||||
|
||||
<?php
|
||||
echo $extras['footer'];
|
||||
if($config->debug && $user->isSuperuser()) include($config->paths->root . '/wire/templates-admin/debug.inc');
|
||||
if($config->debug && $user->isSuperuser()) {
|
||||
include($config->paths->root . '/wire/templates-admin/debug.inc');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div><!--/#footer-->
|
||||
|
@@ -7,12 +7,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/** @var Config $config */
|
||||
/** @var ProcessWire $wire */
|
||||
|
||||
$config->inputfieldColumnWidthSpacing = 0; // percent spacing between columns
|
||||
|
||||
$markup = InputfieldWrapper::getMarkup();
|
||||
$markup['item_label'] = "\n\t\t<label class='InputfieldHeader' for='{for}'>{out}</label>";
|
||||
$markup['item_label_hidden'] = "\n\t\t<label class='InputfieldHeader InputfieldHeaderHidden'><span>{out}</span></label>";
|
||||
$markup['item_content'] = "\n\t\t<div class='InputfieldContent'>\n{out}\n\t\t</div>";
|
||||
$markup['item_label'] = "<label class='InputfieldHeader' for='{for}'>{out}</label>";
|
||||
$markup['item_label_hidden'] = "<label class='InputfieldHeader InputfieldHeaderHidden'><span>{out}</span></label>";
|
||||
$markup['item_content'] = "<div class='InputfieldContent'>{out}</div>";
|
||||
InputfieldWrapper::setMarkup($markup);
|
||||
|
||||
$classes = InputfieldWrapper::getClasses();
|
||||
@@ -20,10 +23,12 @@ $classes['item'] = "Inputfield {class} Inputfield_{name}";
|
||||
$classes['item_error'] = "InputfieldStateError";
|
||||
InputfieldWrapper::setClasses($classes);
|
||||
|
||||
wire()->addHookBefore('MarkupPagerNav::render', null, 'hookMarkupPagerNavRender');
|
||||
$wire->addHookBefore('MarkupPagerNav::render', null, 'hookMarkupPagerNavRender');
|
||||
|
||||
/**
|
||||
* Change the default prev/next links for MarkupPagerNav
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
function hookMarkupPagerNavRender(HookEvent $event) {
|
||||
|
@@ -12,10 +12,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/** @var Config $config */
|
||||
/** @var AdminThemeReno $adminTheme */
|
||||
/** @var User $user */
|
||||
/** @var Modules $modules */
|
||||
|
||||
if(!defined("PROCESSWIRE")) die();
|
||||
|
||||
if(!isset($content)) $content = '';
|
||||
$version = $adminTheme->version . 'j';
|
||||
$version = $adminTheme->version . 'k';
|
||||
$ext = $config->debug ? "js" : "min.js";
|
||||
|
||||
// Search form
|
||||
|
@@ -175,7 +175,7 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
|
||||
// identify the current language from the user, or set one if it's not already
|
||||
if($this->user->language && $this->user->language->id) {
|
||||
$language = $this->user->language;
|
||||
// $language = $this->user->language;
|
||||
} else {
|
||||
$language = $this->defaultLanguagePage;
|
||||
$this->user->language = $language;
|
||||
@@ -222,7 +222,7 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
public function ready() {
|
||||
// styles used by our Inputfield hooks
|
||||
if($this->wire('page')->template == 'admin') {
|
||||
$this->config->styles->add($this->config->urls->LanguageSupport . "LanguageSupport.css");
|
||||
$this->config->styles->add($this->config->urls('LanguageSupport') . "LanguageSupport.css");
|
||||
$language = $this->wire('user')->language;
|
||||
if($language) $this->config->js('LanguageSupport', array(
|
||||
'language' => array(
|
||||
@@ -306,6 +306,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
* Hook before Inputfield::render to set proper default language value
|
||||
*
|
||||
* Only applies to Inputfields that have: useLanguages == true
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookInputfieldBeforeRender(HookEvent $event) {
|
||||
@@ -330,6 +332,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
*
|
||||
* Only applies to Inputfields that have: useLanguages == false.
|
||||
* Applies only if page-edit-lang-none permission is installed.
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookInputfieldWrapperBeforeRenderInputfield(HookEvent $event) {
|
||||
@@ -372,9 +376,9 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
$out;
|
||||
}
|
||||
|
||||
$out = "\n<div class='$class' id='langTab_$id' data-language='$language->id'>" .
|
||||
"\n<label for='$id' class='$labelClass'>$label</label>" . $out .
|
||||
"\n</div>";
|
||||
$out = "<div class='$class' id='langTab_$id' data-language='$language->id'>" .
|
||||
"<label for='$id' class='$labelClass'>$label</label>" . $out .
|
||||
"</div>";
|
||||
return $out;
|
||||
}
|
||||
|
||||
@@ -382,6 +386,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
* Hook into Inputfield::render to duplicate inputs for other languages
|
||||
*
|
||||
* Only applies to Inputfields that have: useLanguages == true
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookInputfieldAfterRender(HookEvent $event) {
|
||||
@@ -468,6 +474,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
|
||||
/**
|
||||
* Hook before Inputfield::processInput to process input for other languages (or prevent it)
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookInputfieldBeforeProcessInput(HookEvent $event) {
|
||||
@@ -502,6 +510,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
* Hook into Inputfield::processInput to process input for other languages
|
||||
*
|
||||
* Only applies to Inputfields that have: useLanguages == true
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookInputfieldAfterProcessInput(HookEvent $event) {
|
||||
@@ -555,6 +565,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
|
||||
/**
|
||||
* Hook into Field::getInputfield to change label/description to proper language
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookFieldGetInputfield(HookEvent $event) {
|
||||
@@ -564,7 +576,9 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
|
||||
/** @var Field $field */
|
||||
$field = $event->object;
|
||||
/** @var Page $page */
|
||||
$page = $event->arguments[0];
|
||||
/** @var Template $template */
|
||||
$template = $page ? $page->template : null;
|
||||
$inputfield = $event->return;
|
||||
if(!$inputfield) return;
|
||||
@@ -607,6 +621,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
|
||||
/**
|
||||
* Hook called when new language added
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookPageAdded(HookEvent $event) {
|
||||
@@ -630,6 +646,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
|
||||
/**
|
||||
* Hook called when language is deleted
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookPageDeleteReady(HookEvent $event) {
|
||||
@@ -684,6 +702,9 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
* This method exists in this class rather than one of the field-specific classes
|
||||
* because it deals with both language fields and page names, and potentially
|
||||
* other types of unknown types that implement LanguagesValueInterface.
|
||||
*
|
||||
* @param HookEvent $event
|
||||
* @throws WireException
|
||||
*
|
||||
*/
|
||||
public function hookPageSetLanguageValue(HookEvent $event) {
|
||||
@@ -747,12 +768,18 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
* This method exists in this class rather than one of the field-specific classes
|
||||
* because it deals with both language fields and page names, and potentially
|
||||
* other types of unknown types that implement LanguagesValueInterface.
|
||||
*
|
||||
* @param HookEvent $event
|
||||
* @throws WireException
|
||||
*
|
||||
*/
|
||||
public function hookPageGetLanguageValue(HookEvent $event) {
|
||||
|
||||
|
||||
/** @var Page $page */
|
||||
$page = $event->object;
|
||||
/** @var Language $language */
|
||||
$language = $event->arguments(0);
|
||||
/** @var Field $field */
|
||||
$field = $event->arguments(1);
|
||||
$value = null;
|
||||
|
||||
@@ -794,9 +821,13 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
|
||||
/**
|
||||
* Module configuration screen
|
||||
*
|
||||
* @param array $data
|
||||
* @return InputfieldWrapper
|
||||
*
|
||||
*/
|
||||
public static function getModuleConfigInputfields(array $data) {
|
||||
if($data) {}
|
||||
$form = new InputfieldWrapper();
|
||||
// TBA
|
||||
return $form;
|
||||
@@ -827,10 +858,13 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
|
||||
|
||||
/**
|
||||
* Install or uninstall by loading the LanguageSupportInstall script
|
||||
*
|
||||
* @param bool $install
|
||||
*
|
||||
*/
|
||||
protected function installer($install = true) {
|
||||
require_once($this->config->paths->LanguageSupport . 'LanguageSupportInstall.php');
|
||||
require_once(dirname(__FILE__) . '/LanguageSupportInstall.php');
|
||||
/** @var LanguageSupportInstall $installer */
|
||||
$installer = $this->wire(new LanguageSupportInstall());
|
||||
if($install) $installer->install();
|
||||
else $installer->uninstall();
|
||||
|
@@ -5,6 +5,11 @@
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @method void languageAdded(Page $language) #pw-hooker
|
||||
* @method void languageDeleted(Page $language) #pw-hooker
|
||||
* @method void fieldLanguageAdded(Field $field, Page $language) #pw-hooker
|
||||
* @method void fieldLanguageRemoved(Field $field, Page $language) #pw-hooker
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -118,6 +123,8 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
*
|
||||
* Replace a value of one field with the value from another field that has the same name, but with the language name appended to it.
|
||||
* Example: title and title_es
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookFieldtypeFormatValue(HookEvent $event) {
|
||||
@@ -131,6 +138,7 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
// exit quickly if we can determine now we don't need to continue
|
||||
if(!isset($this->multilangAlternateFields[$field->name])) return;
|
||||
|
||||
/** @var Page $page */
|
||||
$page = $event->arguments[0];
|
||||
|
||||
// determine name of language field, if present.
|
||||
@@ -160,6 +168,8 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
|
||||
/**
|
||||
* Hook called when new language added
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookLanguageAdded(HookEvent $event) {
|
||||
@@ -178,14 +188,18 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
|
||||
/**
|
||||
* Hookable function called when a new language is added
|
||||
*
|
||||
*
|
||||
* @param Page|Language $language
|
||||
e*
|
||||
*/
|
||||
public function ___languageAdded(Page $language) {
|
||||
// hookable, intentionally blank
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called when language is deleted
|
||||
* Hook called when languag is deleted
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function hookLanguageDeleted(HookEvent $event) {
|
||||
@@ -203,6 +217,8 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
|
||||
/**
|
||||
* Hookable function called when a language is deleted
|
||||
*
|
||||
* @param Page|Language $language
|
||||
*
|
||||
*/
|
||||
public function ___languageDeleted(Page $language) {
|
||||
@@ -212,6 +228,9 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
|
||||
/**
|
||||
* Called when a new language is added to the system for each field that implements FieldtypeLanguageInterface
|
||||
*
|
||||
* @param Field $field
|
||||
* @param Page|Language $language
|
||||
*
|
||||
*/
|
||||
public function ___fieldLanguageAdded(Field $field, Page $language) {
|
||||
@@ -248,6 +267,9 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
|
||||
/**
|
||||
* Called when a language is removed from the system for each field that implements FieldtypeLanguageInterface
|
||||
*
|
||||
* @param Field $field
|
||||
* @param Page|Language $language
|
||||
*
|
||||
*/
|
||||
protected function ___fieldLanguageRemoved(Field $field, Page $language) {
|
||||
@@ -276,6 +298,8 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
* Adjusts the selectors passed to the query so that find operations search in user's native language version, as well as the default version.
|
||||
*
|
||||
* We may make this behavior configurable later on, as one may want to limit the search to 1 language only.
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function pageFinderGetQuery(HookEvent $event) {
|
||||
@@ -289,7 +313,7 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
$arguments = $event->arguments;
|
||||
$selectors = $arguments[0];
|
||||
|
||||
foreach($selectors as $key => $selector) {
|
||||
foreach($selectors as $selector) {
|
||||
|
||||
$changed = false;
|
||||
$fields = $selector->field;
|
||||
@@ -334,6 +358,8 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
* Hook into FieldtypeLanguageInterface::loadPageField
|
||||
*
|
||||
* Converts the value to a LanguagesPageFieldValue
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function fieldtypeLoadPageField(HookEvent $event) {
|
||||
@@ -349,6 +375,8 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
* Hook into FieldtypeLanguageInterface::wakeupValue
|
||||
*
|
||||
* Converts the value to a LanguagesPageFieldValue
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function fieldtypeWakeupValue(HookEvent $event) {
|
||||
@@ -374,12 +402,14 @@ class LanguageSupportFields extends WireData implements Module {
|
||||
* Hook into FieldtypeLanguageInterface::sleepValue
|
||||
*
|
||||
* Converts a LanguagesPageFieldValue to an array
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function fieldtypeSleepValue(HookEvent $event) {
|
||||
|
||||
$page = $event->arguments[0];
|
||||
$field = $event->arguments[1];
|
||||
// $page = $event->arguments[0];
|
||||
// $field = $event->arguments[1];
|
||||
$value = $event->arguments[2];
|
||||
//$value = $event->return;
|
||||
$values = array();
|
||||
|
@@ -8,6 +8,9 @@
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @method void install()
|
||||
* @method void uninstall()
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
@@ -54,7 +54,7 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
|
||||
// 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:
|
||||
// <a href='{$config->urls->admin}page/edit/?id=$page->id&language=$user->language'>Edit</a>
|
||||
$id = (int) $this->input->get->language;
|
||||
$id = (int) $this->input->get('language');
|
||||
if($id) $language = $this->languages->get($id);
|
||||
|
||||
// if language is not specified as a GET variable, then use the user's language
|
||||
@@ -85,7 +85,9 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
|
||||
$this->wire('modules')->loadModuleFileAssets($this);
|
||||
$this->wire('modules')->get('JqueryCore')->use('longclick');
|
||||
if(strpos($e->return, 'LanguageSupport') === false) return;
|
||||
$id = $e->object->attr('id');
|
||||
/** @var InputfieldForm $form */
|
||||
$form = $e->object;
|
||||
$id = $form->attr('id');
|
||||
$e->return .= "<script>setupLanguageTabs($('#$id'));</script>";
|
||||
}
|
||||
|
||||
@@ -117,6 +119,7 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
|
||||
}
|
||||
$id = $inputfield->attr('id');
|
||||
$liClass = trim($liClass);
|
||||
/** @noinspection HtmlUnknownAnchorTarget */
|
||||
$this->tabs[] = "<li class='$liClass'><a data-lang='$language->id' class='$class' href='#langTab_$id'>$title</a></li>";
|
||||
}
|
||||
|
||||
@@ -127,7 +130,7 @@ class LanguageTabs extends WireData implements Module, ConfigurableModule {
|
||||
* This method automatically calls resetTabs() after rendering.
|
||||
*
|
||||
* @param Inputfield $inputfield
|
||||
* @param $content Content that will have the tabs
|
||||
* @param string $content Content that will have the tabs
|
||||
* @return string Modified $content with tabs
|
||||
*
|
||||
*/
|
||||
|
Reference in New Issue
Block a user