VolkerE has submitted this change and it was merged. Change subject: Switch to core's server-side HTML templating ......................................................................
Switch to core's server-side HTML templating Copy template setup code from https://www.mediawiki.org/wiki/Manual:HTML_templates into BlueprintSkinTemplate, Also the 'debughtml' from vendor/werdnum/mediawiki-lightncandy-skin/AbstractLightNCandyTemplate.php werdnum's lightncandy wrappers are no longer needed, so no more vendor, and hence no more BlueprintHooks::registerExtension. No more PHP compiled skin files in templates/. Tweak templates to not use @first (Core's lightncandy doesn't support it), which also fixes some bugs. Requires recent MW 1.26 with support for partials in PHP HTML templating (Id588ae9b). Bug: T104672 Bug: T113067 Bug: T110988 Change-Id: I450c799382f6c596fd0c82b482a765b24322e7dd --- D BlueprintHooks.php M composer.json D composer.lock M resources/master.less M skin.json M src/BlueprintSkinTemplate.php R templates/Skin.mustache D templates/Skin.php R templates/sidebar.mustache 9 files changed, 38 insertions(+), 508 deletions(-) Approvals: VolkerE: Looks good to me, approved diff --git a/BlueprintHooks.php b/BlueprintHooks.php deleted file mode 100644 index fe79ae1..0000000 --- a/BlueprintHooks.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php - -class BlueprintHooks { - - /** - * Executed after processing skin.json - */ - public static function registerExtension() { - require_once __DIR__ . '/vendor/autoload.php'; - } -} \ No newline at end of file diff --git a/composer.json b/composer.json index 1724e12..3d55a97 100644 --- a/composer.json +++ b/composer.json @@ -1,14 +1,10 @@ { - "require": { - "werdnum/simple-lightncandy": "~0.1-dev", - "werdnum/mediawiki-lightncandy-skin": "~0.1-dev" - }, - "require-dev": { - "jakub-onderka/php-parallel-lint": "0.9.*" - }, - "scripts": { - "test": [ - "parallel-lint . --exclude vendor" - ] - } + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9.*" + }, + "scripts": { + "test": [ + "parallel-lint . --exclude vendor" + ] + } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 1bd96bf..0000000 --- a/composer.lock +++ /dev/null @@ -1,176 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "588b787398a5b08e15c2f367fafcb0bf", - "packages": [ - { - "name": "werdnum/mediawiki-lightncandy-skin", - "version": "0.1.x-dev", - "source": { - "type": "git", - "url": "https://github.com/werdnum/mediawiki-lightncandyskin.git", - "reference": "79ddf899dee8fea78cc4888dec6f2328bb0ef21d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/werdnum/mediawiki-lightncandyskin/zipball/79ddf899dee8fea78cc4888dec6f2328bb0ef21d", - "reference": "79ddf899dee8fea78cc4888dec6f2328bb0ef21d", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "AbstractLightNCandyTemplate.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL" - ], - "authors": [ - { - "name": "Andrew Garrett", - "email": "[email protected]" - } - ], - "description": "Simple library for creating LightnCandy based skins for MediaWiki.", - "time": "2015-01-14 12:06:59" - }, - { - "name": "werdnum/simple-lightncandy", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/werdnum/simple-lightncandy.git", - "reference": "3f9ce07c4ac3e7391b4dabf5bb0a107f361cd626" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/werdnum/simple-lightncandy/zipball/3f9ce07c4ac3e7391b4dabf5bb0a107f361cd626", - "reference": "3f9ce07c4ac3e7391b4dabf5bb0a107f361cd626", - "shasum": "" - }, - "require": { - "zordius/lightncandy": "~0.18" - }, - "type": "library", - "autoload": { - "classmap": [ - "SimpleLightNCandy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "description": "No-nonsense templating with lightncandy", - "time": "2015-04-06 10:24:18" - }, - { - "name": "zordius/lightncandy", - "version": "v0.20", - "source": { - "type": "git", - "url": "https://github.com/zordius/lightncandy.git", - "reference": "257355494db7edb4738471fa7f2b247a2c4d8719" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zordius/lightncandy/zipball/257355494db7edb4738471fa7f2b247a2c4d8719", - "reference": "257355494db7edb4738471fa7f2b247a2c4d8719", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "4.0.17" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/lightncandy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Zordius Chen", - "email": "[email protected]" - } - ], - "description": "An extremely fast PHP implementation of handlebars ( http://handlebarsjs.com/ ) and mustache ( http://mustache.github.io/ ).", - "homepage": "https://github.com/zordius/lightncandy", - "keywords": [ - "handlebars", - "logicless", - "mustache", - "php", - "template" - ], - "time": "2015-03-04 02:07:44" - } - ], - "packages-dev": [ - { - "name": "jakub-onderka/php-parallel-lint", - "version": "v0.9", - "source": { - "type": "git", - "url": "https://github.com/JakubOnderka/PHP-Parallel-Lint.git", - "reference": "1b693fb455201cacf595163c92bfb1adfa2158d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Parallel-Lint/zipball/1b693fb455201cacf595163c92bfb1adfa2158d8", - "reference": "1b693fb455201cacf595163c92bfb1adfa2158d8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "jakub-onderka/php-console-highlighter": "~0.3", - "nette/tester": "~1.3" - }, - "suggest": { - "jakub-onderka/php-console-highlighter": "Highlight syntax in code snippet" - }, - "bin": [ - "parallel-lint" - ], - "type": "library", - "autoload": { - "classmap": [ - "./" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "[email protected]" - } - ], - "description": "This tool check syntax of PHP files about 20x faster than serial check.", - "homepage": "https://github.com/JakubOnderka/PHP-Parallel-Lint", - "time": "2015-06-16 10:17:07" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "werdnum/simple-lightncandy": 20, - "werdnum/mediawiki-lightncandy-skin": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] -} diff --git a/resources/master.less b/resources/master.less index de86246..89a3e7e 100644 --- a/resources/master.less +++ b/resources/master.less @@ -195,6 +195,13 @@ background-image: url(talk.svg); } } + /* + * Hide the current tab (e.g. "Page" or "Discussion") + * in the content_navigation.namespace set of tabs. + */ + .mw-skin-bs-cn_ns .selected { + display:none + } } } diff --git a/skin.json b/skin.json index 441efb7..73beb38 100644 --- a/skin.json +++ b/skin.json @@ -9,7 +9,6 @@ "descriptionmsg": "blueprint-skin-desc", "type": "skin", "license-name": "MIT", - "callback": "BlueprintHooks::registerExtension", "ValidSkinNames": { "blueprint": "Blueprint" }, @@ -19,7 +18,6 @@ ] }, "AutoloadClasses": { - "BlueprintHooks": "BlueprintHooks.php", "SkinBlueprint": "src/SkinBlueprint.php", "BlueprintSkinTemplate": "src/BlueprintSkinTemplate.php" }, diff --git a/src/BlueprintSkinTemplate.php b/src/BlueprintSkinTemplate.php index d198c65..30a77f4 100644 --- a/src/BlueprintSkinTemplate.php +++ b/src/BlueprintSkinTemplate.php @@ -1,11 +1,22 @@ <?php -class BlueprintSkinTemplate extends LightNCandyTemplate { +class BlueprintSkinTemplate extends QuickTemplate { public function execute() { global $wgBlueprintLeftNav; + $this->data['debughtml'] = MWDebug::getDebugHTML( $this->getSkin()->getContext() ); $this->data['left_nav_sections'] = $this->getLeftNav(); - return parent::execute(); + $this->data['username'] = $this->data['personal_urls']['userpage']; + + $templateParser = new TemplateParser( __DIR__ . '/../templates' ); + try { + echo $templateParser->processTemplate( + 'Skin', + $this->data + ); + } catch ( Exception $e ) { + echo 'Error: ' . htmlspecialchars( $e->getMessage() ); + } } // This returns an array of the pages in the leftnav that are specified diff --git a/templates/Skin.template b/templates/Skin.mustache similarity index 90% rename from templates/Skin.template rename to templates/Skin.mustache index 620f7bf..327d557 100644 --- a/templates/Skin.template +++ b/templates/Skin.mustache @@ -24,13 +24,7 @@ <ul class="nav navbar-nav navbar-right"> <li class="dropdown"> <a href="#" class="account-menu dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> - {{! HACK: personal_urls.0.text not working }} - {{#each personal_urls}} - {{#if @first}} - {{text}} - {{/if}} - {{/each}} - {{! /HACK }} + {{ username.text }} </a> <ul class="dropdown-menu" role="menu"> {{#each personal_urls}} diff --git a/templates/Skin.php b/templates/Skin.php deleted file mode 100644 index 5327c6d..0000000 --- a/templates/Skin.php +++ /dev/null @@ -1,287 +0,0 @@ -<?php return function ($in, $debugopt = 1) { - $cx = array( - 'flags' => array( - 'jstrue' => false, - 'jsobj' => false, - 'spvar' => true, - 'prop' => false, - 'method' => false, - 'mustlok' => true, - 'echo' => false, - 'debug' => $debugopt, - ), - 'constants' => array( - 'DEBUG_ERROR_LOG' => 1, - 'DEBUG_ERROR_EXCEPTION' => 2, - 'DEBUG_TAGS' => 4, - 'DEBUG_TAGS_ANSI' => 12, - 'DEBUG_TAGS_HTML' => 20, - ), - 'helpers' => array( 'msg' => function( array $args, array $named ) { - $message = null; - $str = array_shift( $args ); - - return wfMessage( $str )->params( $args )->text(); - }, -), - 'blockhelpers' => array(), - 'hbhelpers' => array(), - 'partials' => array(), - 'scopes' => array(), - 'sp_vars' => array('root' => $in), - 'lcrun' => 'LCRun3', -'funcs' => array( - 'v' => function ($cx, $base, $path) { - $count = count($cx['scopes']); - while ($base) { - $v = $base; - foreach ($path as $name) { - if (is_array($v) && isset($v[$name])) { - $v = $v[$name]; - continue; - } - if (is_object($v)) { - if ($cx['flags']['prop'] && isset($v->$name)) { - $v = $v->$name; - continue; - } - if ($cx['flags']['method'] && is_callable(array($v, $name))) { - $v = $v->$name(); - continue; - } - } - if ($cx['flags']['mustlok']) { - unset($v); - break; - } - return null; - } - if (isset($v)) { - return $v; - } - $count--; - switch ($count) { - case -1: - $base = $cx['sp_vars']['root']; - break; - case -2: - return null; - default: - $base = $cx['scopes'][$count]; - } - } - }, - 'sec' => function ($cx, $v, $in, $each, $cb, $else = null) { - $isAry = is_array($v); - $isTrav = $v instanceof Traversable; - $loop = $each; - $keys = null; - $last = null; - $isObj = false; - - if ($isAry && $else !== null && count($v) === 0) { - $cx['scopes'][] = $in; - $ret = $else($cx, $in); - array_pop($cx['scopes']); - return $ret; - } - - // #var, detect input type is object or not - if (!$loop && $isAry) { - $keys = array_keys($v); - $loop = (count(array_diff_key($v, array_keys($keys))) == 0); - $isObj = !$loop; - } - - if (($loop && $isAry) || $isTrav) { - if ($each && !$isTrav) { - // Detect input type is object or not when never done once - if ($keys == null) { - $keys = array_keys($v); - $isObj = (count(array_diff_key($v, array_keys($keys))) > 0); - } - } - $ret = array(); - $cx['scopes'][] = $in; - $i = 0; - if ($cx['flags']['spvar']) { - $old_spvar = $cx['sp_vars']; - $cx['sp_vars'] = array( - '_parent' => $old_spvar, - 'root' => $old_spvar['root'], - ); - if (!$isTrav) { - $last = count($keys) - 1; - } - } - foreach ($v as $index => $raw) { - if ($cx['flags']['spvar']) { - $cx['sp_vars']['first'] = ($i === 0); - $cx['sp_vars']['last'] = ($i == $last); - $cx['sp_vars']['key'] = $index; - $cx['sp_vars']['index'] = $i; - $i++; - } - $ret[] = $cb($cx, $raw); - } - if ($cx['flags']['spvar']) { - if ($isObj) { - unset($cx['sp_vars']['key']); - } else { - unset($cx['sp_vars']['last']); - } - unset($cx['sp_vars']['index']); - unset($cx['sp_vars']['first']); - $cx['sp_vars'] = $old_spvar; - } - array_pop($cx['scopes']); - return join('', $ret); - } - if ($each) { - if ($else !== null) { - $cx['scopes'][] = $in; - $ret = $else($cx, $v); - array_pop($cx['scopes']); - return $ret; - } - return ''; - } - if ($isAry) { - $cx['scopes'][] = $in; - $ret = $cb($cx, $v); - array_pop($cx['scopes']); - return $ret; - } - - if ($v === true) { - return $cb($cx, $in); - } - - if (!is_null($v) && ($v !== false)) { - return $cb($cx, $v); - } - - if ($else !== null) { - $cx['scopes'][] = $in; - $ret = $else($cx, $in); - array_pop($cx['scopes']); - return $ret; - } - - return ''; - }, - 'ifvar' => function ($cx, $v) { - return !is_null($v) && ($v !== false) && ($v !== 0) && ($v !== 0.0) && ($v !== '') && (is_array($v) ? (count($v) > 0) : true); - }, - 'ch' => function ($cx, $ch, $vars, $op) { - return $cx['funcs']['chret'](call_user_func_array($cx['helpers'][$ch], $vars), $op); - }, - 'chret' => function ($ret, $op) { - if (is_array($ret)) { - if (isset($ret[1]) && $ret[1]) { - $op = $ret[1]; - } - $ret = $ret[0]; - } - - switch ($op) { - case 'enc': - return htmlentities($ret, ENT_QUOTES, 'UTF-8'); - case 'encq': - return preg_replace('/'/', ''', htmlentities($ret, ENT_QUOTES, 'UTF-8')); - } - return $ret; - }, -) - - ); - - return ''.$cx['funcs']['v']($cx, $in, array('headelement')).' - -<div id="side-menu"> -'.' <h6 class="side-menu-heading">'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('titletext')), ENT_QUOTES, 'UTF-8').'</h6> - <ul class="content-links"> -'.$cx['funcs']['sec']($cx, $cx['funcs']['v']($cx, $in, array('content_navigation','views')), $in, true, function($cx, $in) {return ' <li> - <a - href="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('href')), ENT_QUOTES, 'UTF-8').'" - class="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('class')), ENT_QUOTES, 'UTF-8').'" - '.(($cx['funcs']['ifvar']($cx, $cx['funcs']['v']($cx, $in, array('rel')))) ? 'rel="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('rel')), ENT_QUOTES, 'UTF-8').'"' : '').' - '.(($cx['funcs']['ifvar']($cx, $cx['funcs']['v']($cx, $in, array('id')))) ? 'id="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('id')), ENT_QUOTES, 'UTF-8').'"' : '').' - > - '.htmlentities((string)$cx['funcs']['v']($cx, $in, array('text')), ENT_QUOTES, 'UTF-8').' - </a> - </li> -';}).''.$cx['funcs']['sec']($cx, $cx['funcs']['v']($cx, $in, array('content_navigation','namespaces')), $in, true, function($cx, $in) {return ''.((!$cx['funcs']['ifvar']($cx, $cx['funcs']['v']($cx, $cx['sp_vars'], array('first')))) ? ' <li> - <a - href="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('href')), ENT_QUOTES, 'UTF-8').'" - class="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('class')), ENT_QUOTES, 'UTF-8').'" - id="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('id')), ENT_QUOTES, 'UTF-8').'" - > - '.htmlentities((string)$cx['funcs']['v']($cx, $in, array('text')), ENT_QUOTES, 'UTF-8').' - </a> - </li> -' : '').'';}).' </ul> - <ul class="toc sidebar-toc"> -'.$cx['funcs']['sec']($cx, $cx['funcs']['v']($cx, $in, array('left_nav_sections')), $in, true, function($cx, $in) {return ' <li class="'.(($cx['funcs']['ifvar']($cx, $cx['funcs']['v']($cx, $in, array('current')))) ? 'sidebar-toc-active' : '').' sidebar-toc-page"> - <a href="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('url')), ENT_QUOTES, 'UTF-8').'"> - <span class="tocnumber">—</span> - <span class="toctext">'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('text')), ENT_QUOTES, 'UTF-8').'</span> - </a> - </li> -';}).' </ul> -'.'</div> - - <nav class="navbar navbar-fixed-top"> - <div class="navbar-header"> - <ul class="nav navbar-nav navbar-head" > - <li><a href="javascript:void(0)" id="toc-toggle"></a></li> - <li><a class="navbar-brand" href="/">'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('sitename')), ENT_QUOTES, 'UTF-8').'</a></li> - <li id="extra-space"></li> - </ul> - </div> - - <div class="collapse navbar-collapse" id="navbar-collapse"> - <div id="navbar-right"> - <form class="navbar-form navbar-left" action="'.$cx['funcs']['v']($cx, $in, array('scriptpath')).'" role="search"> - <input type="search" id="searchInput" name="search" class="form-control search-input" placeholder="Search"> - <label for="searchInput" class="search-input-label">Search</label> - <input type="hidden" name="title" value="Special:Search"> - </form> - - <ul class="nav navbar-nav navbar-right"> - <li class="dropdown"> - <a href="#" class="account-menu dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> -'.$cx['funcs']['sec']($cx, $cx['funcs']['v']($cx, $in, array('personal_urls')), $in, true, function($cx, $in) {return ''.(($cx['funcs']['ifvar']($cx, $cx['funcs']['v']($cx, $cx['sp_vars'], array('first')))) ? ' '.htmlentities((string)$cx['funcs']['v']($cx, $in, array('text')), ENT_QUOTES, 'UTF-8').' -' : '').'';}).' </a> - <ul class="dropdown-menu" role="menu"> -'.$cx['funcs']['sec']($cx, $cx['funcs']['v']($cx, $in, array('personal_urls')), $in, true, function($cx, $in) {return ' <li><a href="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('href')), ENT_QUOTES, 'UTF-8').'" class="'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('class')), ENT_QUOTES, 'UTF-8').'">'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('text')), ENT_QUOTES, 'UTF-8').'</a></li> -';}).' </ul> - </li> - </ul> - </div> - </div> - </nav> - - <div class="container" id="content"> - <h1 class="firstHeading" id="firstHeading"> - '.$cx['funcs']['v']($cx, $in, array('title')).' - </h1> -'.(($cx['funcs']['ifvar']($cx, $cx['funcs']['v']($cx, $in, array('isarticle')))) ? ' <div id="siteSub">'.$cx['funcs']['ch']($cx, 'msg', array(array('tagline'),array()), 'enc').'</div> -' : '').' <div id="contentSub" '.$cx['funcs']['v']($cx, $in, array('userlangattributes')).'> - '.$cx['funcs']['v']($cx, $in, array('subtitle')).' - </div> -'.(($cx['funcs']['ifvar']($cx, $cx['funcs']['v']($cx, $in, array('undelete')))) ? ' <div id="contentSub2">'.$cx['funcs']['v']($cx, $in, array('undelete')).'</div> -' : '').''.(($cx['funcs']['ifvar']($cx, $cx['funcs']['v']($cx, $in, array('newtalk')))) ? ' <div class="usermessage">'.htmlentities((string)$cx['funcs']['v']($cx, $in, array('newtalk')), ENT_QUOTES, 'UTF-8').'</div> -' : '').' <div class="mw-body-content" id="bodyContent"> - '.$cx['funcs']['v']($cx, $in, array('bodytext')).' - </div> - </div> - -'.$cx['funcs']['v']($cx, $in, array('debughtml')).' -'.$cx['funcs']['v']($cx, $in, array('bottomscripts')).' -'.$cx['funcs']['v']($cx, $in, array('reporttime')).' -</body> -</html> -'; -} -?> diff --git a/templates/sidebar.template b/templates/sidebar.mustache similarity index 79% rename from templates/sidebar.template rename to templates/sidebar.mustache index 29890e1..46d00ac 100644 --- a/templates/sidebar.template +++ b/templates/sidebar.mustache @@ -13,17 +13,15 @@ </li> {{/each}} {{#each content_navigation.namespaces}} - {{#unless @first}} - <li> - <a - href="{{href}}" - class="{{class}}" - id="{{id}}" - > - {{text}} - </a> - </li> - {{/unless}} + <li class="mw-skin-bs-cn_ns"> + <a + href="{{href}}" + class="{{class}}" + id="{{id}}" + > + {{text}} + </a> + </li> {{/each}} </ul> <ul class="toc sidebar-toc"> -- To view, visit https://gerrit.wikimedia.org/r/223165 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I450c799382f6c596fd0c82b482a765b24322e7dd Gerrit-PatchSet: 11 Gerrit-Project: mediawiki/skins/Blueprint Gerrit-Branch: master Gerrit-Owner: Spage <[email protected]> Gerrit-Reviewer: Legoktm <[email protected]> Gerrit-Reviewer: Paladox <[email protected]> Gerrit-Reviewer: Prtksxna <[email protected]> Gerrit-Reviewer: Spage <[email protected]> Gerrit-Reviewer: VolkerE <[email protected]> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
