Forráskód Böngészése

#3685 Wiki: new layout for wiki pages

Alex Trofimov 4 éve
szülő
commit
e94dda7d42

+ 6 - 0
inc/classes/BxDolTemplate.php

@@ -2895,6 +2895,7 @@ class BxDolTemplate extends BxDolFactory implements iBxDolSingleton
             "'<bx_text:([_\{\}\w\d\s]+[^\s]{1}) \/>'s" => "get_text",
             "'<bx_text:([_\{\}\w\d\s]+[^\s]{1}) \/>'s" => "get_text",
             "'<bx_text_js:([^\s]+) \/>'s" => "get_text_js",
             "'<bx_text_js:([^\s]+) \/>'s" => "get_text_js",
             "'<bx_text_attribute:([^\s]+) \/>'s" => "get_text_attribute",
             "'<bx_text_attribute:([^\s]+) \/>'s" => "get_text_attribute",
+            "'<bx_page:([^\s]+) \/>'s" => "get_page",
         ));
         ));
 
 
         foreach($aCallbackPatterns as $sPattern => $sAction)
         foreach($aCallbackPatterns as $sPattern => $sAction)
@@ -2923,6 +2924,11 @@ class BxDolTemplate extends BxDolFactory implements iBxDolSingleton
                 case 'get_menu':
                 case 'get_menu':
                     $sResult = $oTemplate->getMenu($aMatches[1]);
                     $sResult = $oTemplate->getMenu($aMatches[1]);
                     break;
                     break;
+                case 'get_page':
+                    $oPage = BxDolPage::getObjectInstanceByURI($aMatches[1], false, true);
+                    $oPage->setSubPage(true);
+                    $sResult = $oPage ? $oPage->getCode() : '';
+                    break;
             }
             }
 
 
             return $sResult;
             return $sResult;

+ 32 - 0
inc/classes/BxDolWiki.php

@@ -175,6 +175,7 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
     public function getContents ($sAllExceptSpecified = '', $sOnlySpecified = '')
     public function getContents ($sAllExceptSpecified = '', $sOnlySpecified = '')
     {
     {
         $aAllExceptSpecified = $sAllExceptSpecified ? explode(',', $sAllExceptSpecified) : array();
         $aAllExceptSpecified = $sAllExceptSpecified ? explode(',', $sAllExceptSpecified) : array();
+        $aAllExceptSpecified = array_merge($aAllExceptSpecified, ['wiki-pages-list', 'wiki-page-contents']);
         $aOnlySpecified = $sOnlySpecified ? explode(',', $sOnlySpecified) : array();
         $aOnlySpecified = $sOnlySpecified ? explode(',', $sOnlySpecified) : array();
         if (!($a = $this->_oQuery->getPages($aAllExceptSpecified, $aOnlySpecified)))
         if (!($a = $this->_oQuery->getPages($aAllExceptSpecified, $aOnlySpecified)))
             return '';
             return '';
@@ -540,6 +541,7 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
                 $oLang->addLanguageString($sLangKey, $sVal, $iLangId, $iLangCat);
                 $oLang->addLanguageString($sLangKey, $sVal, $iLangId, $iLangCat);
             }
             }
 
 
+            $sUrl = $this->getPageUrl($sPageUri, false, false);
             return array('code' => 0, 'url' => BxDolPermalinks::getInstance()->permalink($sUrl));
             return array('code' => 0, 'url' => BxDolPermalinks::getInstance()->permalink($sUrl));
         }
         }
         else {
         else {
@@ -917,6 +919,36 @@ class BxDolParsedown extends Parsedown
         }
         }
         return $a;
         return $a;
     }
     }
+
+	protected function blockHeader($Excerpt) {
+		$a = parent::blockHeader($Excerpt);
+
+		if (isset($a)) {
+			$sText = trim($a['element']['handler']['argument'], '#');
+			$sText = trim($sText, ' ');
+			$sLink = preg_replace('/[^\p{L}\p{N}\p{M}-]+/u', '', mb_strtolower(mb_ereg_replace(' ','-', $sText)));
+			$aAttr = array();
+
+			if (!empty($sLink)) {
+				$aAttr = isset($a['element']['attributes']) ? $a['element']['attributes'] : [];
+				$aAttr['id'] = $sLink;
+
+				$aHandler = array(
+					'function' => 'lineElements',
+					'argument' => $sText,
+					'destination' => 'elements',
+				);
+
+				$a['element']['attributes'] = $aAttr;
+				$a['element']['handler'] = $aHandler;
+			}
+		} 
+        else {
+			$a = null;
+		}
+
+        return $a;
+	}
 }
 }
 
 
 /** @} */
 /** @} */

