Changes for page Skin Extension Tutorial

Last modified by Vincent Massol on 2023/10/10

<
From version < 36.8 >
edited by slauriere
on 2018/08/24
To version < 37.1 >
edited by Ecaterina Moraru (Valica)
on 2018/09/12
>
Change comment: Changed "Skins eXtensions" to "Skins extensions

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.slauriere
1 +XWiki.evalica
Content
... ... @@ -15,7 +15,7 @@
15 15  
16 16  = Introduction to XWiki Skin Extensions =
17 17  
18 -XWiki Skins eXtensions (abbreviated as **SX**) is a mechanism available in XWiki that allows to customize the layout of your wiki, or just some pages of your wiki, without the need of changing its skin templates and/or stylesheets. For this, the [[Skin Extension plugin>>extensions:Extension.Skin Extension Plugin]] (bundled in all XWiki versions superior to 1.5) provides the ability to send to the browser extra JavaScript and CSS files that are not part of the actual skin of the wiki. The code for these //extensions// is defined in [[wiki objects>>platform:DevGuide.DataModel]].
18 +XWiki Skins extensions (abbreviated as **SX**) is a mechanism available in XWiki that allows to customize the layout of your wiki, or just some pages of your wiki, without the need of changing its skin templates and/or stylesheets. For this, the [[Skin Extension plugin>>extensions:Extension.Skin Extension Plugin]] (bundled in all XWiki versions superior to 1.5) provides the ability to send to the browser extra JavaScript and CSS files that are not part of the actual skin of the wiki. The code for these //extensions// is defined in [[wiki objects>>platform:DevGuide.DataModel]].
19 19  
20 20  To illustrate usage of Skin Extension in XWiki, this tutorial will guide you through the creation of minimal JavaScript and StyleSheet working extensions. Then, will push it further to build a fully functional extension based on Natalie Downe's ##addSizes.js## script.
21 21  
... ... @@ -22,23 +22,23 @@
22 22  A minimal [[JavaScript>>http://en.wikipedia.org/wiki/JavaScript]] and [[CSS>>http://en.wikipedia.org/wiki/CSS]] knowledge is also needed to take full advantage of XWiki Skin Extensions, although expert knowledge in those fields is not needed to follow the tutorial.
23 23  
24 24  {{info}}
25 -If you are interested by the Skin eXtension mechanism itself and its internals, you should read its [[plugin page>>extensions:Extension.Skin Extension Plugin]], and its [[design page on dev.xwiki.org>>dev:Design.Skin Extensions]]. This tutorial does not address this topic. Or, since this is an Open Source project, feel free to {{scm path="xwiki-platform-core/xwiki-platform-skin/xwiki-platform-skin-skinx"}}browse the code{{/scm}}, and [[propose enhancements or improvements>>dev:Community.Contributing]].
25 +If you are interested by the Skin extension mechanism itself and its internals, you should read its [[plugin page>>extensions:Extension.Skin Extension Plugin]], and its [[design page on dev.xwiki.org>>dev:Design.Skin Extensions]]. This tutorial does not address this topic. Or, since this is an Open Source project, feel free to {{scm path="xwiki-platform-core/xwiki-platform-skin/xwiki-platform-skin-skinx"}}browse the code{{/scm}}, and [[propose enhancements or improvements>>dev:Community.Contributing]].
26 26  {{/info}}
27 27  
28 -= My first Skin eXtension =
28 += My first Skin extension =
29 29  
30 -Skin eXtensions are defined as [[XWiki Objects>>platform:DevGuide.DataModel||anchor="HXWikiClasses2CObjects2CandProperties"]]. As a consequence, you can create them from your browser.
30 +Skin extensions are defined as [[XWiki Objects>>platform:DevGuide.DataModel||anchor="HXWikiClasses2CObjects2CandProperties"]]. As a consequence, you can create them from your browser.
31 31  
32 32  Two types of extensions are currently supported:
33 33  
34 -* JavaScript eXtensions (incarnated by XWiki objects of class **XWiki.JavaScriptExtension**), also known as **JSX**
35 -* StyleSheet eXtensions (incarnated by XWiki objects of class **XWiki.StyleSheetExtension**), also known as **SSX**
34 +* JavaScript extensions (incarnated by XWiki objects of class **XWiki.JavaScriptExtension**), also known as **JSX**
35 +* StyleSheet extensions (incarnated by XWiki objects of class **XWiki.StyleSheetExtension**), also known as **SSX**
36 36  
37 -The very first step to create an eXtension is then... to create its object!
37 +The very first step to create an extension is then... to create its object!
38 38  
39 -== Minimal JavaScript eXtension ==
39 +== Minimal JavaScript extension ==
40 40  
41 -=== Creating an eXtension object ===
41 +=== Creating an extension object ===
42 42  
43 43  Point your wiki on the page you want to create your extension in, and edit it with the object editor. The page itself can be any XWiki page - an existing page or a new page. I use in this example the page **XWiki.SkinExt**. From the **New Object** drop-down list of the object editor choose **XWiki.JavaScriptExtension**. Then, click the "Add" button.
44 44  
... ... @@ -46,21 +46,21 @@
46 46  
47 47  Once the page is loaded, you should see your extension object in the object list.
48 48  
49 -=== Writing the eXtension ===
49 +=== Writing the extension ===
50 50  
51 -Now that the object is available, we can just start writing the actual eXtension. For this, we will fill in all the fields of the created object. The first one is the extension name. This is easy! We can just write here **Hello World** (this information is only descriptive, it is not actually used by the SX plugin). The next field name is **code**, and this is where we will write the javascript code we want our extension to execute. This eXtension is supposed to be minimalist, so let's write something very basic here: a traditional greeting alert
51 +Now that the object is available, we can just start writing the actual extension. For this, we will fill in all the fields of the created object. The first one is the extension name. This is easy! We can just write here **Hello World** (this information is only descriptive, it is not actually used by the SX plugin). The next field name is **code**, and this is where we will write the javascript code we want our extension to execute. This extension is supposed to be minimalist, so let's write something very basic here: a traditional greeting alert
52 52  
53 53  {{code}}
54 54  alert("Hello World!");
55 55  {{/code}}
56 56  
57 -Now the next field asks us if we want this extension to be used **Always** or **On Demand**. We will explore all the differences between those two modes later in the tutorial, let us for now just precise we want it **On Demand**, which will force us to call the eXtension explicitly to see it executed.
57 +Now the next field asks us if we want this extension to be used **Always** or **On Demand**. We will explore all the differences between those two modes later in the tutorial, let us for now just precise we want it **On Demand**, which will force us to call the extension explicitly to see it executed.
58 58  
59 -Next thing our eXtension wants to know is if we want its content being parsed or not. This option allows to write **[[velocity code>>platform:DevGuide.Scripting]]**, for example to dynamically generate the javascript code to be executed. We did not write any velocity, so we can just say **No**. We will see later on an example of an extension with parsed content.
59 +Next thing our extension wants to know is if we want its content being parsed or not. This option allows to write **[[velocity code>>platform:DevGuide.Scripting]]**, for example to dynamically generate the javascript code to be executed. We did not write any velocity, so we can just say **No**. We will see later on an example of an extension with parsed content.
60 60  
61 61  Finally, we can precise a **caching policy**, to tune the HTTP headers that will be returned with the generated javascript file. Let's not go wild, and chose the **default** one here
62 62  
63 -That's it ! our eXtension is production-ready ! It should by now look like the following:
63 +That's it ! our extension is production-ready ! It should by now look like the following:
64 64  
65 65  {{image reference="MyFirstJSX.png"/}}
66 66  
... ... @@ -93,9 +93,9 @@
93 93  
94 94  You may also note, that the browser is delivered a minified version of the script given in the object's text. This is good practice for the memory of the browser but may make it hard to debug. Using the extra parameter ##debug=true## is a way to prevent it as explained in the [[Debugging Page>>doc:dev:Community.Debugging]].
95 95  
96 -== Minimal StyleSheet eXtension ==
96 +== Minimal StyleSheet extension ==
97 97  
98 -Good, we wrote our first javascript extension. But, we see things big and we already are looking forward to modify the graphical appearance of wiki pages using those eXtensions. That's what **StyleSheet eXtensions** are meant for. And the good news is that it just works the same as javascript extensions, the only difference being that the code written is **CSS code**.
98 +Good, we wrote our first javascript extension. But, we see things big and we already are looking forward to modify the graphical appearance of wiki pages using those extensions. That's what **StyleSheet extensions** are meant for. And the good news is that it just works the same as javascript extensions, the only difference being that the code written is **CSS code**.
99 99  
100 100  Create a new page named **XWiki.MyFirstStylesheetExtension**. From the **New Object** drop-down list of the object editor choose **XWiki.StyleSheetExtension**. Then, click the "Add" button. We will name it **Blue Background**, give it a **default** cache policy, ask it not to parse the content, and write the following **code**:
101 101  
... ... @@ -111,9 +111,9 @@
111 111  
112 112  == Put all together ==
113 113  
114 -Now let's try something new with this eXtension. Instead of loading it "On Demand", we can ask to have it used **"Always on this wiki"**. For this to happen however, you need to save the extension document with [[programming rights>>platform:AdminGuide.Access Rights||anchor="HSpecialpermissions"]].
114 +Now let's try something new with this extension. Instead of loading it "On Demand", we can ask to have it used **"Always on this wiki"**. For this to happen however, you need to save the extension document with [[programming rights>>platform:AdminGuide.Access Rights||anchor="HSpecialpermissions"]].
115 115  
116 -Your StyleSheet eXtension should now look like the following:
116 +Your StyleSheet extension should now look like the following:
117 117  
118 118  {{image reference="MyFirstSSX.png"/}}
119 119  
... ... @@ -135,9 +135,9 @@
135 135  A document can have as many **ssx** or **jsx** object as it needs, but a skin extension is identified by the name of the document, so in the end an extension is a document. The content of a skin extension is the concatenation of the objects in that document, so it's impossible to write two different extensions in a single document, only different parts of the same extension.
136 136  {{/info}}
137 137  
138 -= Real-world eXtension with addSizes.js =
138 += Real-world extension with addSizes.js =
139 139  
140 -Let's now go further with this idea, and build a complete extension that will dynamically add the file type and size next to certain links that are present in a wiki document. This extension will make usage of the **addSizes.js** script published by Natalie Downe. This Javascript snippet itself relies on **json-head**, a Google App Engine application by Simon Willison which //"provides a JSON-P API for running [[HEAD requests>>http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4]] against an arbitrary URL"//. **addSizes.js** consumes this service to dynamically add the file type and size next to links in HTML documents. And this is what we will do in our new eXtension, using the aforementioned script and service.
140 +Let's now go further with this idea, and build a complete extension that will dynamically add the file type and size next to certain links that are present in a wiki document. This extension will make usage of the **addSizes.js** script published by Natalie Downe. This Javascript snippet itself relies on **json-head**, a Google App Engine application by Simon Willison which //"provides a JSON-P API for running [[HEAD requests>>http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4]] against an arbitrary URL"//. **addSizes.js** consumes this service to dynamically add the file type and size next to links in HTML documents. And this is what we will do in our new extension, using the aforementioned script and service.
141 141  
142 142  Our new skin extension will be composed of a javascript and a stylesheet extension. We will hold the two objects in the same wiki page, namely **XWiki.AddSizesExtension**.
143 143  
... ... @@ -194,7 +194,7 @@
194 194  // addSizes was written by Natalie Downe
195 195  // http://natbat.net/2008/Aug/27/addSizes/
196 196  // ported to prototype.js by Jerome Velociter, and adapted to XWiki for this tutorial
197 -
197 +
198 198  // Copyright (c) 2008, Natalie Downe under the BSD license
199 199  // http://www.opensource.org/licenses/bsd-license.php
200 200  
... ... @@ -214,7 +214,7 @@
214 214   }
215 215   if(json.ok && content_length) {
216 216   var length = parseInt(content_length, 10);
217 -
217 +
218 218   // divide the length into its largest unit
219 219   var units = [
220 220   [1024 * 1024 * 1024, 'GB'],
... ... @@ -222,9 +222,9 @@
222 222   [1024, 'KB'],
223 223   [1, 'bytes']
224 224   ];
225 -
225 +
226 226   for(var i = 0; i < units.length; i++){
227 -
227 +
228 228   var unitSize = units[i][0];
229 229   var unitText = units[i][1];
230 230   if (length >= unitSize) {
... ... @@ -234,8 +234,8 @@
234 234   var lengthUnits = unitText;
235 235   break;
236 236   }
237 - }
238 -
237 + }
238 +
239 239   // insert the text in a span directly after the link and add a class to the link
240 240   Element.insert(link, {'after':
241 241   ' <span class="filesize">(' + length + ' ' + lengthUnits + ')</span>'});
... ... @@ -284,7 +284,7 @@
284 284  
285 285  When asked to serve the CSS file, XWiki will evaluate this code using its Velocity Rendering engine, and will return a file that contains pure CSS code!
286 286  
287 -== Testing the final eXtension ==
287 +== Testing the final extension ==
288 288  
289 289  Ok, it's time for us to see the whole thing in action! The snippet below is intended to showcase the extension on its own wiki page. It request to the **jsx** and **ssx** plugins the use of the contained objects, and then give an example of all the supported links.
290 290  

Get Connected