Phuedx has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/219188

Change subject: Extend the core TemplateParser
......................................................................

Extend the core TemplateParser

TemplateParser#getTemplate eval's a compiled template so that the
renderer function can be returned to the caller. Due to a bug in HHVM's
implementation of eval [0], we can't rely on the render function
returned by #getTemplate on being the correct one.

Extend the Gather\views\TemplateParser class so that #getTemplate will
write the compiled template to a file that is then required, thus
avoiding eval. The compiled templates are written to the
templates/compiled directory and should be committed whenever they
change.

Since the new TemplateParser class can't change the public API of the
parent TemplateParser (LSP), the rest of the codebase should be agnostic
to the change. However, because we're expecting the compiled templates
to be committed, modify Gather\views\helpers\Template::render
to force template recompilation whenever the GatherRecompileTemplates
config variable is true.

The GatherRecompileTemplates config variable defaults to false.
Developers are expected to override it during development.

Also reverts "Work around Mustache problems" (1c1f658) so we're in a
clean state immediately.

[0] https://github.com/facebook/hhvm/pull/5502

Bug: T102941
Change-Id: I729dd34d102879e596428cb07d8cf381071068bb
---
M extension.json
M includes/views/CollectionsListItemCard.php
A includes/views/TemplateParser.php
M includes/views/helpers/Template.php
M templates/CollectionsListItemCard.mustache
A templates/compiled/CardImage.mustache.php
A templates/compiled/CollectionsList.mustache.php
A templates/compiled/CollectionsListItemCard.mustache.php
8 files changed, 204 insertions(+), 39 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Gather 
refs/changes/88/219188/1

diff --git a/extension.json b/extension.json
index 21759b6..c80570e 100644
--- a/extension.json
+++ b/extension.json
@@ -79,6 +79,7 @@
                "Gather\\views\\Pagination": "includes/views/Pagination.php",
                "Gather\\views\\ReportTableRow": 
"includes/views/ReportTableRow.php",
                "Gather\\views\\ReportTable": "includes/views/ReportTable.php",
+               "Gather\\views\\TemplateParser": 
"includes/views/TemplateParser.php",
                "Gather\\views\\helpers\\CSS": "includes/views/helpers/CSS.php",
                "Gather\\views\\helpers\\Template": 
"includes/views/helpers/Template.php",
                "Gather\\SpecialGather": "includes/specials/SpecialGather.php",
@@ -701,7 +702,8 @@
        "config": {
                "GatherShouldShowTutorial": true,
                "GatherAllowPublicWatchlist": false,
-               "GatherEnableBetaFeature": false
+               "GatherEnableBetaFeature": false,
+               "GatherRecompileTemplates": false
        },
        "manifest_version": 1
 }
diff --git a/includes/views/CollectionsListItemCard.php 
b/includes/views/CollectionsListItemCard.php
index 845d3db..f1bdf6b 100644
--- a/includes/views/CollectionsListItemCard.php
+++ b/includes/views/CollectionsListItemCard.php
@@ -78,40 +78,7 @@
                                'class' => helpers\CSS::iconClass( 'profile', 
'before' ),
                                'label' => $owner->getName(),
                        );
-                       // FIXME: Not needed when 
https://phabricator.wikimedia.org/T101918 is fixed.
-                       $ownerElement = Html::element( 'a', array(
-                                       'class' => 'collection-owner ' . 
$defaults['owner']['class'],
-                                       'href' => $defaults['owner']['link'],
-                               ), $defaults['owner']['label'] );
-               } else {
-                       // FIXME: Not needed when 
https://phabricator.wikimedia.org/T101918 is fixed.
-                       $ownerElement = Html::element( 'span', array( 'class' 
=> 'collection-card-following' ),
-                               $this->getPrivacyMsg() );
                }