+ 1 - 1
inc/classes/BxDolWikiQuery.php

@@ -158,7 +158,7 @@ class BxDolWikiQuery extends BxDolDb
         return $this->getAll("SELECT `title`, `uri`, `object` FROM `sys_objects_page` WHERE `module` = ?" . $sWhere, array($this->_aObject['module']));
         return $this->getAll("SELECT `title`, `uri`, `object` FROM `sys_objects_page` WHERE `module` = ?" . $sWhere, array($this->_aObject['module']));
     }
     }
 
 
-    public function insertPage ($sUri, $sUrl, $sTitleLangKey, $iType = 1, $iLayoutId = 5, $iVisibleForLevels = 2147483647, $sClass = 'BxTemplPageWiki')
+    public function insertPage ($sUri, $sUrl, $sTitleLangKey, $iType = 1, $iLayoutId = 20, $iVisibleForLevels = 2147483647, $sClass = 'BxTemplPageWiki')
     {
     {
         $oQueryPageBuilder = new BxDolStudioBuilderPageQuery();
         $oQueryPageBuilder = new BxDolStudioBuilderPageQuery();
         return $oQueryPageBuilder->insertPage($this->_aObject['module'] . '_' . str_replace('-', '_', $sUri), $this->_aObject['module'], $sUri, $sUrl, $sTitleLangKey, $iType, $iLayoutId, $iVisibleForLevels, $sClass);
         return $oQueryPageBuilder->insertPage($this->_aObject['module'] . '_' . str_replace('-', '_', $sUri), $this->_aObject['module'], $sUri, $sUrl, $sTitleLangKey, $iType, $iLayoutId, $iVisibleForLevels, $sClass);

+ 5 - 1
inc/js/classes/BxDolWiki.js

@@ -148,7 +148,11 @@ BxDolWiki.prototype.actionClosePopup = function (oResponce) {
 }
 }
 BxDolWiki.prototype.actionReload = function (oResponce) {
 BxDolWiki.prototype.actionReload = function (oResponce) {
     var l = document.location;
     var l = document.location;
-    loadDynamicBlock(oResponce.block_id, l.hash.length ? l.href.replace(l.hash, '') : l.href);
+    var ePage = $('#bx-page-block-' + oResponce.block_id).parents('.bx-layout-wrapper:first');
+    var sUrl = l.hash.length ? l.href.replace(l.hash, '') : l.href;
+    if (ePage.size())
+        sUrl = sUrlRoot + 'page.php?i=' + ePage.attr('id').replace('bx-page-', ''); 
+    loadDynamicBlock(oResponce.block_id, sUrl);
 }
 }
 
 
 BxDolWiki.prototype.actionDeleteBlock = function (oResponce) {
 BxDolWiki.prototype.actionDeleteBlock = function (oResponce) {

+ 9 - 2
install/sql/system.sql

@@ -5240,7 +5240,9 @@ INSERT INTO `sys_objects_page` (`object`, `uri`, `title_system`, `title`, `modul
 ('sys_cmts_view' ,'cmts-view', '_sys_page_title_system_cmts_view', '_cmt_page_view_header', 'system', 1, 5, '', 2147483647, 1, 'page.php?i=cmts-view', '', '', '', 0, 1, 0, 'BxTemplCmtsPageView', '', 0),
 ('sys_cmts_view' ,'cmts-view', '_sys_page_title_system_cmts_view', '_cmt_page_view_header', 'system', 1, 5, '', 2147483647, 1, 'page.php?i=cmts-view', '', '', '', 0, 1, 0, 'BxTemplCmtsPageView', '', 0),
 ('sys_cmts_administration' ,'cmts-administration', '_sys_page_title_system_cmts_administration', '_sys_page_title_cmts_administration', 'system', 1, 5, '', 192, 1, 'page.php?i=cmts-administration', '', '', '', 0, 1, 0, '', '', 0),
 ('sys_cmts_administration' ,'cmts-administration', '_sys_page_title_system_cmts_administration', '_sys_page_title_cmts_administration', 'system', 1, 5, '', 192, 1, 'page.php?i=cmts-administration', '', '', '', 0, 1, 0, '', '', 0),
 ('sys_audit' ,'audit-administration', '_sys_page_title_system_audit_administration', '_sys_page_title_audit_administration', 'system', 1, 5, '', 192, 1, 'page.php?i=audit-administration', '', '', '', 0, 1, 0, '', '', 0),
 ('sys_audit' ,'audit-administration', '_sys_page_title_system_audit_administration', '_sys_page_title_audit_administration', 'system', 1, 5, '', 192, 1, 'page.php?i=audit-administration', '', '', '', 0, 1, 0, '', '', 0),
-('sys_search_keyword', 'search-keyword', '_sys_page_title_system_search_keyword', '_sys_page_title_search_keyword', 'system', 1, 5, '', 2147483647, 1, 'searchKeyword.php', '', '', '', 0, 1, 0, '', '', 0);
+('sys_search_keyword', 'search-keyword', '_sys_page_title_system_search_keyword', '_sys_page_title_search_keyword', 'system', 1, 5, '', 2147483647, 1, 'searchKeyword.php', '', '', '', 0, 1, 0, '', '', 0),
+('sys_sub_wiki_pages_list', 'wiki-pages-list', '', '_sys_page_title_wiki_pages_list', 'system', 1, 5, '', 2147483647, 1, '', '', '', '', 0, 1, 0, '', '', 0),
+('sys_sub_wiki_page_contents', 'wiki-page-contents', '', '_sys_page_title_wiki_page_contents', 'system', 1, 5, '', 2147483647, 1, '', '', '', '', 0, 1, 0, '', '', 0);
 
 
 
 
 CREATE TABLE IF NOT EXISTS `sys_pages_types` (
 CREATE TABLE IF NOT EXISTS `sys_pages_types` (
@@ -5288,7 +5290,8 @@ INSERT INTO `sys_pages_layouts` (`id`, `name`, `icon`, `title`, `template`, `cel
 (16, 'topbottom_area_col1_col3_col2', 'layout_topbottom_area_col1_col3_col2.png', '_sys_layout_topbottom_area_col1_col3_col2', 'layout_topbottom_area_col1_col3_col2.html', 5),
 (16, 'topbottom_area_col1_col3_col2', 'layout_topbottom_area_col1_col3_col2.png', '_sys_layout_topbottom_area_col1_col3_col2', 'layout_topbottom_area_col1_col3_col2.html', 5),
 (17, 'topbottom_area_col1_col5', 'layout_topbottom_area_col1_col5.png', '_sys_layout_topbottom_area_col1_col5', 'layout_topbottom_area_col1_col5.html', 4),
 (17, 'topbottom_area_col1_col5', 'layout_topbottom_area_col1_col5.png', '_sys_layout_topbottom_area_col1_col5', 'layout_topbottom_area_col1_col5.html', 4),
 (18, '1_column_thin', 'layout_1_column_thin.png', '_sys_layout_1_column_thin', 'layout_1_column_thin.html', 1),
 (18, '1_column_thin', 'layout_1_column_thin.png', '_sys_layout_1_column_thin', 'layout_1_column_thin.html', 1),
-(19, '1_column_half', 'layout_1_column_half.png', '_sys_layout_1_column_half', 'layout_1_column_half.html', 1);
+(19, '1_column_half', 'layout_1_column_half.png', '_sys_layout_1_column_half', 'layout_1_column_half.html', 1),
+(20, '1_column_wiki', 'layout_1_column_wiki.png', '_sys_layout_1_column_wiki', 'layout_1_column_wiki.html', 1);
 
 
 CREATE TABLE IF NOT EXISTS `sys_pages_design_boxes` (
 CREATE TABLE IF NOT EXISTS `sys_pages_design_boxes` (
   `id` int(11) NOT NULL,
   `id` int(11) NOT NULL,
@@ -5465,6 +5468,10 @@ INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title_system`, `
 
 
 ('sys_search_keyword', 1, 'system', '', '_sys_page_block_title_search_keyword_form', 13, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:19:"search_keyword_form";s:6:"params";a:0:{}s:5:"class";s:13:"TemplServices";}', 0, 1, 1, 1),
 ('sys_search_keyword', 1, 'system', '', '_sys_page_block_title_search_keyword_form', 13, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:19:"search_keyword_form";s:6:"params";a:0:{}s:5:"class";s:13:"TemplServices";}', 0, 1, 1, 1),
 ('sys_search_keyword', 1, 'system', '', '_sys_page_block_title_search_keyword_result', 0, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:21:"search_keyword_result";s:6:"params";a:0:{}s:5:"class";s:13:"TemplServices";}', 0, 1, 1, 1),
 ('sys_search_keyword', 1, 'system', '', '_sys_page_block_title_search_keyword_result', 0, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:21:"search_keyword_result";s:6:"params";a:0:{}s:5:"class";s:13:"TemplServices";}', 0, 1, 1, 1),
+
+('sys_sub_wiki_pages_list', 1, 'system', '', '_sys_page_block_title_wiki_pages_list', 0, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:10:"pages_list";s:6:"params";a:0:{}s:5:"class";s:16:"TemplServiceWiki";}', 0, 1, 1, 1),
+('sys_sub_wiki_page_contents', 1, 'system', '', '_sys_page_block_title_wiki_page_contents', 0, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:13:"page_contents";s:6:"params";a:0:{}s:5:"class";s:16:"TemplServiceWiki";}', 0, 1, 1, 1),
+
 -- studio dashboard blocks
 -- studio dashboard blocks
 ('sys_std_dashboard', 1, 'system', '', '_sys_page_block_title_std_dash_version', 11, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:17:"get_block_version";s:6:"params";a:0:{}s:5:"class";s:20:"TemplStudioDashboard";}', 0, 0, 1, 1),
 ('sys_std_dashboard', 1, 'system', '', '_sys_page_block_title_std_dash_version', 11, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:17:"get_block_version";s:6:"params";a:0:{}s:5:"class";s:20:"TemplStudioDashboard";}', 0, 0, 1, 1),
 
 

+ 4 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -3143,6 +3143,8 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_page_block_title_terms"><![CDATA[Terms of Service]]></string>
 	<string name="_sys_page_block_title_terms"><![CDATA[Terms of Service]]></string>
         <string name="_sys_page_block_title_sys_std_site_submenu"><![CDATA[Site submenu]]></string>
         <string name="_sys_page_block_title_sys_std_site_submenu"><![CDATA[Site submenu]]></string>
         <string name="_sys_page_block_title_std_site_submenu"><![CDATA[Site submenu]]></string>
         <string name="_sys_page_block_title_std_site_submenu"><![CDATA[Site submenu]]></string>
+        <string name="_sys_page_block_title_wiki_pages_list"><![CDATA[Pages List]]></string>
+        <string name="_sys_page_block_title_wiki_page_contents"><![CDATA[Page Contents]]></string>
     
     
 	<string name="_sys_page_lang_block_about"><![CDATA[This site is powered by UNA. The rest is a mystery.]]></string>
 	<string name="_sys_page_lang_block_about"><![CDATA[This site is powered by UNA. The rest is a mystery.]]></string>
 	<string name="_sys_page_lang_block_terms"><![CDATA[Our terms of use.]]></string>
 	<string name="_sys_page_lang_block_terms"><![CDATA[Our terms of use.]]></string>
@@ -3210,6 +3212,8 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_page_title_unsubscribe_news"><![CDATA[Unsubscribe From Site Newsletters]]></string>
 	<string name="_sys_page_title_unsubscribe_news"><![CDATA[Unsubscribe From Site Newsletters]]></string>
 	<string name="_sys_page_title_unsubscribe_notifications"><![CDATA[Unsubscribe From Site Notifications]]></string>
 	<string name="_sys_page_title_unsubscribe_notifications"><![CDATA[Unsubscribe From Site Notifications]]></string>
 	<string name="_sys_page_title_studio_dashboard"><![CDATA[Studio Dashboard]]></string>
 	<string name="_sys_page_title_studio_dashboard"><![CDATA[Studio Dashboard]]></string>
+	<string name="_sys_page_title_wiki_pages_list"><![CDATA[Pages List]]></string>
+	<string name="_sys_page_title_wiki_page_contents"><![CDATA[Page Contents]]></string>
         <string name="_sys_page_type_application"><![CDATA[Application]]></string>
         <string name="_sys_page_type_application"><![CDATA[Application]]></string>
 	<string name="_sys_page_type_default"><![CDATA[Default]]></string>
 	<string name="_sys_page_type_default"><![CDATA[Default]]></string>
         <string name="_sys_page_type_standard"><![CDATA[Standard]]></string>
         <string name="_sys_page_type_standard"><![CDATA[Standard]]></string>

+ 4 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -3108,6 +3108,8 @@
 	<string name="_sys_page_block_title_std_dash_cache"><![CDATA[Кэш]]></string>
 	<string name="_sys_page_block_title_std_dash_cache"><![CDATA[Кэш]]></string>
     <string name="_sys_page_block_title_std_dash_queues"><![CDATA[Очереди]]></string>
     <string name="_sys_page_block_title_std_dash_queues"><![CDATA[Очереди]]></string>
 	<string name="_sys_page_block_title_terms"><![CDATA[Правила пользования]]></string>
 	<string name="_sys_page_block_title_terms"><![CDATA[Правила пользования]]></string>
+    <string name="_sys_page_block_title_wiki_pages_list"><![CDATA[Список страниц]]></string>
+    <string name="_sys_page_block_title_wiki_page_contents"><![CDATA[Содержание страницы]]></string>
 	<string name="_sys_page_lang_block_about"><![CDATA[Этот сайт сделан на UNA. Остальное - тайна, покрытая мраком.]]></string>
 	<string name="_sys_page_lang_block_about"><![CDATA[Этот сайт сделан на UNA. Остальное - тайна, покрытая мраком.]]></string>
 	<string name="_sys_page_lang_block_terms"><![CDATA[Правила пользования нашим сайтом.]]></string>
 	<string name="_sys_page_lang_block_terms"><![CDATA[Правила пользования нашим сайтом.]]></string>
 	<string name="_sys_page_lang_block_privacy"><![CDATA[Политика конфиденциальности нашего сайта.]]></string>
 	<string name="_sys_page_lang_block_privacy"><![CDATA[Политика конфиденциальности нашего сайта.]]></string>
@@ -3174,6 +3176,8 @@
 	<string name="_sys_page_title_unsubscribe_news"><![CDATA[Отписаться от новостей сайта]]></string>
 	<string name="_sys_page_title_unsubscribe_news"><![CDATA[Отписаться от новостей сайта]]></string>
 	<string name="_sys_page_title_unsubscribe_notifications"><![CDATA[Отписаться от уведомлений сайта]]></string>
 	<string name="_sys_page_title_unsubscribe_notifications"><![CDATA[Отписаться от уведомлений сайта]]></string>
 	<string name="_sys_page_title_studio_dashboard"><![CDATA[Студия - Панель]]></string>
 	<string name="_sys_page_title_studio_dashboard"><![CDATA[Студия - Панель]]></string>
+	<string name="_sys_page_title_wiki_pages_list"><![CDATA[Список страниц]]></string>
+	<string name="_sys_page_title_wiki_page_contents"><![CDATA[Содержание страницы]]></string>
         <string name="_sys_page_type_application"><![CDATA[Приложение]]></string>
         <string name="_sys_page_type_application"><![CDATA[Приложение]]></string>
 	<string name="_sys_page_type_default"><![CDATA[Тип по умолчанию]]></string>
 	<string name="_sys_page_type_default"><![CDATA[Тип по умолчанию]]></string>
         <string name="_sys_page_type_standard"><![CDATA[Стандартная]]></string>
         <string name="_sys_page_type_standard"><![CDATA[Стандартная]]></string>

+ 100 - 0
plugins_public/toc.js

@@ -0,0 +1,100 @@
+// https://github.com/ghiculescu/jekyll-table-of-contents
+(function($){
+  $.fn.toc = function(options) {
+    var defaults = {
+      noBackToTopLinks: false,
+      title: '<i>Jump to...</i>',
+      minimumHeaders: 3,
+      headers: 'h1, h2, h3, h4, h5, h6',
+      listType: 'ol', // values: [ol|ul]
+      showEffect: 'show', // values: [show|slideDown|fadeIn|none]
+      showSpeed: 'slow', // set to 0 to deactivate effect
+      classes: { list: '',
+                 item: '',
+                 link: ''
+               }
+    },
+    settings = $.extend(defaults, options);
+
+    function fixedEncodeURIComponent (str) {
+      return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
+        return '%' + c.charCodeAt(0).toString(16);
+      });
+    }
+
+    function createLink (header) {
+      var innerText = (header.textContent === undefined) ? header.innerText : header.textContent;
+      var href = document.location.href.replace(document.location.hash, '');
+      return "<a class='"+settings.classes.link+"' href='" + href + "#" + fixedEncodeURIComponent(header.id) + "'>" + innerText + "</a>";
+    }
+
+    var headers = $(settings.headers).filter(function() {
+      // get all headers with an ID
+      var previousSiblingName = $(this).prev().attr( "name" );
+      if (!this.id && previousSiblingName) {
+        this.id = $(this).attr( "id", previousSiblingName.replace(/\./g, "-") );
+      }
+      return this.id;
+    }), output = $(this);
+    if (!headers.length || headers.length < settings.minimumHeaders || !output.length) {
+      $(this).hide();
+      return;
+    }
+
+    if (0 === settings.showSpeed) {
+      settings.showEffect = 'none';
+    }
+
+    var render = {
+      show: function() { output.hide().html(html).show(settings.showSpeed); },
+      slideDown: function() { output.hide().html(html).slideDown(settings.showSpeed); },
+      fadeIn: function() { output.hide().html(html).fadeIn(settings.showSpeed); },
+      none: function() { output.html(html); }
+    };
+
+    var get_level = function(ele) { return parseInt(ele.nodeName.replace("H", ""), 10); };
+    var highest_level = headers.map(function(_, ele) { return get_level(ele); }).get().sort()[0];
+    var return_to_top = '<i class="icon-arrow-up back-to-top"> </i>';
+
+    var level = get_level(headers[0]),
+      this_level,
+      html = settings.title + " <" +settings.listType + " class=\"" + settings.classes.list +"\">";
+    headers.on('click', function() {
+      if (!settings.noBackToTopLinks) {
+        window.location.hash = this.id;
+      }
+    })
+    .addClass('clickable-header')
+    .each(function(_, header) {
+      this_level = get_level(header);
+      if (!settings.noBackToTopLinks && this_level === highest_level) {
+        $(header).addClass('top-level-header').after(return_to_top);
+      }
+      if (this_level === level) // same level as before; same indenting
+        html += "<li class=\"" + settings.classes.item + "\">" + createLink(header);
+      else if (this_level <= level){ // higher level than before; end parent ol
+        for(var i = this_level; i < level; i++) {
+          html += "</li></"+settings.listType+">"
+        }
+        html += "<li class=\"" + settings.classes.item + "\">" + createLink(header);
+      }
+      else if (this_level > level) { // lower level than before; expand the previous to contain a ol
+        for(i = this_level; i > level; i--) {
+          html += "<" + settings.listType + " class=\"" + settings.classes.list +"\">" +
+                  "<li class=\"" + settings.classes.item + "\">"
+        }
+        html += createLink(header);
+      }
+      level = this_level; // update for the next one
+    });
+    html += "</"+settings.listType+">";
+    if (!settings.noBackToTopLinks) {
+      $(document).on('click', '.back-to-top', function() {
+        $(window).scrollTop(0);
+        window.location.hash = '';
+      });
+    }
+
+    render[settings.showEffect]();
+  };
+})(jQuery);

+ 40 - 0
studio/template/layout_1_column_wiki.html

@@ -0,0 +1,40 @@
+<!-- layout 1 column with menu on left and contents on right [ start ] -->
+<div id="__page_id__" class="bx-layout-wrapper bx-layout-bcb">
+    <div class="bx-layout-row flex">
+        <div class="bx-layout-col bx-layout-bcb-bar1 bx-layout-column-thin w-1/4">
+            <div class="bx-layout-cell pr-2 lg:pr-3" id="bx-layout-cell-1">
+<div class="space-y-2 bx-def-margin-topbottom bx-def-padding-sec bx-def-border">
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-4 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+</div>
+            </div>
+        </div>
+        <div class="bx-layout-col bx-layout-bcb-content bx-layout-column-half w-1/2">
+            <div class="bx-layout-cell px-2 lg:px-3" id="bx-layout-cell-2">
+                __cell_1__
+            </div>
+        </div>
+        <div class="bx-layout-col bx-layout-bcb-bar2 bx-layout-column-thin w-1/4">
+            <div class="bx-layout-cell pl-2 lg:pl-3" id="bx-layout-cell-3">
+<div class="space-y-1 bx-def-margin-topbottom bx-def-padding-sec bx-def-border">
+    <div class="h-3 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-3 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-3 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-3 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-3 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+    <div class="h-3 bg-gray-200 dark:bg-gray-700 rounded-xl">&nbsp;</div>
+</div>
+            </div>
+        </div>
+    </div>
+    <bx_include_auto:_row_1_column_dump.html />
+</div>
+<!-- layout 1 column with menu on left and contents on right [  end  ] -->

BIN
template/images/layout_1_column_wiki.png


+ 22 - 0
template/layout_1_column_wiki.html

@@ -0,0 +1,22 @@
+<!-- layout 1 column with menu on left and contents on right [ start ] -->
+<div id="__page_id__" class="bx-layout-wrapper bx-layout-bcb">
+    <div class="bx-layout-row flex">
+        <div class="bx-layout-col bx-layout-bcb-bar1 bx-layout-column-thin w-1/4">
+            <div class="bx-layout-cell pr-2 lg:pr-3" id="bx-layout-cell-1">
+                <bx_page:wiki-pages-list />
+            </div>
+        </div>
+        <div class="bx-layout-col bx-layout-bcb-content bx-layout-column-half w-1/2">
+            <div class="bx-layout-cell px-2 lg:px-3" id="bx-layout-cell-2">
+                __cell_1__
+            </div>
+        </div>
+        <div class="bx-layout-col bx-layout-bcb-bar2 bx-layout-column-thin w-1/4">
+            <div class="bx-layout-cell pl-2 lg:pl-3" id="bx-layout-cell-3">
+                <bx_page:wiki-page-contents />
+            </div>
+        </div>
+    </div>
+    <bx_include_auto:_row_1_column_dump.html />
+</div>
+<!-- layout 1 column with menu on left and contents on right [  end  ] -->

+ 13 - 3
template/scripts/BxBasePage.php

@@ -23,6 +23,8 @@ class BxBasePage extends BxDolPage
     
     
     protected $_bStickyColumns = false;
     protected $_bStickyColumns = false;
 
 
+    protected $_bSubPage = false;
+
     public function __construct ($aObject, $oTemplate)
     public function __construct ($aObject, $oTemplate)
     {
     {
         parent::__construct ($aObject);
         parent::__construct ($aObject);
@@ -175,11 +177,13 @@ class BxBasePage extends BxDolPage
 
 
         $this->_addJsCss();
         $this->_addJsCss();
 
 
-        $this->_addSysTemplateVars();
+        if (!$this->_bSubPage) {
+            $this->_addSysTemplateVars();
 
 
-        $this->_selectMenu();
+            $this->_selectMenu();
 
 
-        $this->_setSubmenu(array());
+            $this->_setSubmenu(array());
+        }
 
 
         if (!getParam('sys_page_cache_enable') || !$this->_aObject['cache_lifetime'] || (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST')) {
         if (!getParam('sys_page_cache_enable') || !$this->_aObject['cache_lifetime'] || (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST')) {
             $sPageCode = $this->_getPageCode();
             $sPageCode = $this->_getPageCode();
@@ -215,6 +219,7 @@ class BxBasePage extends BxDolPage
             'page_object' => $this,
             'page_object' => $this,
             'page_query' => $this->_oQuery,
             'page_query' => $this->_oQuery,
             'page_code' => &$sPageCode,
             'page_code' => &$sPageCode,
+            'sub_page' => $this->_bSubPage,
         ));
         ));
 
 
         $sPageCode .= $this->getJsScript();
         $sPageCode .= $this->getJsScript();
@@ -276,6 +281,11 @@ class BxBasePage extends BxDolPage
     	return $bResult;
     	return $bResult;
     }
     }
 
 
+    public function setSubPage($b = true)
+    {
+        $this->_bSubPage = $b;
+    }
+
     public function setPageCover($bCover = true)
     public function setPageCover($bCover = true)
     {
     {
         $this->_aObject['cover'] = (bool)$bCover;
         $this->_aObject['cover'] = (bool)$bCover;

+ 49 - 0
template/scripts/BxBaseServiceWiki.php

@@ -43,6 +43,8 @@ class BxBaseServiceWiki extends BxDol
         $oPage = BxDolPage::getObjectInstanceByModuleAndURI($oWiki->getObjectName(), $sUri);
         $oPage = BxDolPage::getObjectInstanceByModuleAndURI($oWiki->getObjectName(), $sUri);
         if ($oPage) {
         if ($oPage) {
 
 
+            $_GET['i'] = $sUri;
+
             $oPage->displayPage();
             $oPage->displayPage();
 
 
         } else {
         } else {
@@ -213,6 +215,53 @@ class BxBaseServiceWiki extends BxDol
         return $a;
         return $a;
     }
     }
 
 
+    /**
+     * @page service Service Calls
+     * @section bx_system_general System Services 
+     * @subsection bx_system_general-wiki Wiki
+     * @subsubsection bx_system_general-pages_list pages_list
+     * 
+     * Get list of pages in current module
+     * 
+     * @see BxBaseServiceWiki::servicePagesList
+     */
+    /** 
+     * @ref bx_system_general-pages_list "pages_list"
+     */
+    public function servicePagesList ()
+    {
+        if (!($sPageObject = BxDolPageQuery::getPageObjectNameByURI(bx_get('i'))))
+            return '';
+        if (!($aPage = BxDolPageQuery::getPageObject ($sPageObject)))
+            return '';
+        if (!($oWiki = BxDolWiki::getObjectInstance($aPage['module'])))
+            return '';
+
+        BxDolTemplate::getInstance()->addCss(['wiki.css', 'wiki-github-markdown.css']);
+
+        return $oWiki->getContents();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_system_general System Services 
+     * @subsection bx_system_general-wiki Wiki
+     * @subsubsection bx_system_general-page_contents page_contents
+     * 
+     * Get table of contents for current page, generated automatically from paragraphs headers
+     * 
+     * @see BxBaseServiceWiki::servicePageContents
+     */
+    /** 
+     * @ref bx_system_general-page_contents "page_contents"
+     */
+    public function servicePageContents ()
+    {
+        $o = BxDolTemplate::getInstance();
+        $o->addJs('toc.js');
+        return $o->parseHtmlByName('wiki_page_contents.html', []);
+    }
+
     protected function _addCssJs ($bAddPage = false)
     protected function _addCssJs ($bAddPage = false)
     {
     {
         if ($this->_bJsCssAdded)
         if ($this->_bJsCssAdded)

+ 1 - 1
template/wiki_contents.html

@@ -1,4 +1,4 @@
-<ul class="bx-wiki-contents bx-def-font-large">
+<ul class="bx-wiki-contents bx-def-font-large markdown-body">
     <bx_repeat:pages>
     <bx_repeat:pages>
         <li><a href="__url__">__title__</a></li>
         <li><a href="__url__">__title__</a></li>
     </bx_repeat:pages>
     </bx_repeat:pages>

+ 14 - 0
template/wiki_page_contents.html

@@ -0,0 +1,14 @@
+<div id="bx_wiki_toc" class="markdown-body"></div>
+
+<script type="text/javascript">
+$(document).ready(function() {
+    if ("undefined" != typeof($("#bx_wiki_toc").toc))
+        $("#bx_wiki_toc").toc({
+            title:"", 
+            noBackToTopLinks: true, 
+            minimumHeaders: 2, 
+            showSpeed: 0, 
+            headers: ".bx-page-wiki-container h2, .bx-page-wiki-container h3, .bx-page-wiki-container h4, .bx-page-wiki-container h5, .bx-page-wiki-container h6" 
+        });
+});
+</script>