Client side scripting can greatly improve the user experience of a web site and particularly a web application. So you are encouraged to add client side scripting to your plugin, wherever that makes sense. All client side scripting for CMSimple_XH should be done in JavaScript. Note that you can count on JavaScript being enabled for the back-end; for front-end scripting, you should not rely on JavaScript being enabled in the visitors browser, so prefer to use JavaScript as progressive enhancement and provide a graceful degredation for user agents, which ignore JavaScript.
When writing JavaScript for a CMSimple_XH plugin, the “golden rule” applies also:
So prefix all you global identifiers with a unique string (preferably the plugin name). As JavaScript offers the possibility to define objects ad hoc, you can make use of the namespace pattern, e.g. (simplified):
var myplugin = { variable = "some value", doThis = function() {...}, doThat = function() {...} }
Usually you'll want to embed your JavaScript code in the produced document with a “script” element; either directly in the document or by including a separate JS file 1). The latter has some general advantages (particularly it is not necessary to take care of escaping the JavaScript), but sometimes the former is more appropriate. In any way you should not use the “language” attribute, but instead the “type” attribute:
<script type="text/javascript" ...>...</script>
If you're going to embed the JavaScript directly, you should precautiously 2) cater for XML processing of the XHTML by declaring the code as CDATA section:
<script type="text/javascript">/* <![CDATA[ */ ... /* ]]> */</script>
To actually put the “script” element in the generated output, you often can simply do it the same way as with (X)HTML, i.e. as part of the return value of a plugin function or directly by appending to the global $o (CMSimple_XH's output buffer for the content area) 3). For performance reasons it's often reasonable to write “script” elements at the end of the “body” element. Since CMSimple_XH 1.5.4 there's the global variable $bjs, which you can extend with your “script” element, to do so. Sometimes it's necessary to write your “script” element to the “head” element of the document; therefore you can use the global $hjs. Note that appending to $hjs doesn't have the desired effect, if done from the template, after the funtion head() was called.
To trigger the actual execution of the JavaScript code, there are basically three possibilities:
(1) is useful for initialization; just let some code execute in the global scope or, often preferable, use a anonymous function expression that is called immediately after creation:
(function() { doThis(); doThat(); })()
(2) is a simple way to handle an event. You can output the required code directly with the (X)HTML:
<form ... onsubmit="return validateInput()">
In this case you have to be careful with the quotes when using more complex expressions. Somewhat special is the onload attribute of the “body” element, which can be used to trigger execution of JavaScript code after the complete DOM is built. To add code to this attribute, you can append it to the global $onload:
$onload .= 'doSomething();';
Note the semicolon, which is important if another plugin appends to $onload after yourself. And note, that appending to $onload has not the desired effect, when done from the template after the opening “body” tag was processed.
(3) is the most flexible and powerful mechanism. Unfortunately that's a little bit complicated, as IE < 9 doesn't implement the standardized EventListener interface, so you'll have to provide a fallback:
if (typeof element.addEventListener != "undefined") { // for standard conforming browsers element.addEventListener("click", doSomething(), false); } else if (typeof element.attachEvent != "undefined") { // for IE < 9 element.attachEvent("onclick", doSomething()); } else { // handle other browsers, if reasonable doSomethingElse(); }
JSON (JavaScript Object Notation) is a universal data exchange format, which is built from a subset of JavaScript. Therefore it is particularly well suited to pass values from PHP to JavaScript and vice versa.
Of course it's possible to construct a JSON string “manually”, but there are several issues with regard to the necessary escaping. All this is handled automatically by json_encode(), which converts an arbitrary PHP value to a JSON string. json_encode()/json_decode() are bundled with PHP since PHP 5.2; if you want your plugins to be compatible with older versions, you can use the fallback implementations of the CMBUtils.
A very useful feature of modern JavaScript is the XMLHttpRequest (XHR for short), which is commonly known as AJAX (asynchronous JavaScript and XML). Here's not the place to go into detail what you can do with XHR, and how to do it generally, though; there's plenty of information available on the web. However, a note about how to use it with CMSimple_XH seems to be appropriate:
That means that you may avoid setting up a seperate file, which handles the request(s), but instead you may call CMSimple_XH's index.php passing an appropriate GET resp. POST parameter, that triggers your plugin to handle the request. This has the big advantage, that the full CMSimple_XH API is available, so you don't have to construct some paths yourself or even have to pass other values in a session variable for example. Note, that in this case you'll want to terminate CMSimple_XH after you have sent the response. An example:
if (isset($_GET['myplugin_xhr'])) { // handle XHR of myplugin while (ob_get_level()) { // purge existing output buffers ob_end_clean(); } header('Content-Type: text/plain'); // set the appropriate Content-Type header echo $plugin_tx['myplugin']['response']; // sent the response exit; // prevent further processing }
To refer to CMSimple_XH's index.php you can simply use the global $sn.
You may want to use a JavaScript library/framework to ease writing the code. Basically that's fine and you may choose whichever library you prefer. But note, that there's a potential problem: several of these libraries use the $ as important identifier (e.g. jQuery, Mootools, Prototype), so this may clash, if more than one library is used on a single CMSimple page. As jQuery is the most prominent of these libraries nowadays, it was decided to endorse jQuery as official JavaScript library for CMSimple, which seems the only way to reduce the probability of clashes. To avoid problems when more than one plugin is including jQuery in combination with a jQuery plugin, jQuery4CMSimple was developed. This CMSimple_XH plugin offers a simple API, which will take care, that jQuery, jQueryUI and jQuery plugins will be included at most once. How to use jQuery4CMSimple is described in its manual.
« Data Storage | Security »