-               // FIXME: Use Template::render( 'CollectionsListItemCard', 
array_merge( $defaults, $data ) );
-               // as soon as https://phabricator.wikimedia.org/T101918 is 
fixed.
-               return Html::openElement( 'div',
-                       array(
-                               'class' => $defaults['hasImage'] ? 
'collection-card' : 'collection-card without-image',
-                       ) ) .
-                       Html::rawElement( 'a', array(
-                               'href' => $defaults['collectionUrl'],
-                               'class' => 'collection-card-image',
-                       ), $defaults['image'] ) .
-                       Html::openElement( 'div', array(
-                               'class' => 'collection-card-overlay',
-                               'dir' => $defaults['langdir'],
-                       ) ) .
-                       Html::openElement( 'div', array( 'class' => 
'collection-card-title' ) ) .
-                               Html::element( 'a', array(
-                                       'href' => $defaults['collectionUrl'],
-                               ), $defaults['title'] ) .
-                       Html::closeElement( 'div' ) .
-                       $ownerElement .
-                       Html::element( 'span', array(), '•' ) .
-                       Html::element( 'span', array( 'class' => 
'collection-card-article-count' ),
-                               $defaults['articleCountMsg'] ) .
-                       Html::closeElement( 'div' ) .
-                       Html::closeElement( 'div' );
+               return Template::render( 'CollectionsListItemCard', 
array_merge( $defaults, $data ) );
        }
 }
