Merge "SpecialMovepage: Convert form to use OOUI controls"
[lhc/web/wiklou.git] / resources / src / mediawiki / mediawiki.template.js
1 /**
2 * @class mw.template
3 * @singleton
4 */
5 ( function ( mw, $ ) {
6 var compiledTemplates = {},
7 compilers = {};
8
9 mw.template = {
10 /**
11 * Register a new compiler and template.
12 *
13 * @param {string} name of compiler. Should also match with any file extensions of templates that want to use it.
14 * @param {Function} compiler which must implement a compile function
15 */
16 registerCompiler: function ( name, compiler ) {
17 if ( !compiler.compile ) {
18 throw new Error( 'Compiler must implement compile method.' );
19 }
20 compilers[ name ] = compiler;
21 },
22
23 /**
24 * Get the name of the compiler associated with a template based on its name.
25 *
26 * @param {string} templateName Name of template (including file suffix)
27 * @return {String} Name of compiler
28 */
29 getCompilerName: function ( templateName ) {
30 var templateParts = templateName.split( '.' );
31
32 if ( templateParts.length < 2 ) {
33 throw new Error( 'Unable to identify compiler. Template name must have a suffix.' );
34 }
35 return templateParts[ templateParts.length - 1 ];
36 },
37
38 /**
39 * Get the compiler for a given compiler name.
40 *
41 * @param {string} compilerName Name of the compiler
42 * @return {Object} The compiler associated with that name
43 */
44 getCompiler: function ( compilerName ) {
45 var compiler = compilers[ compilerName ];
46 if ( !compiler ) {
47 throw new Error( 'Unknown compiler ' + compilerName );
48 }
49 return compiler;
50 },
51
52 /**
53 * Register a template associated with a module.
54 *
55 * Compiles the newly added template based on the suffix in its name.
56 *
57 * @param {string} moduleName Name of ResourceLoader module to get the template from
58 * @param {string} templateName Name of template to add including file extension
59 * @param {string} templateBody Contents of a template (e.g. html markup)
60 * @return {Function} Compiled template
61 */
62 add: function ( moduleName, templateName, templateBody ) {
63 var compiledTemplate,
64 compilerName = this.getCompilerName( templateName );
65
66 if ( !compiledTemplates[ moduleName ] ) {
67 compiledTemplates[ moduleName ] = {};
68 }
69
70 compiledTemplate = this.compile( templateBody, compilerName );
71 compiledTemplates[ moduleName ][ templateName ] = compiledTemplate;
72 return compiledTemplate;
73 },
74
75 /**
76 * Retrieve a template by module and template name.
77 *
78 * @param {string} moduleName Name of the module to retrieve the template from
79 * @param {string} templateName Name of template to be retrieved
80 * @return {Object} Compiled template
81 */
82 get: function ( moduleName, templateName ) {
83 var moduleTemplates, compiledTemplate;
84
85 // Check if the template has already been compiled, compile it if not
86 if ( !compiledTemplates[ moduleName ] || !compiledTemplates[ moduleName ][ templateName ] ) {
87 moduleTemplates = mw.templates.get( moduleName );
88 if ( !moduleTemplates || !moduleTemplates[ templateName ] ) {
89 throw new Error( 'Template ' + templateName + ' not found in module ' + moduleName );
90 }
91
92 // Add compiled version
93 compiledTemplate = this.add( moduleName, templateName, moduleTemplates[ templateName ] );
94 } else {
95 compiledTemplate = compiledTemplates[ moduleName ][ templateName ];
96 }
97 return compiledTemplate;
98 },
99
100 /**
101 * Wrap our template engine of choice.
102 *
103 * @param {string} templateBody Template body
104 * @param {string} compilerName The name of a registered compiler
105 * @return {Object} Template interface
106 */
107 compile: function ( templateBody, compilerName ) {
108 return this.getCompiler( compilerName ).compile( templateBody );
109 }
110 };
111
112 // Register basic html compiler
113 mw.template.registerCompiler( 'html', {
114 compile: function ( src ) {
115 return {
116 render: function () {
117 return $( $.parseHTML( $.trim( src ) ) );
118 }
119 };
120 }
121 } );
122
123 }( mediaWiki, jQuery ) );