resourceloader: Add template compiler for Mustache JS
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoaderFileModule.php
index 7bbc9bb..a46c931 100644 (file)
@@ -34,6 +34,9 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        /** @var string Remote base path, see __construct() */
        protected $remoteBasePath = '';
 
+       /** @var array Saves a list of the templates named by the modules. */
+       protected $templates = array();
+
        /**
         * @var array List of paths to JavaScript files to always include
         * @par Usage:
@@ -199,6 +202,9 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *         'loaderScripts' => [file path string or array of file path strings],
         *         // Modules which must be loaded before this module
         *         'dependencies' => [module name string or array of module name strings],
+        *         'templates' => array(
+        *             [template alias with file.ext] => [file path to a template file],
+        *         ),
         *         // Styles to always load
         *         'styles' => [file path string or array of file path strings],
         *         // Styles to include in specific skin contexts
@@ -223,6 +229,8 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                $localBasePath = null,
                $remoteBasePath = null
        ) {
+               // Flag to decide whether to automagically add the mediawiki.template module
+               $hasTemplates = false;
                // localBasePath and remoteBasePath both have unbelievably long fallback chains
                // and need to be handled separately.
                list( $this->localBasePath, $this->remoteBasePath ) =
@@ -238,6 +246,10 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                                case 'styles':
                                        $this->{$member} = (array)$option;
                                        break;
+                               case 'templates':
+                                       $hasTemplates = true;
+                                       $this->{$member} = (array)$option;
+                                       break;
                                // Collated lists of file paths
                                case 'languageScripts':
                                case 'skinScripts':
@@ -281,6 +293,21 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                                        break;
                        }
                }
+               if ( $hasTemplates ) {
+                       $this->dependencies[] = 'mediawiki.template';
+                       // Ensure relevant template compiler module gets loaded
+                       foreach ( $this->templates as $alias => $templatePath ) {
+                               if ( is_int( $alias ) ) {
+                                       $alias = $templatePath;
+                               }
+                               $suffix = explode( '.', $alias );
+                               $suffix = end( $suffix );
+                               $compilerModule = 'mediawiki.template.' . $suffix;
+                               if ( $suffix !== 'html' && !in_array( $compilerModule, $this->dependencies ) ) {
+                                       $this->dependencies[] = $compilerModule;
+                               }
+                       }
+               }
        }
 
        /**
@@ -468,8 +495,8 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
 
        /**
         * Get the skip function.
-        *
-        * @return string|null
+        * @return null|string
+        * @throws MWException
         */
        public function getSkipFunction() {
                if ( !$this->skipFunction ) {
@@ -512,7 +539,6 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                if ( isset( $this->modifiedTime[$context->getHash()] ) ) {
                        return $this->modifiedTime[$context->getHash()];
                }
-               wfProfileIn( __METHOD__ );
 
                $files = array();
 
@@ -535,6 +561,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                $files = array_merge(
                        $files,
                        $this->scripts,
+                       $this->templates,
                        $context->getDebug() ? $this->debugScripts : array(),
                        $this->getLanguageScripts( $context->getLanguage() ),
                        self::tryForKey( $this->skinScripts, $context->getSkin(), 'default' ),
@@ -551,13 +578,10 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                // giving max() an empty array
                if ( count( $files ) === 0 ) {
                        $this->modifiedTime[$context->getHash()] = 1;
-                       wfProfileOut( __METHOD__ );
                        return $this->modifiedTime[$context->getHash()];
                }
 
-               wfProfileIn( __METHOD__ . '-filemtime' );
                $filesMtime = max( array_map( array( __CLASS__, 'safeFilemtime' ), $files ) );
-               wfProfileOut( __METHOD__ . '-filemtime' );
 
                $this->modifiedTime[$context->getHash()] = max(
                        $filesMtime,
@@ -565,7 +589,6 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        $this->getDefinitionMtime( $context )
                );
 
-               wfProfileOut( __METHOD__ );
                return $this->modifiedTime[$context->getHash()];
        }
 
@@ -576,9 +599,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @return array
         */
        public function getDefinitionSummary( ResourceLoaderContext $context ) {
-               $summary = array(
-                       'class' => get_class( $this ),
-               );
+               $summary = parent::getDefinitionSummary( $context );
                foreach ( array(
                        'scripts',
                        'debugScripts',
@@ -590,6 +611,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        'dependencies',
                        'messages',
                        'targets',
+                       'templates',
                        'group',
                        'position',
                        'skipFunction',
@@ -959,4 +981,30 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        protected function getLessCompiler( ResourceLoaderContext $context = null ) {
                return ResourceLoader::getLessCompiler( $this->getConfig() );
        }
+
+       /**
+        * Takes named templates by the module and returns an array mapping.
+        * @return array of templates mapping template alias to content
+        * @throws MWException
+        */
+       public function getTemplates() {
+               $templates = array();
+
+               foreach ( $this->templates as $alias => $templatePath ) {
+                       // Alias is optional
+                       if ( is_int( $alias ) ) {
+                               $alias = $templatePath;
+                       }
+                       $localPath = $this->getLocalPath( $templatePath );
+                       if ( file_exists( $localPath ) ) {
+                               $content = file_get_contents( $localPath );
+                               $templates[$alias] = $content;
+                       } else {
+                               $msg = __METHOD__ . ": template file not found: \"$localPath\"";
+                               wfDebugLog( 'resourceloader', $msg );
+                               throw new MWException( $msg );
+                       }
+               }
+               return $templates;
+       }
 }