diff --git a/includes/views/TemplateParser.php 
b/includes/views/TemplateParser.php
new file mode 100644
index 0000000..fabf855
--- /dev/null
+++ b/includes/views/TemplateParser.php
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * views\TemplateParser.php
+ */
+
+namespace Gather\views;
+
+use TemplateParser as BaseTemplateParser;
+use LightnCandy;
+use Exception;
+
+/**
+ * See https://phabricator.wikimedia.org/T102941.
+ */
+class TemplateParser extends BaseTemplateParser {
+
+        /**
+        * Constructs the location of the the source Mustache template and
+        * where to store the compiled PHP that will be used to render it.
+         *
+         * @param string $templateName
+         *
+         * @return string[]
+        * @throws \UnexpectedValueException Disallows upwards directory 
traversal via
+        *  $templateName (see TemplateParser#getTemplateFilename).
+         */
+        public function getTemplateFilenames( $templateName ) {
+               $templateFilename = $this->getTemplateFilename( $templateName );
+
+                return array(
+                        'template' => $templateFilename,
+                        'compiled' => 
"{$this->templateDir}/compiled/{$templateName}.mustache.php",
+                );
+        }
+
+        /**
+         * Returns a given template function if found, otherwise throws an 
exception.
+         *
+         * @param string $templateName
+         *
+         * @return \Closure
+         * @throws Exception
+         */
+        public function getTemplate( $templateName ) {
+                if ( isset( $this->renderers[$templateName] ) ) {
+                        return $this->renderers[$templateName];
+                }
+
+                $filenames = $this->getTemplateFilenames( $templateName );
+
+                if ( $this->forceRecompile ) {
+                        $code = $this->compile( file_get_contents( 
$filenames['template'] ), $this->templateDir );
+
+                        if ( !$code ) {
+                                throw new Exception( "Failed to compile 
template '$templateName'." );
+                        }
+
+                        if ( !file_put_contents( $filenames['compiled'], $code 
) ) {
+                                throw new Exception( "Failed to save updated 
compiled template '$templateName'" );
+                        }
+                }
+
+               $this->renderers[$templateName] = $renderer = require 
$filenames['compiled'];
+
+                return $renderer;
+        }
+
+        /**
+         * @param string $code Handlebars code
+         * @param string $templateDir Directory templates are stored in
+         *
+         * @return string PHP code
+         */
+        protected function compile( $code ) {
+                return LightnCandy::compile(
+                        $code,
+                        array(
+                                'flags' => LightnCandy::FLAG_ERROR_EXCEPTION
+                                        | LightnCandy::FLAG_MUSTACHE,
+                        )
+                );
+        }
+}
diff --git a/includes/views/helpers/Template.php 
b/includes/views/helpers/Template.php
index 206f2b3..51808e1 100644
--- a/includes/views/helpers/Template.php
+++ b/includes/views/helpers/Template.php
@@ -6,14 +6,16 @@
 
 namespace Gather\views\helpers;
 
-use TemplateParser;
+use Gather\views\TemplateParser;
 
 class Template {
        /**
         * Easy helper for rendering a template from the Gather extension
         */
        public static function render( $template, $data=array() ) {
-               $templateParser = new TemplateParser( __DIR__ . 
'/../../../templates' );
+               global $wgGatherRecompileTemplates;
+
+               $templateParser = new TemplateParser( __DIR__ . 
'/../../../templates', $wgGatherRecompileTemplates );
                return $templateParser->processTemplate( $template, $data );
        }
 }
diff --git a/templates/CollectionsListItemCard.mustache 
b/templates/CollectionsListItemCard.mustache
index feef5e5..8e04761 100644
--- a/templates/CollectionsListItemCard.mustache
+++ b/templates/CollectionsListItemCard.mustache
@@ -7,12 +7,15 @@
                        <a href='{{collectionUrl}}'>{{title}}</a>
                </div>
                {{#owner}}
-               <a class="{{class}} collection-owner" 
href="{{link}}">{{label}}</a>
+                       <a
+                               class="{{class}} collection-owner"
+                               href="{{link}}">{{label}}</a>
+               <span>•</span>
                {{/owner}}
                {{^owner}}
                <span class='collection-card-following'>{{privacyMsg}}</span>
-               {{/owner}}
                <span>•</span>
+               {{/owner}}
                <span 
class='collection-card-article-count'>{{articleCountMsg}}</span>
        </div>
 </div>
diff --git a/templates/compiled/CardImage.mustache.php 
b/templates/compiled/CardImage.mustache.php
new file mode 100644
index 0000000..c576b60
--- /dev/null
+++ b/templates/compiled/CardImage.mustache.php
@@ -0,0 +1,31 @@
+<?php return function ($in, $debugopt = 1) {
+    $cx = array(
+        'flags' => array(
+            'jstrue' => false,
+            'jsobj' => false,
+            'spvar' => false,
+            'prop' => false,
+            'method' => false,
+            'mustlok' => true,
+            'echo' => false,
+            'debug' => $debugopt,
+        ),
+        'constants' => array(),
+        'helpers' => array(),
+        'blockhelpers' => array(),
+        'hbhelpers' => array(),
+        'partials' => array(),
+        'scopes' => array(),
+        'sp_vars' => array('root' => $in),
+        'lcrun' => 'LCRun3',
+
+    );
+    
+    return '<div
+  class=\'list-thumb
+        '.LCRun3::sec($cx, LCRun3::v($cx, $in, array('wide')), $in, false, 
function($cx, $in) {return 'list-thumb-y';}).'
+        '.((LCRun3::isec($cx, LCRun3::v($cx, $in, array('wide')))) ? 
'list-thumb-x' : '').'\'
+  style=\'background-image: url("'.htmlentities((string)LCRun3::v($cx, $in, 
array('url')), ENT_QUOTES, 'UTF-8').'")\'></div>
+';
+}
+?>
\ No newline at end of file
diff --git a/templates/compiled/CollectionsList.mustache.php 
b/templates/compiled/CollectionsList.mustache.php
new file mode 100644
index 0000000..7020e88
--- /dev/null
+++ b/templates/compiled/CollectionsList.mustache.php
@@ -0,0 +1,33 @@
+<?php return function ($in, $debugopt = 1) {
+    $cx = array(
+        'flags' => array(
+            'jstrue' => false,
+            'jsobj' => false,
+            'spvar' => false,
+            'prop' => false,
+            'method' => false,
+            'mustlok' => true,
+            'echo' => false,
+            'debug' => $debugopt,
+        ),
+        'constants' => array(),
+        'helpers' => array(),
+        'blockhelpers' => array(),
+        'hbhelpers' => array(),
+        'partials' => array(),
+        'scopes' => array(),
+        'sp_vars' => array('root' => $in),
+        'lcrun' => 'LCRun3',
+
+    );
+    
+    return '
+<div class=\'collections-list content view-border-box\' 
data-owner="'.htmlentities((string)LCRun3::v($cx, $in, array('owner')), 
ENT_QUOTES, 'UTF-8').'" data-is-owner=\''.LCRun3::v($cx, $in, 
array('isOwner')).'\'>
+  <div class=\'collection-cards\'>
+    '.LCRun3::v($cx, $in, array('items')).'
+  </div>
+  <div class=\'collection-actions\'></div>
+</div>
+';
+}
+?>
\ No newline at end of file
diff --git a/templates/compiled/CollectionsListItemCard.mustache.php 
b/templates/compiled/CollectionsListItemCard.mustache.php
new file mode 100644
index 0000000..3aaacd6
--- /dev/null
+++ b/templates/compiled/CollectionsListItemCard.mustache.php
@@ -0,0 +1,43 @@
+<?php return function ($in, $debugopt = 1) {
+    $cx = array(
+        'flags' => array(
+            'jstrue' => false,
+            'jsobj' => false,
+            'spvar' => false,
+            'prop' => false,
+            'method' => false,
+            'mustlok' => true,
+            'echo' => false,
+            'debug' => $debugopt,
+        ),
+        'constants' => array(),
+        'helpers' => array(),
+        'blockhelpers' => array(),
+        'hbhelpers' => array(),
+        'partials' => array(),
+        'scopes' => array(),
+        'sp_vars' => array('root' => $in),
+        'lcrun' => 'LCRun3',
+
+    );
+    
+    return '<div class=\'collection-card '.((LCRun3::isec($cx, LCRun3::v($cx, 
$in, array('hasImage')))) ? 'without-image' : '').'\'>
+       <a href=\''.htmlentities((string)LCRun3::v($cx, $in, 
array('collectionUrl')), ENT_QUOTES, 'UTF-8').'\' 
class=\'collection-card-image\'>
+               '.LCRun3::v($cx, $in, array('image')).'
+       </a>
+       <div class=\'collection-card-overlay\' 
dir=\''.htmlentities((string)LCRun3::v($cx, $in, array('langdir')), ENT_QUOTES, 
'UTF-8').'\'>
+               <div class=\'collection-card-title\'>
+                       <a href=\''.htmlentities((string)LCRun3::v($cx, $in, 
array('collectionUrl')), ENT_QUOTES, 
'UTF-8').'\'>'.htmlentities((string)LCRun3::v($cx, $in, array('title')), 
ENT_QUOTES, 'UTF-8').'</a>
+               </div>
+'.LCRun3::sec($cx, LCRun3::v($cx, $in, array('owner')), $in, false, 
function($cx, $in) {return '                       <a
+                               class="'.htmlentities((string)LCRun3::v($cx, 
$in, array('class')), ENT_QUOTES, 'UTF-8').' collection-owner"
+                               href="'.htmlentities((string)LCRun3::v($cx, 
$in, array('link')), ENT_QUOTES, 
'UTF-8').'">'.htmlentities((string)LCRun3::v($cx, $in, array('label')), 
ENT_QUOTES, 'UTF-8').'</a>
+               <span>•</span>
+';}).''.((LCRun3::isec($cx, LCRun3::v($cx, $in, array('owner')))) ? '          
<span class=\'collection-card-following\'>'.htmlentities((string)LCRun3::v($cx, 
$in, array('privacyMsg')), ENT_QUOTES, 'UTF-8').'</span>
+               <span>•</span>
+' : '').'              <span 
class=\'collection-card-article-count\'>'.htmlentities((string)LCRun3::v($cx, 
$in, array('articleCountMsg')), ENT_QUOTES, 'UTF-8').'</span>
+       </div>
+</div>
+';
+}
+?>
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/219188
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I729dd34d102879e596428cb07d8cf381071068bb
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Gather
Gerrit-Branch: master
Gerrit-Owner: Phuedx <g...@samsmith.io>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to