Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Web Development

1797 Articles
article-image-mootool-understanding-foundational-basics
Packt
01 Aug 2011
9 min read
Save for later

MooTool: Understanding the Foundational Basics

Packt
01 Aug 2011
9 min read
  MooTools 1.3 Cookbook Over 110 highly effective recipes to turbo-charge the user interface of any web-enabled Internet application and web page MooTroduction MooTools was conceived by Valerio Proietti and copy written under MIT License in 2006. We send a great round of roaring applause to Valerio for creating the Moo.FX (My Object Oriented Effects) plugin for Prototype, a JavaScript abstraction library. That work gave life to an arguably more effects-oriented (and highly extensible) abstraction layer of its own: MooTools (My Object Oriented Tools).   Knowing our MooTools version This recipe is an introduction to the different MooTools versions and how to be sure we are coding in the right version. Getting ready Not all are equal nor are backwards compatible! The biggest switch in compatibility came between MooTools 1.1 and MooTools 1.2. This minor version change caused clamor in the community given the rather major changes included. In our experience, we find that 1.2 and 1.3 MooTool scripts play well together while 1.0 and 1.1 scripts tend to be agreeable as well. However, Moo's popularity spiked with version 1.1, and well-used scripts written with 1.0, like MooTabs, were upgraded to 1.1 when released. The exact note in Google Libraries for the version difference between 1.1 and 1.2 reads: Since 1.1 versions are not compatible with 1.2 versions, specifying version "1" will map to the latest 1.1 version (currently 1.1.2). MooTools 1.1.1 has inline comments, which cause the uncompressed version to be about 180% larger than version 1.2.5 and 130% larger than the 1.3.0 release. When compressed, with YUI compression, 1.1 and 1.2 weigh in at about 65K while 1.3.0 with the CSS3 selectors is a modest 85K. In the code snippets, the compressed versions are denoted with a c.js file ending. Two great additions in 1.3.0 that account for most of the difference in size from 1.2.5 are Slick.Parser and Slick.Finder. We may not need CSS3 parsing; so we may download the MooTools Core with only the particular class or classes we need. Browse http://mootools.net/core/ and pick and choose the classes needed for the project. We should note that the best practice is to download all modules during development and pare down to what is needed when taking an application into production. When we are more concerned with functionality than we are with performance and have routines that require backwards compatibility with MooTools 1.1, we can download the 1.2.5 version with the 1.1 classes from the MooTools download page at http://mootools.net/download. The latest MooTools version as of authoring is 1.3.0. All scripts within this cookbook are built and tested using MooTools version 1.3.0 as hosted by Google Libraries. How to do it... This is the basic HTML framework within which all recipes will be launched. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title>MooTools Recipes</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> Note that the portion above is necessary but is not included in the other recipes to save space. Please do always include a DOCTYPE, and opening HTML, HEAD, TITLE, and META tag for the HTTP-EQUIV and CONTENT. <script type="text/javascript" src="mootools-1.3.0.js"></script> </head> <body> <noscript>Your Browser has JavaScript Disabled. Please use industry best practices for coding in JavaScript; letting users know they are missing out is crucial!</noscript> <script type="text/javascript"> // best practice: ALWAYS include a NOSCRIPT tag! var mooversion = MooTools.version; var msg = 'version: '+mooversion; document.write(msg); // just for fun: var question = 'Use MooTools version '+msg+'?'; var yes = 'It is as you have requested!'; var no = "Please change the mootools source attribute in HTML->head->script."; // give 'em ham alert((confirm(question)?yes:no)); </script> </body> </html> How it works... Inclusion of external libraries like MooTools is usually handled within the HEAD element of the HTML document. The NOSCRIPT tag will only be read by browsers that have their JavaScript disabled. The SCRIPT tag may be placed directly within the layout of the page. There's more... Using the XHTML doctype (or any doctype for that matter) allows your HTML to validate, helps browsers parse your pages faster, and helps the Dynamic Object Model (DOM) behave consistently. When our HTML does not validate, our JavaScript errors will be more random and difficult to solve. Many seasoned developers have settled upon a favorite doctype. This allows them to become familiar with the ad-nauseam of cross browser oddities associated with that particular doctype. To further delve into doctypes, quirksmode, and other HTML specification esoterica, the heavily trafficked http://www.quirksmode.org/css/quirksmode.html provides an easy-to-follow and complete discourse.   Finding MooTools documentation both new and old Browsing http://mootools.net/docs/core will afford us the opportunity to use the version of our choice. The 1.2/1.3 demonstrations at the time of writing are expanding nicely. Tabs in the demonstrations at http://mootools.net/demos display each of the important elements of the demonstration. (Move the mouse over the image to enlarge.) MooTools had a major split at the minor revision number of 1.1. If working on a legacy project that still implements the deprecated MooTools version 1.1, take a shortcut to http://docs111.mootools.net. Copying the demonstrations line-for-line, without studying them to see how they work, may afford our project the opportunity to become malicious code.   Using Google Library's MooTools scripts Let Google maintain the core files and provide the bandwidth to serve them. Getting ready Google is leading the way in helping MooTools developers save time in the arenas of development, maintenance, and hosting by working together with the MooTools developers to host and deliver compressed and uncompressed versions of MooTools to our website visitors. Hosting on their servers eliminates the resources required to host, bandwidth required to deliver, and developer time required to maintain the requested, fully patched, and up-to-date version. Usually we link to a minor version of a library to prevent major version changes that could cause unexpected behavior in our production code. Google API keys that are required in the documentation to use Google Library can be easily and quickly obtained at: http://code.google.com/apis/libraries/devguide.html#sign_up_for_an_api_key. How to do it... Once you have the API Key, use the script tag method to include MooTools. For more information on loading the JavaScript API see http://code.google.com/apis/libraries/devguide.html#load_the_javascript_api_and_ajax_search_module. <!--script type="text/javascript" src="mootools-1.3.0.js"> </script--> <!--we've got ours commented out so that we can use google's here:--> <script src="https://www.google.com/jsapi?key=OUR-KEY-HERE" type="text/javascript"></script> // the full src path is truncated for display here <script src="https://ajax.googleapis.com/... /mootools-yui-compressed.js" type="text/javascript"></script> </head> <body> <noscript>JavaScript is disabled.</noscript> <script type="text/javascript"> var mooversion = MooTools.version; var msg = 'MooTools version: '+mooversion+' from Google'; // show the msg in two different ways (just because) document.write(msg); alert(msg); </script> Using google.load(), which is available to us when we include the Google Library API, we can make the inclusion code a bit more readable. See the line below that includes the string jsapi?key=. We replace OUR-KEY-HERE with our API key, which is tied to our domain name so Google can contact us if they detect a problem: <!--script type="text/javascript" src="mootools-1.3.0.js"> </script--> <!--we've got ours commented out so that we can use google's here:--> <script src="https://www.google.com/jsapi?key=OUR-KEY-HERE" type="text/javascript"></script> <script type="text/javascript"> google.load("mootools", "1.2.5"); </script> </head> <body> <noscript>JavaScript is disabled.</noscript> <script type="text/javascript"> var mooversion = MooTools.version; var msg = 'MooTools version: '+mooversion+' from Google'; // show the msg in two different ways (just because) document.write(msg); alert(msg); </script> How it works... There are several competing factors that go into the decision to use a direct load or dynamic load via google.load(): Are we loading more than one library? Are our visitors using other sites that include this dynamic load? Can our page benefit from parallel loading? Do we need to provide a secure environment? There's more... If we are only loading one library, a direct load or local load will almost assuredly benchmark faster than a dynamic load. However, this can be untrue when browser accelerator techniques, most specifically browser caching, come into play. If our web server is sending no-cache headers, then dynamic load, or even direct load, as opposed to a local load, will allow the browser to cache the Google code and reduce our page load time. If our page is making a number of requests to our web server, it may be possible to have the browser waiting on a response from the server. In this instance, parallel loading from another website can allow those requests that the browser can handle in parallel to continue during such a delay. We need to also take a look at how secure websites function with non-secure, external includes. Many of us are familiar with the errors that can occur when a secure website is loaded with an external (or internal) resource that is not provided via http. The browser can pop up an alert message that can be very concerning and lose the confidence of our visitors. Also, it is common to have some sort of negative indicator in the address bar or in the status bar that alerts visitors that not all resources on the page are secure. Avoid mixing http and https resources; if using a secure site, opt for a local load of MooTools or use Google Library over HTTPS.  
Read more
  • 0
  • 1
  • 2248

article-image-creating-enterprise-portal-oracle-webcenter-11g-ps3
Packt
01 Aug 2011
9 min read
Save for later

Creating an Enterprise Portal with Oracle WebCenter 11g PS3

Packt
01 Aug 2011
9 min read
  Oracle WebCenter 11g PS3 Administration Cookbook Over 100 advanced recipes to secure, support, manage, and administer Oracle WebCenter         Introduction An enterprise portal is a framework that allows users to interact with different applications in a secure way. There is a single point of entry and the security to the composite applications is transparent for the user. Each user should be able to create their own view on the portal. A portal is highly customizable, which means that most of the work will be done at runtime. An administrator should be able to create and manage pages, users, roles, and so on. Users can choose whatever content they want to see on their pages so they can personalize the portal to their needs. In this article, you will learn some basics about the WebCenter Portal application. Later chapters will go into further details on most of the subjects covered in this chapter. It is intended as an introduction to the WebCenter Portal. Preparing JDeveloper for WebCenter When you want to build WebCenter portals, JDeveloper is the preferred IDE. JDeveloper has a lot of built-in features that will help us to build rich enterprise applications. It has a lot of wizards that can help in building the complex configuration files. Getting ready You will need to install JDeveloper before you can start with this recipe. JDeveloper is the IDE from Oracle and can be downloaded from the following link: http://www.oracle.com/technetwork/developer-tools/jdev/downloads/index.html. You will need to download JDeveloper 11.1.1.5 Studio Edition and not JDeveloper 11.1.2 because that version is not compatible with WebCenter yet. This edition is the full-blown edition with all the bells and whistles. It has all the libraries for building an ADF application, which is the basis for a WebCenter application. How to do it... Open JDeveloper that was installed. Choose Default Role. From JDeveloper, open the Help menu and select Check for updates. Click Next on the welcome screen. Make sure all the Update Centers are selected and press Next. In the available Updates, enter WebCenter and select all the found updates. Press Next to start the download. After the download is finished, you will need to restart JDeveloper. You can check if the updates have been installed by opening the About window from the Help menu. Select the Extensions tab and scroll down to the WebCenter extensions. You should be able to see them: How it works... When you first open JDeveloper, you first need to select a role. The role determines the functionality you have in JDeveloper. When you select the default role, all the functionality will be available. By installing the WebCenter extensions, you are installing all the necessary jar files containing the libraries for the WebCenter framework. JDeveloper will have three additional application templates: Portlet Producer Application: This template allows you to create a producer based upon the new JSR286 standard. WebCenter Portal Application: Template that will create a preconfigured portal with ADF and WebCenter technology. WebCenter Spaces Taskflow Customizations: This application is configured for customizing the applications and services taskflows used with the WebCenter Spaces Application. The extensions also include the taskflows and data controls for each of the WebCenter services that we will be integrating in our portal. Creating a WebCenter portal In this release of WebCenter, we can easily build enterprise portals by using the WebCenter Portal application template in JDeveloper. This template contains a preconfigured portal that we can modify to our needs. It has basic administration pages and security. Getting ready For this recipe, you need the latest version of JDeveloper with the WebCenter extensions installed, which is described in the previous recipe. How to do it... Select New from the File menu. Select Application in the General section on the left-hand side. Select WebCenter Portal Application from the list on the right. Press OK. The Create WebCenter Portal Application dialog will open. In the dialog, you will need to complete a few steps in order to create the portal application: Application Name: Specify the application name, directory, and application package prefix. Project Name: Specify the name and directory of the portal project. At this stage, you can also add additional libraries to the project. Project Java Settings: Specify the default package, java source, and output directory. Project WebCenter settings: With this step, you can request to build a default portal environment. When you disable the Configure the application with standard Portal features checkbox, you will have an empty project with only the reference to the WebCenter libraries, but no default portal will be configured. You can also let JDeveloper create a special test-role, so you can test your application. Press the Finish button to create the application. You can test the portal without needing to develop anything. Just start the integrated WebLogic server, right-click the portal project, and select Run from the context menu. When you start the WebLogic server for the first time, it can take a few minutes. This is because JDeveloper will create the WebLogic domain for the integrated WebLogic server. Because we have installed the WebCenter extensions, JDeveloper will also extend the domain with the WebCenter libraries. How it works... When the portal has been started, you will see a single page, which is the Home page that contains a login form at the top right corner: When you log in with the default WebLogic user, you should have complete administration rights. The default user of the integrated WebLogic server is weblogic with password weblogic1. When logged in, you should see an Administration link. This links to the Administration Console where you can manage the resources of your portal like pages, resource catalogs, navigations, and so on. In the Administration Console you have five tabs: Resources: In this tab, you manage all the resources of your portal. The resources are divided into three parts: Structure: In the structure, you manage the resources about the structure of your portal, such as pages, templates, navigations, and resource catalogs. Look and Layout: In the look and layout part, you manage things like skins, styles, templates for the content presenter, and mashup styles. Mashups: Mashups are taskflows created during runtime. You can also manage data controls in the mashup section. Services: In the services tab, you can manage the services that are configured for your portal. Security: In the security tab, you can add users or roles and define their access to the portal application. Configuration: In this tab, you can configure default settings for the portal like the default page template, default navigation, default resource catalog, and default skin. Propagation: This tab is only visible when you create a specific URL connection. From this tab, you can propagate changes from your staging environment to your production environment. There's more... The WebCenter Portal application will create a preconfigured portal for us. It has a basic structure and page navigation to build complex portals. JDeveloper has created a lot of files for us. Here is an overview of the most important files created for us by JDeveloper: Templates The default portal has two page templates. They can be found in the Web Content/oracle/Webcenter/portalapp/pagetemplates folder: pageTemplate_globe.jspx: This is the default template used for a page pageTemplate_swooshy.jspx: This is the same template as the globe template, but with another header image You can of course create your own templates. Pages JDeveloper will create four pages for us. These can be found in the Web Content/oracle/Webcenter/portalapp/pages folder: error.jspx: This page looks like the login page and is designed to show error messages upon login. home.jspx: This is an empty page that uses the globe template. login.jspx: This is the login page. It is also based upon the globe template. Resource catalogs By default, JDeveloper will create a default resource catalog. This can be found in the Web Content/oracle/Webcenter/portalapp/catalogs folder. In this folder, you will find the default-catalog.xml file which represents the resource catalog. When you open this file, you will notice that JDeveloper has a design view for this file. This way it is easier to manage and edit the catalog without knowing the underlying XML. Another file in the catalogs folder is the catalog-registry.xml. This is the set of components that the user can use when creating a resource catalog at runtime. Navigations By using navigations, you can allow users to find content on different pages, taskflow, or even external pages. By defining different navigation, you allow users to have a personalized navigation that fits their needs. By default, you will find one navigation model in the Web content/oracle/Webcenter/portalapp/navigations folder: default-navigation-model.xml. It contains the page hierarchy and a link to the administration page. This model is not used in the template, but it is there as an example. You can of course use this model and modify it, or you can create your own models. You will also find the navigation-registry.xml. This file contains the items that can be used to create a navigation model at runtime. Page hierarchy With the page hierarchy, you can create parent-child relationships between pages. It allows you to create multi-level navigation of existing pages. Within the page hierarchy, you can set the security of each node. You are able to define if a child node inherits the security from its parent or it has its own security. By default, JDeveloper will create the pages.xml page hierarchy in the Web Content/oracle/Webcenter/portalapp/pagehierarchy folder. This hierarchy has only one node, being the Home page.
Read more
  • 0
  • 0
  • 1776

article-image-integrating-phplist-2-wordpress
Packt
29 Jul 2011
3 min read
Save for later

Integrating phpList 2 with WordPress

Packt
29 Jul 2011
3 min read
Prerequisites for this WordPress tutorial For this tutorial, we'll make the following assumptions: We already have a working instance of WordPress (version 3.x) Our phpList site is accessible through HTTP / HTTPS from our WordPress site Installing and configuring the phpList Integration plugin Download the latest version of Jesse Heap's phpList Integration plugin from http://wordpress.org/extend/plugins/phplist-form-integration/, unpack it, and upload the contents to your wp-content/plugins/ directory in WordPress. Activate the plugin from within your WordPress dashboard: Under the Settings menu, click on the new PHPlist link to configure the plugin: General Settings Under the General Settings heading, enter the URL to your phpList installation, as well as an admin username/password combination. Enter the ID and name of at least one list that you want to allow your WordPress users to subscribe to: Why does the plugin require my admin login and password? The admin login and password are used to bypass the confirmation e-mail that would normally be sent to a subscriber. Effectively, the plugin "logs into" phpList as the administrator and then subscribes the user, bypassing confirmation. If you don't want to bypass confirmation e-mails, then you don't need to enter your username and password. Form Settings The plugin will work with this section unmodified. However, let's imagine that we also want to capture the subscriber's name. We already have an attribute in phpList called first name, so change the first field label to First Name and the Text Field ID to first name (the same as our phpList attribute name): Adding a phpList Integration page The plugin will replace the HTML comment <!--phplist form--> with the generated phpList form. Let's say we wanted our phpList form to show up at http://ourblog.com/signup. Create a new WordPress page called Signup, add the content you want to be displayed, and then click on the HTML tab to edit the HTML source: You will see the HTML source of your page displayed. Insert the text "<!--phplist form-->" where you want the form to be displayed and save the page: HTML comments The "<!--some text-->" syntax designates an HTML comment, which is not displayed when the HTML is processed by the browser / viewer. This means that you won't see your comment when you view your page in Visual mode. Once the page has been updated, click on the View page link to display the page in WordPress: The subscribe form will be inserted in the page at the location where you added the comment: Adding a phpList Integration widget Instead of a dedicated page to sign up new subscribers, you may want to use a sidebar widget instead, so that the subscription options can show up on multiple pages on your WordPress site. To add the phpList integration widget, go to your WordPress site's Appearance option and go to the Widgets page: Drag the PHPList Integration widget to your preferred widget location. (These vary depending on your theme): You can change the Title of the widget before you click on Close to finish: Now that you've added the PHPList Integration widget to the widget area, your sign up form will be displayed on all WordPress pages, which include that widget area:   Further resources on this subject: Integrating phpList 2 with Drupal phpList 2 E-mail Campaign Manager: Personalizing E-mail Body Tcl: Handling Email Email, Languages, and JFile with Joomla!
Read more
  • 0
  • 0
  • 4299
Visually different images

article-image-haxe-2-dynamic-type-and-properties
Packt
28 Jul 2011
7 min read
Save for later

haXe 2: The Dynamic Type and Properties

Packt
28 Jul 2011
7 min read
  haXe 2 Beginner's Guide Develop exciting applications with this multi-platform programming language Freeing yourself from the typing system The goal of the Dynamic type is to allow one to free oneself from the typing system. In fact, when you define a variable as being a Dynamic type, this means that the compiler won't make any kind of type checking on this variable. Time for action – Assigning to Dynamic variables When you declare a variable as being Dynamic, you will be able to assign any value to it at compile time. So you can actually compile this code: class DynamicTest { public static function main() { var dynamicVar : Dynamic; dynamicVar = "Hello"; dynamicVar = 123; dynamicVar = {name:"John", lastName : "Doe"}; dynamicVar = new Array<String>(); } } The compiler won't mind even though you are assigning values with different types to the same variable! Time for action – Assigning from Dynamic variables You can assign the content of any Dynamic variable to a variable of any type. Indeed, we generally say that the Dynamic type can be used in place of any type and that a variable of type Dynamic is indeed of any type. So, with that in mind, you can now see that you can write and compile this code: class DynamicTest { public static function main() { var dynamicVar : Dynamic; var year : Int; dynamicVar = "Hello"; year = dynamicVar; } } So, here, even though we will indeed assign a String to a variable typed as Int, the compiler won't complain. But you should keep in mind that this is only at compile time! If you abuse this possibility, you may get some strange behavior! Field access A Dynamic variable has an infinite number of fields all of Dynamic type. That means you can write the following: class DynamicTest { public static function main() { var dynamicVar : Dynamic; dynamicVar = {}; dynamicVar.age = 12; //age is Dynamic dynamicVar.name = "Benjamin"; //name is Dynamic } } Note that whether this code will work or not at runtime is highly dependent on the runtime you're targeting. Functions in Dynamic variables It is also possible to store functions in Dynamic variables and to call them: class DynamicTest { public static function main() { var dynamicVar : Dynamic; dynamicVar = function (name : String) { trace("Hello" + name); }; dynamicVar(); var dynamicVar2 : Dynamic = {}; dynamicVar2.sayBye = function (name : String) { trace("Bye" + name ); }; dynamicVar2.sayBye(); } } As you can see, it is possible to assign functions to a Dynamic variable or even to one of its fields. It's then possible to call them as you would do with any function. Again, even though this code will compile, its success at running will depend on your target. Parameterized Dynamic class You can parameterize the Dynamic class to slightly modify its behavior. When parameterized, every field of a Dynamic variable will be of the given type. Let's see an example: class DynamicTest { public static function main() { var dynamicVar : Dynamic<String>; dynamicVar = {}; dynamicVar.name = "Benjamin"; //name is a String dynamicVar.age = 12; //Won't compile since age is a String } } In this example, dynamicVar.name and dynamicVar.age are of type String, therefore, this example will fail to compile on line 7 because we are trying to assign an Int to a String. Classes implementing Dynamic A class can implement a Dynamic, parameterized or not. Time for action – Implementing a non-parameterized Dynamic When one implements a non-parameterized Dynamic in a class, one will be able to access an infinite number of fields in an instance. All fields that are not declared in the class will be of type Dynamic. So, for example: class User implements Dynamic { public var name : String; public var age : Int; //... } //... var u = new User(); //u is of type User u.name = "Benjamin"; //String u.age = 22; //Int u.functionrole = "Author"; //Dynamic   What just happened?   As you can see, the functionrole field is not declared in the User class, so it is of type Dynamic. In fact, when you try to access a field that's not declared in the class, a function named resolve will be called and it will get the name of the property accessed. You can then return the value you want. This can be very useful to implement some magic things. Time for action – Implementing a parameterized Dynamic When implementing a parameterized Dynamic, you will get the same behavior as with a non-parameterized Dynamic except that the fields that are not declared in the class will be of the type given as a parameter. Let's take almost the same example but with a parameterized Dynamic: class User implements Dynamic<String> { public var name : String; public var age : Int; //... } //... var u = new User(); //u is of type User u.name = "Benjamin"; //String u.age = 22; //Int u.functionrole = "Author"; //String because of the type parameter   What just happened?   As you can see here, fields that are not declared in the class are of type String because we gave String as a type parameter. Using a resolve function when implementing Dynamic Now we are going to use what we've just learned. We are going to implement a Component class that will be instantiated from a configuration file. A component will have properties and metadata. Such properties and metadata are not pre-determined, which means that the properties' names and values will be read from the configuration file. Each line of the configuration file will hold the name of the property or metadata, its value, and a 0 if it's a property (or otherwise it will be a metadata). Each of these fields will be separated by a space. The last constraint is that we should be able to read the value of a property or metadata by using the dot-notation. Time for action – Writing our Component class As you may have guessed, we will begin with a very simple Component class — all it has to do at first is to have two Hashes: one for metadata, the other one for properties. class Component { public var properties : Hash<String>; public var metadata : Hash<String>; public function new() { properties = new Hash<String>(); metadata = new Hash<String>(); } } It is that simple at the moment. As you can see, we do not implement access via the dot-notation at the moment. We will do it later, but the class won't be very complicated even with the support for this notation. Time for action – Parsing the configuration file We are now going to parse our configuration file to create a new instance of the Component class. In order to do that, we are going to create a ComponentParser class. It will contain two functions: parseConfigurationFile to parse a configuration file and return an instance of Component. writeConfigurationFile that will take an instance of Component and write data to a file. Let's see how our class should look at the moment (this example will only work on neko): class ComponentParser { /** * This function takes a path to a configuration file and returns an instance of ComponentParser */ public static function parseConfigurationFile(path : String) { var stream = neko.io.File.read(path, false); //Open our file for reading in character mode var comp = new Component(); //Create a new instance of Component while(!stream.eof()) //While we're not at the end of the file { var str = stream.readLine(); //Read one line from file var fields = str.split(" "); //Split the string using space as delimiter if(fields[2] == "0") { comp.properties.set(fields[0], fields[1]); //Set the key<->value in the properties Hash } else { comp.metadata.set(fields[0], fields[1]); //Set the key<->value in the metadata Hash } } stream.close(); return comp; } } It's not that complicated, and you would actually use the same kind of method if you were going to use a XML file. Time for action – Testing our parser Before continuing any further, we should test our parser in order to be sure that it works as expected. To do this, we can use the following configuration file: nameMyComponent 1 textHelloWorld 0 If everything works as expected, we should have a name metadata with the value MyComponent and a property named text with the value HelloWorld. Let's write a simple test class: class ComponentImpl { public static function main(): Void { var comp = ComponentParser.parseConfigurationFile("conf.txt"); trace(comp.properties.get("text")); trace(comp.metadata.get("name")); } } Now, if everything went well, while running this program, you should get the following output: ComponentImpl.hx:6: HelloWorld ComponentImpl.hx:7: MyComponent
Read more
  • 0
  • 0
  • 1476

article-image-play-framework-introduction-writing-modules
Packt
28 Jul 2011
11 min read
Save for later

Play Framework: Introduction to Writing Modules

Packt
28 Jul 2011
11 min read
Play Framework Cookbook In order to get to know more modules, you should not hesitate to take a closer look at the steadily increasing amount of modules available at the Play framework modules page at http://www.playframework.org/modules. When beginning to understand modules, you should not start with modules implementing its persistence layer, as they are often the more complex ones. In order to clear up some confusion, you should be aware of the definition of two terms throughout the article, as these two words with an almost identical meaning are used most of the time. The first is word is module and the second is plugin. Module means the little application which serves your main application, where as plugin represents a piece of Java code, which connects to the mechanism of plugins inside Play. Creating and using your own module Before you can implement your own functionality in a module, you should know how to create and build a module. This recipe takes a look at the module's structure and should give you a good start. The source code of the example is available at examples/chapter5/module-intro. How to do it... It is pretty easy to create a new module. Go into any directory and enter the following: play new-module firstmodule This creates a directory called firstmodule and copies a set of predefined files into it. By copying these files, you can create a package and create this module ready to use for other Play applications. Now, you can run play build-module and your module is built. The build step implies compiling your Java code, creating a JAR file from it, and packing a complete ZIP archive of all data in the module, which includes Java libraries, documentation, and all configuration files. This archive can be found in the dist/ directory of the module after building it. You can just press Return on the command line when you are asked for the required Play framework version for this module. Now it is simple to include the created module in any Play framework application. Just put this in the in the conf/dependencies.yml file of your application. Do not put this in your module! require: - play - customModules -> firstmodule repositories: - playCustomModules: type: local artifact: "/absolute/path/to/firstmodule/" contains: - customModules -> * The next step is to run play deps. This should show you the inclusion of your module. You can check whether the modules/ directory of your application now includes a file modules/firstmodule, whose content is the absolute path of your module directory. In this example it would be /path/to/firstmodule. To check whether you are able to use your module now, you can enter the following: play firstmodule:hello This should return Hello in the last line. In case you are wondering where this is coming from, it is part of the commands.py file in your module, which was automatically created when you created the module via play new-module. Alternatively, you just start your Play application and check for an output such as the following during application startup: INFO ~ Module firstmodule is available (/path/to/firstmodule) The next step is to fill the currently non-functional module with a real Java plugin, so create src/play/modules/firstmodule/MyPlugin.java: public class MyPlugin extends PlayPlugin { public void onApplicationStart() { Logger.info("Yeeha, firstmodule started"); } } You also need to create the file src/play.plugins: 1000:play.modules.firstmodule.MyPlugin Now you need to compile the module and create a JAR from it. Build the module as shown in the preceding code by entering play build-module. After this step, there will be a lib/play- firstmodule.jar file available, which will be loaded automatically when you include the module in your real application configuration file. Furthermore, when starting your application now, you will see the following entry in the application log file. If you are running in development mode, do not forget to issue a first request to make sure all parts of the application are loaded: INFO ~ Yeeha, firstmodule started How it works... After getting the most basic module to work, it is time go get to know the structure of a module. The filesystem layout looks like this, after the module has been created: app/controllers/firstmodule app/models/firstmodule app/views/firstmodule app/views/tags/firstmodule build.xml commands.py conf/messages conf/routes lib src/play/modules/firstmodule/MyPlugin.java src/play.plugins As you can see a module basically resembles a normal Play application. There are directories for models, views, tags, and controllers, as well as a configuration directory, which can include translations or routes. Note that there should never be an application.conf file in a module. There are two more files in the root directory of the module. The build.xml file is an ant file. This helps to compile the module source and creates a JAR file out of the compiled classes, which is put into the lib/ directory and named after the module. The commands.py file is a Python file, which allows you to add special command line directives, such as the play firstmodule:hello command that we just saw when executing the Play command line tool. The lib/ directory should also be used for additional JARs, as all JAR files in this directory are automatically added to classpath when the module is loaded. Now the only missing piece is the src/ directory. It includes the source of your module, most likely the logic and the plugin source. Furthermore, it features a very important file called play.plugins. After creating the module, the file is empty. When writing Java code in the src/ directory, it should have one line consisting of two entries. One entry features the class to load as a plugin; where as the other entry resembles a priority. This priority defines the order in which to load all modules of an application. The lower the priority, the earlier the module gets loaded. If you take a closer look at the PlayPlugin class, which MyPlugin inherits from, you will see a lot of methods that you can override. Here is a list of some of them accompanying a short description: onLoad(): This gets executed directly after the plugin has been loaded. However, this does not mean that the whole application is ready! bind(): There are two bind() methods with different parameters. These methods allow a plugin to create a real object out of arbitrary HTTP request parameters or even the body of a request. If you return anything different other than null in this method, the returned value is used as a parameter for controller whenever any controller is executed. getStatus(), getJsonStatus(): Allows you to return an arbitrary string representing a status of the plugin or statistics about its usage. You should always implement this for production ready plugins in order to simplify monitoring. enhance(): Performs bytecode enhancement. rawInvocation(): This can be used to intercept any incoming request and change the logic of it. This is already used in the CorePlugin to intercept the @kill and @status URLs. This is also used in the DocViewerPlugin to provide all the existing documentation, when being in test mode. serveStatic(): Allows for programmatically intercepting the serving of static resources. A common example can be found in the SASS module, where the access to the .sass file is intercepted and it is precomplied. loadTemplate(): This method can be used to inject arbitrary templates into the template loader. For example, it could be used to load templates from a database instead of the filesystem. detectChange(): This is only active in development mode. If you throw an exception in this method, the application will be reloaded. onApplicationStart(): This is executed on application start and if in development mode, on every reload of your application. You should initiate stateful things here, such as connections to databases or expensive object creations. Be aware, that you have to care of thread safe objects and method invocations for yourself. For an example you could check the DBPlugin, which initializes the database connection and its connection pool. Another example is the JPAPlugin, which initializes the persistence manager or the JobPlugin, which uses this to start jobs on application start. onApplicationReady(): This method is executed after all plugins are loaded, all classes are precompiled, and every initialization is finished. The application is now ready to serve requests. afterApplicationStart(): This is currently almost similar to onApplicationReady(). onApplicationStop(): This method is executed during a graceful shutdown. This should be used to free resources, which were opened during the starting of the plugin. A standard example is to close network connections to database, remove stale file system entries, or clear up caches. onInvocationException(): This method is executed when an exception, which is not caught is thrown during controller invocation. The ValidationPlugin uses this method to inject an error cookie into the current request. invocationFinally(): This method is executed after a controller invocation, regardless of whether an exception was thrown or not. This should be used to close request specific data, such as a connection, which is only active during request processing. beforeActionInvocation(): This code is executed before controller invocation. Useful for validation, where it is used by Play as well. You could also possibly put additional objects into the render arguments here. Several plugins also set up some variables inside thread locals to make sure they are thread safe. onActionInvocationResult(): This method is executed when the controller action throws a result. It allows inspecting or changing the result afterwards. You can also change headers of a response at this point, as no data has been sent to the client yet. onInvocationSuccess(): This method is executed upon successful execution of a complete controller method. onRoutesLoaded(): This is executed when routes are loaded from the routes files. If you want to add some routes programmatically, do it in this method. onEvent(): This is a poor man's listener for events, which can be sent using the postEvent() method. onClassesChange(): This is only relevant in testing or development mode. The argument of this method is a list of freshly changed classes, after a recompilation. This allows the plugin to detect whether certain resources need to be refreshed or restarted. If your application is a complete shared-nothing architecture, you should not have any problems. Test first, before implementing this method. addTemplateExtensions(): This method allows you to add further TemplateExtension classes, which do not inherit from JavaExtensions, as these are added automatically. At the time of this writing, neither a plugin nor anything in the core Play framework made use of this, with the exception of the Scala module. compileAll(): If the standard compiler inside Play is not sufficient to compile application classes, you can override this method. This is currently only done inside the Scala plugin and should not be necessary in regular applications. routeRequest(): This method can be used to redirect requests programmatically. You could possibly redirect any URL which has a certain prefix or treat POST requests differently. You have to render some result if you decide to override this method. modelFactory(): This method allows for returning a factory object to create different model classes. This is needed primarily inside of the different persistence layers. It was introduced in play 1.1 and is currently only used by the JPA plugin and by the Morphia plugin. The model factory returned here implements a basic and generic interface for getting data, which is meant to be independent from the persistence layer. It is also used to provide a more generic fixtures support. afterFixtureLoad(): This method is executed after a Fixtures.load() method has been executed. It could possibly be used to free or check some resources after adding batch data via fixtures. Cleaning up after creating your module When creating a module via Play new-module, you should remove any unnecessary cruft from your new module, as most often, not all of this is needed. Remove all unneeded directories or files, to make understanding the module as easy as possible. Supporting Eclipse IDE As play eclipsify does not work currently for modules, you need to set it up manually. A trick to get around this is to create and eclipsify a normal Play application, and then configure the build path and use "Link source" to add the src/ directory of the plugin.
Read more
  • 0
  • 0
  • 4282

article-image-integrating-phplist-2-drupal
Packt
28 Jul 2011
3 min read
Save for later

Integrating phpList 2 with Drupal

Packt
28 Jul 2011
3 min read
PHPList 2 E-mail Campaign Manager Get to grips with the PHPList e-mail announcement delivery system!        Prerequisites For this article, we'll make the following assumptions: We already have a working instance of Drupal (version 6). We are hosting our Drupal site and our phpList site on the same web server and with the same URL base. That is, our Drupal site is accessible at http://yoursite.com and our phpList installation is accessible at http://yoursite.com/lists/. We chose to document the Drupal-phpList integration using Drupal 6, even though Drupal 7 has recently been released. This is because (a) the phpList module for Drupal 7 is still marked as "development" and (b) Drupal 6 has been the official stable version for three years and has a more familiar interface than 7 at this time. However, the following method described for Drupal 6 will work on Drupal 7. Installing and configuring the phpList integration module Go to http://drupal.org/project/phplist and download the latest stable version of the module for Drupal 6.x. Unpack the tar.gz file and you should have a folder called phplist inside. Upload this folder to your Drupal installation's modules directory and then navigate to Administer | Site building | Modules: At the bottom of the modules list, you'll find the Mail and phpList headings with a single phpList module under each. Check both and click on Save configuration: External phpList configuration Navigate to Administer | Site configuration | PHPlist to set up the database credentials and other options required for the integration: You are prompted for your phpList database details. Enter your database host, database name, username, and password. Unless you've done a non-standard installation of phpList, the default entries for prefix and user table prefix will already be correct. Under PHPList URL, enter the URL to your phpList installation. Because we are using phpList and Drupal at the same base URL, we set /lists/ (with a trailing slash) as our PHPList URL: The database check illustrated in the preceding screenshot (red text reading Password is not set) is done after you save your settings. The module tries to connect to the phpList database using the details provided and will warn you if it fails. Scroll to the bottom, ignoring the other options for now, and click on Save configuration: If the database connection test was successful, the External PHPList configuration options will be collapsed into a single, clickable field, hiding them from normal view, as you configure the remaining options: Attribute mapping The module can auto-create attributes in phpList to match any attributes created in your Drupal instance. For example, you may ask your Drupal members to enter demographic information when registering and this mapping would allow these details to be transferred to the phpList. Note that the module warns you that this mapping only works well with textline attributes and not select attributes or radio buttons. Use of this feature is not covered in this article, as it requires advanced pre-configuration of your Drupal instance:
Read more
  • 0
  • 0
  • 1550
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €14.99/month. Cancel anytime
article-image-alfresco-3-writing-and-executing-scripts
Packt
27 Jul 2011
4 min read
Save for later

Alfresco 3: Writing and Executing Scripts

Packt
27 Jul 2011
4 min read
  Alfresco 3 Cookbook Over 70 recipes for implementing the most important functionalities of Alfresco The reader can benefit from the previous article on Implementing Alfresco JavaScript API Functionalities. Introduction Alfresco, like any other enterprise open source framework, exposes a number of APIs including Alfresco SDK (Software Development Kit) a set of development tools that allows the creation of an application for a certain software package or framework and JavaScript API. Available JavaScript APIs Alfresco JavaScript API exposes all important repository objects as JavaScript objects that can be used in a script file. The API follows the object-oriented programming model for well known Alfresco concepts such as Nodes, Properties, Associations, and Aspects. The JavaScript API is capable of performing several essential functions for the script developer, such as: Create Node, Update Node: You can create, upload, or update files using these. Check In/Check Out: You can programmatically check-out and check-in your content. Access Rights Management Permissioning: You can manage your content’s security aspects. Transformation: You can transform your content using this. For example, you want to generate a PDF version of your MS-Office document. Tagging: Tagging APIs will help you tag your contents. Classifying: You can categorize or classify your contents using this. People: Using these APIs, you can handle all user-and group-related operations in your script; such as creating a new user, changing the password of a user, and so on. Searching: One of most important and powerful APIs exposed. You can search your contents using these APIs. You can perform Lucene-based search or XPath-based search operations using these APIs. Workflow: You can manage the tasks and workflows in your system using these APIs and services. Thumbnail: Exposes APIs to manage the thumbnail operations of various content items. Node operations: You use these APIs to perform several node-related functions such as Manage Properties, Manage Aspects, copying, deleting, moving, and so on. Thus, as you can see, pretty much most of the things can be done in a JavaScript file using these APIs. However, one thing is important, that you should not mix the usual JavaScript code you write for your HTML or JSP web pages. Those scripts are executed by your browser (this means, at the client side). The scripts you write using Alfresco JavaScript API are not client-side JavaScript file – this means these do not get executed by your browser. Instead, they get executed in your server and the browser has nothing to do in these scripts. It is called JavaScript API since the APIs are exposed using the ECMA script model and syntaxes. The programs you develop using these APIs are written in JavaScript language. The JavaScript API model Alfresco has provided a number of objects in the JavaScript API – these are more usually named as Root Scope Objects. These objects are your entry point into the repository. Each of the root level objects refers to a particular entity or functional point in the repository. For example, userhome object refers to the home space node of the current user. Each of these objects presents a number of properties and functionalities, thus enabling the script writer to implement several different requirements. For example, the userhome.name statement will return the name of the root folder of the current user. Some important and most frequently used root scope objects are: Companyhome: Returns the company home script node object Userhome: Returns the home folder node of the current user Person: Represents the current user person object Space: Stands for the current space object Document: Returns the currently selected document Search: Offers fully functional search APIs People: Encapsulates all functionalities related to user, groups, roles, permissions, and so on. Sites: Exposes the site service functionalities Actions: Provides invocation methods for registered actions Workflow: Handles all functionalities related to workflow implementation within the repository Among these, companyhome, userhome, person, space, and document objects represent Alfresco Node objects and allow access to the properties and aspects of the corresponding node object. Each of the node objects provides a number of APIs which are termed ScriptNode API. The others – search, people, sites, workflow, and actions – expose several methods that would help you implement specific business requirements. For example, if you want to write a script that searches some documents and contents, you would use the search API. If you want to create a new user – the people API will help you.  
Read more
  • 0
  • 0
  • 2109

article-image-jquery-ui-themes-theme-icons-standalone-icons-and-icon-states
Packt
27 Jul 2011
9 min read
Save for later

jQuery UI Themes: Theme icons, Standalone Icons, and Icon States

Packt
27 Jul 2011
9 min read
  jQuery UI Themes Beginner's Guide Create new themes for your JQuery site with this step-by-step guide   What are theme icons? In any user interface, we see icons all over the place. On your desktop, you see icons that represent the various application shortcuts as well as any files you've placed there. The window containing your web browser has icons for the maximize, minimize, and close actions. The benefit of using icons is that they're incredibly space-efficient, as long as they're descriptive. Using icons out of context defeats their purpose - you don't want a button with a "down arrow" icon in your toolbar. This doesn't mean anything to the user. Having a button with a "trashcan" icon in the tool-bar does make sense—it means I want to delete what I'm looking at. Another potentially harmful use is using icons in places where a text description would better inform the user. For instance, displaying a "trashcan" button in the toolbar might confuse the user if there are several things displayed on the same page, even if they've selected something. In these scenarios, we're often better off using a combination of text and an icon. The jQuery UI theming framework provides a large selection of icons we can use in our user interfaces. Some of these icons are already used in some widgets, for instance, the accordion uses arrow icons by default. Not only are the icon graphics provided to us - we can choose icon colors in the ThemRoller application - but we also have powerful CSS class we use to apply the icons. Using these classes, we can give existing jQuery UI widgets new icons or we can place them strategically in our application user interface where they prove helpful. Sometimes, the provided icon set will only go so far. You'll find that at one point or another, you need new icons that better reflect the concepts of your application domain. Time for action - preparing the example It's time to set up an environment for examples throughout the remainder of this article. If you haven't already, download and extract the jQuery UI package into a directory called jQuery UI from http://jqueryui.com/download. At the same level as the jQuery UI directory, create a new index.html file with the following content: <html > <head> <title>Creating Theme Icons</title> <link href="jqueryui/development-bundle/themes/base/ jquery.ui.all.css" rel="stylesheet" type="text/css" /> <script src="jqueryui/js/jquery-1.5.x.min.js" type="text/ javascript"></script> <script src="jqueryui/js/jquery-ui-1.8.x.custom.min.js" type="text/javascript"></script> <script src="index.js" type="text/javascript"></script> </head> <body style="font-size: 10px;"> <button id="my_button">Click Me</button> </body> </html> At the same level as the jqueryui directory, create a new index.js file with the following content. $(document).ready(function(){ $("#my_button").button(); }); Open index.html in your web browser; you should see something similar to the following: Icons in widgets Several jQuery UI widgets have icons from the theming framework embedded inside them. We use icons inside widgets to decorate them and to add meaning. Icons are similar to interaction cues, they help guide the user through the application workflow by given subtle hints. Before we start modifying icons used in our theme, we need to take a closer look at the role they play in widgets. Time for action - default widget icons Let's take a look at some of the icons displayed in jQuery UI widgets by default: Edit the index.html file created earlier and replace the content with the following: <html > <head> <title>Creating Theme Icons</title> <link href="jqueryui/development-bundle/themes/base/ jquery.ui.all.css" rel="stylesheet" type="text/css" /> <script src="jqueryui/js/jquery-1.5.x.min.js" type="text/ javascript"></script> <script src="jqueryui/js/jquery-ui-1.8.x.custom.min.js" type="text/javascript"></script> <script src="index.js" type="text/javascript"></script> </head> <body style="font-size: 10px;"> <input id="my_datepicker" type="text" style="margin- bottom: 170px;"/> <div style="width: 40%;"> <div id="my_accordion"> <h3><a href="#">First</a></h3> <div> <p>First paragraph</p> <p>Second paragraph</p> <p>Third paragraph</p> </div> <h3><a href="#">Second</a></h3> <div></div> <h3><a href="#">Third</a></h3> <div></div> </div> </div> </body> </html> Edit the index.js file created earlier and replace the content with the following: $(document).ready(function(){ $("#my_accordion").accordion(); $("#my_datepicker").datepicker(); }); Reload index.html in your web browser. You should see something similar to the following:   What just happened?   We've just created two widgets—a date-picker and an accordion. In index.html, we've created the markup for both widgets and in index.js, we construct the jQuery UI components when the page has finished loading. You'll notice that both widgets have icons in them by default. The date-picker widget has two arrows beside the month and year. The accordion widget has an arrow in each accordion section header. These widgets have icons by default because they help bring meaning to the widget succinctly. As a user, I can easily deduce the meaning of the arrows in the date-picker: move to the next or previous month. Additionally, the text "Next" and "Previous" are added to their respective icons as titles. An alternate presentation of these controls is a text link or button: "next month", "previous month". This doesn't add any value; it only takes away from the space inside the widget. The arrow icon role in the accordion widget is even more obvious. The down arrow represents the currently expanded accordion section. The right arrows represent collapsed sections. Without these arrows, the user would eventually figure out how to work the accordion controls; however, the icons make it much more obvious in a non-intrusive way. Time for action - setting widget icons In addition to using the default icons in widgets, we have the option to set the icon in certain widgets. Let's see how this is done: Edit the index.html file created earlier and replace the content with the following: <html > <head> <title>Creating Theme Icons</title> <link href="jqueryui/development-bundle/themes/base/ jquery.ui.all.css" rel="stylesheet" type="text/css" /> <script src="jqueryui/js/jquery-1.5.x.min.js" type="text/ javascript"></script> <script src="jqueryui/js/jquery-ui-1.8.x.custom.min.js" type="text/javascript"></script> <script src="index.js" type="text/javascript"></script> </head> <body style="font-size: 10px;"> <button id="my_button" style="margin-bottom: 10px;">View</ button> <div style="width: 40%;"> <div id="my_accordion"> <h3><a href="#">First</a></h3> <div> <p>First paragraph</p> <p>Second paragraph</p> <p>Third paragraph</p> </div> <h3><a href="#">Second</a></h3> <div></div> <h3><a href="#">Third</a></h3> <div></div> </div> </div> </body> </html> Edit the index.js file created earlier and replace the content with the following: $(document).ready(function(){ $("#my_button").button({icons: {primary: "ui-icon-video"}}); $("#my_accordion").accordion({icons: {header: "ui-icon-circle- triangle-e", headerSelected: "ui-icon-circle-triangle-s"} }); }); Reload index.html in your web browser. You should see something similar to the following:   What just happened? In index.html, we've created a button and an accordion widget. In index.js, we build the jQuery UI components of these widgets when the page has finished loading. In the constructor of the button widget, we pass an object to the icons parameter. This object has a primary value of ui-icon-video. This will give our button a small video icon to the left of the text. Likewise, we pass an object to the icon's parameter in the accordion constructor. This object has two values - header has a value of ui-icon-circletriangle- e and headerSelected has a value of ui-icon-circle-triangle-s. The jQuery UI theme framework has several arrow icons to choose from. The framework uses the "compass notation" for arrow icon classes. Say you want an arrow that points up. You could use ui-icon-circletriangle- n, as this arrow points "north". The button widget has built-in support for adding a button to text in order to provide additional meaning. In our example, the text view isn't very meaningful to the user. With the video icon beside the text view, it becomes very obvious what the button does. What we've done with the accordion widget is slightly different. The accordion widget displays icons by default; we've just specified different ones. This is a pure embellishment of the accordion - we've found icons that we'd like to use and replaced the default ones. We might even want to replace them with our own icons that we create.
Read more
  • 0
  • 0
  • 3078

article-image-implementing-alfresco-javascript-api-functionalities
Packt
27 Jul 2011
6 min read
Save for later

Implementing Alfresco JavaScript API Functionalities

Packt
27 Jul 2011
6 min read
Alfresco 3 Cookbook Over 70 recipes for implementing the most important functionalities of Alfresco The reader can benefit from the previous article on Alfresco 3: Writing and Executing Scripts.   Add/Change contents of a document Let’s explore some example JavaScript. In the following example scripts, you will be able to witness the APIs and functionalities. Getting ready We will store the JavaScript files in the Company Home>Data Dictionary>Scripts>Cookbook folder (this folder does not exist in your repository and create this folder). And will run the sample scripts against a document – Test_JS_API.txt in the folder Company Home>InfoAxon>Chapter 8. I have uploaded this text file with a simple line of text: A sample Document created to investigate in JavaScript API. and used our custom content type iabook:Product. if (document.hasPermission("Write")) { if (document.mimetype == "text/plain") { if (!document.hasAspect("cm:versionable")) document.addAspect("cm:versionable"); var wcopy = document.checkout(); var cnt = wcopy.content; cnt += "rnThis line is added using the JavaScript."; wcopy.content = cnt; wcopy.checkin("Sample Line added via JS"); } } How to do it... Create a new script file in the Company Home>Data Dictionary>Scripts>Cookbook folder and save this code; let’s say the file is named changecontent.js Execute the script using Run Action on the document Test_JS_API.txt in the Chapter 8 folder. After running the script, a new version of the document will be created and a new line will be added in the document. Thus each time you run the script for this document, a line will be appended at the end of the content and a new version will be created. How it works... The document object here automatically refers to the current document, in our case, it is Test_JS_API.txt, since we have executed the script against this document. First we have checked whether we have proper permission to perform the write operation on the document. If the permission is there, we check the mimetype of the document, since the textual content writing operation is possible only for a few mimetypes such as text, html, and so on. After that, we check whether the document is versionable or not, by default, any content you upload in the repository is not versionable. So we add the cm:versionable aspect in case it is not there already. Then we checkout the document and append the line of text we want in the working copy. After updating the content, we checking the working copy with a commit comment. This comment is visible in the Version History of the document. Though it is not always mandatory to check for the required permissions, it is a good practice to confirm for the relevant permissions, otherwise Alfresco may throw runtime errors in case the required permissions are not available.   Creating a backup copy of a document In this recipe, we will write a script to create a backup copy of a particular document. How to do it... Create a new script file in the Company Home>Data Dictionary>Scripts>Cookbook folder and add the following code. Let’s say the file is named createbackup.js var back = space.childByNamePath("Backup"); if (back == null && space.hasPermission("CreateChildren")) { back = space.createFolder("Backup"); } if (back != null && back.hasPermission("CreateChildren")) { var copied = document.copy(back); if (copied != null) { var backName = "Backup of " + copied.name; copied.name = backName; copied.properties.description = "This is a Backup copy created by JS"; copied.save(); } } Execute the script using Run Action on the document Test_JS_API.txt in the Chapter 8 folder. After executing the script, a new folder named Backup will be created (if it does not exist already) and a copy of this document (named Backup of Test_JS_API.txt) will be created in the backup folder. (Move the mouse over the image to enlarge.) How it works... The space object here automatically refers to the current space. In our case, it is Chapter 8, since we have executed the script against a document from this folder. The document object here automatically refers to the current document. In our case, it is Test_JS_API.txt, since we have executed the script against this document. First we have checked whether a space already exists there with the name Backup under Chapter 8. If not, we create the space. This is the space where we intend to create our backup copy. After that, we check whether we have the proper permission to create a new document in the backup folder. We do this by checking the CreateChildren permission. If we have the proper required permission, we create a copy of the document in the backup folder. Then we change a few properties of the copied document – we change the name and description, for instance. After changing the properties, we save the changes. Note that you do not need to save after changing the content of a document. However, you need to do this in case you change any property of the content item.   Adding a tag to a document In this recipe, we will write a script that can be used to tag a document. How to do it… Create a new script file in the Company Home>Data Dictionary>Scripts>Cookbook folder and add the following code; let’s say the file is named addtag.js if (!document.hasAspect("cm:taggable")) document.addAspect("cm:taggable"); document.addTag("test"); Execute the script using Run Action on the document Test_JS_API.txt in the Chapter 8 folder. The document will not be taggable, and a new tag has been added with the document – test. This is reflected in the property sheet of the document. Now, you can also add more tags using the property editor dialog. How it works... The code we presented is rather simple in this case. As usual, the document object here automatically refers to the current document. In our case, it is Test_JS_API.txt, since we have executed the script against this document. First we have checked whether the document already has the cm:taggable aspect associated with it, if not we add this aspect. Then it is just about adding a tag – we added a tag test. You can also add multiple tags at a time using the addTags method (we have used the addTag method to add a single tag in our example).  
Read more
  • 0
  • 0
  • 2135

article-image-apache-solr-spellchecker-statistics-and-grouping-mechanism
Packt
27 Jul 2011
5 min read
Save for later

Apache Solr: Spellchecker, Statistics, and Grouping Mechanism

Packt
27 Jul 2011
5 min read
Computing statistics for the search results Imagine a situation where you want to compute some basic statistics about the documents in the results list. For example, you have an e-commerce shop where you want to show the minimum and the maximum price of the documents that were found for a given query. Of course, you could fetch all the documents and count it by yourself, but imagine if Solr can do it for you. Yes it can and this recipe will show you how to use that functionality. How to do it... Let's start with the index structure (just add this to the fields section of your schema.xml file): <field name="id" type="string" indexed="true" stored="true" required="true" /> <field name="name" type="text" indexed="true" stored="true" /> <field name="price" type="float" indexed="true" stored="true" /> The example data file looks like this: <add> <doc> <field name="id">1</field> <field name="name">Book 1</field> <field name="price">39.99</field> </doc> <doc> <field name="id">2</field> <field name="name">Book 2</field> <field name="price">30.11</field> </doc> <doc> <field name="id">3</field> <field name="name">Book 3</field> <field name="price">27.77</field> </doc> </add> Let's assume that we want our statistics to be computed for the price field. To do that, we send the following query to Solr: http://localhost:8983/solr/select?q=name:book&stats=true&stats. field=price The response Solr returned should be like this: <?xml version="1.0" encoding="UTF-8"?> <response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">0</int> <lst name="params"> <str name="q">name:book</str> <str name="stats">true</str> <str name="stats.field">price</str> </lst> </lst> <result name="response" numFound="3" start="0"> <doc> <str name="id">1</str> <str name="name">Book 1</str> <float name="price">39.99</float> </doc> <doc> <str name="id">2</str> <str name="name">Book 2</str> <float name="price">30.11</float> </doc> <doc> <str name="id">3</str> <str name="name">Book 3</str> <float name="price">27.77</float> </doc> </result> <lst name="stats"> <lst name="stats_fields"> <lst name="price"> <double name="min">27.77</double> <double name="max">39.99</double> <double name="sum">97.86999999999999</double> <long name="count">3</long> <long name="missing">0</long> <double name="sumOfSquares">3276.9851000000003</double> <double name="mean">32.62333333333333</double> <double name="stddev">6.486118510583508</double> </lst> </lst> </lst> </response> As you can see, in addition to the standard results list, there was an additional section available. Now let's see how it works. How it works... The index structure is pretty straightforward. It contains three fields—one for holding the unique identifier (the id field), one for holding the name (the name field), and one for holding the price (the price field). The file that contains the example data is simple too, so I'll skip discussing it. The query is interesting. In addition to the q parameter, we have two new parameters. The first one, stats=true, tells Solr that we want to use the StatsComponent, the component which will calculate the statistics for us. The second parameter, stats.field=price, tells the StatsComponent which field to use for the calculation. In our case, we told Solr to use the price field. Now let's look at the result returned by Solr. As you can see, the StatsComponent added an additional section to the results. This section contains the statistics generated for the field we told Solr we want statistics for. The following statistics are available: min: The minimum value that was found in the field for the documents that matched the query max: The maximum value that was found in the field for the documents that matched the query sum: Sum of all values in the field for the documents that matched the query count: How many non-null values were found in the field for the documents that matched the query missing: How many documents that matched the query didn't have any value in the specified field sumOfSquares: Sum of all values squared in the field for the documents that matched the query mean: The average for the values in the field for the documents that matched the query stddev: The standard deviation for the values in the field for the documents that matched the query You should also remember that you can specify multiple stats.field parameters to calculate statistics for different fields in a single query. Please be careful when using this component on the multi-valued fields. It can sometimes be a performance bottleneck.
Read more
  • 0
  • 0
  • 1727
article-image-phplist-2-e-mail-campaign-manager-personalizing-e-mail-body
Packt
26 Jul 2011
5 min read
Save for later

phpList 2 E-mail Campaign Manager: Personalizing E-mail Body

Packt
26 Jul 2011
5 min read
Enhancing messages using built-in placeholders For simple functionality's sake, we generally want our phpList messages to contain at least a small amount of customization. For example, even the default footer, which phpList attaches to messages, contains three placeholders, customizing each message for each recipient: -- If you do not want to receive any more newsletters, [UNSUBSCRIBE] To update your preferences and to unsubscribe, visit [PREFERENCES] Forward a Message to Someone [FORWARD] The placeholders [UNSUBSCRIBE],[PREFERENCES], and [FORWARD] will be replaced with unique URLs per subscriber, allowing any subscriber to immediately unsubscribe, adjust their preferences, or forward a message to a friend simply by clicking on a link. There's a complete list of available placeholders documented on phpList's wiki page at http://docs.phplist.com/Placeholders. Here are some of the most frequently used ones: [CONTENT]: Use this while creating standard message templates. You can design a styled template which is re-used for every mailing and the [CONTENT] placeholder will be replaced with the unique content for that particular message. [EMAIL]: This is replaced by the user's e-mail address. It can be very helpful in the footer of an e-mail, so that subscribers know which e-mail address they used to sign up for list subscription. [LISTS]: The lists to which a member is subscribed. Having this information attached to system confirmation messages makes it easy for subscribers to manage their own subscriptions. Note that this placeholder is only applicable in system messages and not in general list messages. [UNSUBSCRIBEURL]: Almost certainly, you'll want to include some sort of "click here to unsubscribe" link on your messages, either as a pre-requisite for sending bulk mail (perhaps imposed by your ISP) or to avoid users inadvertently reporting you for spamming. [UNSUBSCRIBE]: This placeholder generates the entire hyperlink for you (including the link text, "unsubscribe"), whereas the [UNSUBSCRIBEURL] placeholder simply generates the URL. You would use the URL only if you wanted to link an image to the unsubscription page, as opposed to a simple link, or if you wanted the HTML link text to be something other than "unsubscribe". [USERTRACK]: This inserts an invisible tracker image into HTML messages, helping you to measure the effectiveness of your newsletter. You might combine several of these placeholders to add a standard signature to your messages, as follows: -- You ([EMAIL]) are receiving this message because you subscribed to one or more of our mailing lists. We only send messages to subscribers who have requested and confirmed their subscription (double-opt-in). You can adjust your list membership at any time by clicking on [PREFERENCES] or unsubscribe altogether by clicking on [UNSUBSCRIBE]. -- Placeholders in confirmation messages Some placeholders (such as [LISTS]) are only applicable in confirmation messages (that is, "thank you for subscribing to the following lists..."). These placeholders allow you to customize the following: Request to confirm: Sent initially to users when they subscribe, confirming their e-mail address and subscription request Confirmation of subscription: Sent to users to confirm that they've been successfully added to the requested lists (after they've confirmed their e-mail address) Confirmation of preferences update: Sent to users to confirm their updates when they change their list subscriptions/preferences themselves Confirmation of unsubscription: Sent to users after they've unsubscribed to confirm that their e-mail address will no longer receive messages from phpList Personalizing messages using member attributes Apart from the built-in placeholders, you can also use any member attributes to further personalize your messages. Say you captured the following attributes from your new members: First Name Last Name Hometown Favorite Food You could craft a personalized message as follows: Dear [FIRST NAME], Hello from your friends at the Funky Town Restaurant. We hope the [LAST NAME] family is well in the friendly town of [HOMETOWN]. If you're ever in the mood for a fresh [FAVORITE FOOD], please drop in - we'd be happy to have you! ... This would appear to different subscribers as: Dear Bart, Hello from your friends at the Funky Town Restaurant. We hope the Simpson family is well in the friendly town of Springfield. If you're ever in the mood for a fresh pizza, please drop in - we'd be happy to have you! ... Or: Dear Clark, Hello from your friends at the Funky Town Restaurant. We hope the Kent family is well in the friendly town of Smallville. If you're ever in the mood for a fresh Krypto-Burger, please drop in - we'd be happy to have you! ... If a user doesn't have an attribute for a particular placeholder, it will be replaced with a blank space. For example, if user "Mary" hadn't entered any attributes, her message would look like: Dear, Hello from your friends at the Funky Town Restaurant. We hope the family is well in the friendly town of . If you're ever in the mood for a fresh , please drop in - we'd be happy to have you! ... If the attributes on your subscription form are optional, try to structure your content in such a way that a blank placeholder substitution won't ruin the text. For example, the following text will look awkward with blank substitutions: Your name is [FIRST NAME], your favorite food is [FAVORITE FOOD], and your last name is [LAST NAME] Whereas the following text would at least "degrade gracefully": Your name: [FIRST NAME] Your favorite food: [FAVORITE FOOD] Your last name [LAST NAME]
Read more
  • 0
  • 0
  • 1872

article-image-using-additional-solr-functionalities
Packt
26 Jul 2011
9 min read
Save for later

Using Additional Solr Functionalities

Packt
26 Jul 2011
9 min read
  Apache Solr 3.1 Cookbook Over 100 recipes to discover new ways to work with Apache’s Enterprise Search Server         Read more about this book       (For more resources on this subject, see here.) Getting more documents similar to those returned in the results list Let's imagine a situation where you have an e-commerce library shop and you want to show users the books similar to the ones they found while using your application. This recipe will show you how to do that. How to do it... Let's assume that we have the following index structure (just add this to your schema.xml file's fields section): <field name="id" type="string" indexed="true" stored="true" required="true" /> <field name="name" type="text" indexed="true" stored="true" termVectors="true" /> The test data looks like this: <add> <doc> <field name="id">1</field> <field name="name">Solr Cookbook first edition</field> </doc> <doc> <field name="id">2</field> <field name="name">Solr Cookbook second edition</field> </doc> <doc> <field name="id">3</field> <field name="name">Solr by example first edition</field> </doc> <doc> <field name="id">4</field> <field name="name">My book second edition</field> </doc> </add> Let's assume that our hypothetical user wants to find books that have first in their names. However, we also want to show him the similar books. To do that, we send the following query: http://localhost:8983/solr/select?q=name:edition&mlt=true&mlt. fl=name&mlt.mintf=1&mlt.mindf=1 The results returned by Solr are as follows: <?xml version="1.0" encoding="UTF-8"?> <response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">1</int> <lst name="params"> <str name="mlt.mindf">1</str> <str name="mlt.fl">name</str> <str name="q">name:edition</str> <str name="mlt.mintf">1</str> <str name="mlt">true</str> </lst> </lst> <result name="response" numFound="1" start="0"> <doc> <str name="id">3</str> <str name="name">Solr by example first edition</str> </doc> </result> <lst name="moreLikeThis"> <result name="3" numFound="3" start="0"> <doc> <str name="id">1</str> <str name="name">Solr Cookbook first edition</str> </doc> <doc> <str name="id">2</str> <str name="name">Solr Cookbook second edition</str> </doc> <doc> <str name="id">4</str> <str name="name">My book second edition</str> </doc> </result> </lst> </response> Now let's see how it works. How it works... As you can see, the index structure and the data are really simple. One thing to notice is that the termVectors attribute is set to true in the name field definition. It is a nice thing to have when using more like this component and should be used when possible in the fields on which we plan to use the component. Now let's take a look at the query. As you can see, we added some additional parameters besides the standard q one. The parameter mlt=true says that we want to add the more like this component to the result processing. Next, the mlt.fl parameter specifies which fields we want to use with the more like this component. In our case, we will use the name field. The mlt.mintf parameter tells Solr to ignore terms from the source document (the ones from the original result list) with the term frequency below the given value. In our case, we don't want to include the terms that will have the frequency lower than 1. The last parameter, mlt.mindf, tells Solr that the words that appear in less than the value of the parameter documents should be ignored. In our case, we want to consider words that appear in at least one document. Finally, let's take a look at the search results. As you can see, there is an additional section (<lst name="moreLikeThis">) that is responsible for showing us the more like this component results. For each document in the results, there is one more similar section added to the response. In our case, Solr added a section for the document with the unique identifier 3 (<result name="3" numFound="3" start="0">) and there were three similar documents found. The value of the id attribute is assigned the value of the unique identifier of the document that the similar documents are calculated for. Presenting search results in a fast and easy way Imagine a situation where you have to show a prototype of your brilliant search algorithm made with Solr to the client. But the client doesn't want to wait another four weeks to see the potential of the algorithm, he/she wants to see it very soon. On the other hand, you don't want to show the pure XML results page. What to do then? This recipe will show you how you can use the Velocity response writer (a.k.a. Solritas) to present a prototype fast. How to do it... Let's assume that we have the following index structure (just add this to your schema.xml file to the fields section): <field name="id" type="string" indexed="true" stored="true" required="true" /> <field name="name" type="text" indexed="true" stored="true" /> The test data looks like this: <add> <doc> <field name="id">1</field> <field name="name">Solr Cookbook first edition</field> </doc> <doc> <field name="id">2</field> <field name="name">Solr Cookbook second edition</field> </doc> <doc> <field name="id">3</field> <field name="name">Solr by example first edition</field> </doc> <doc> <field name="id">4</field> <field name="name">My book second edition</field> </doc> </add> We need to add the response writer definition. To do this, you should add this to your solrconfig.xml file (actually this should already be in the configuration file): <queryResponseWriter name="velocity" class="org.apache.solr. request.VelocityResponseWriter"/> Now let's set up the Velocity response writer. To do that we add the following section to the solrconfig.xml file (actually this should already be in the configuration file): <requestHandler name="/browse" class="solr.SearchHandler"> <lst name="defaults"> <str name="wt">velocity</str> <str name="v.template">browse</str> <str name="v.layout">layout</str> <str name="title">Solr cookbook example</str> <str name="defType">dismax</str> <str name="q.alt">*:*</str> <str name="rows">10</str> <str name="fl">*,score</str> <str name="qf">name</str> </lst> </requestHandler> Now you can run Solr and type the following URL address: http://localhost:8983/solr/browse You should see the following page: (Move the mouse over the image to enlarge it.) How it works... As you can see, the index structure and the data are really simple, so I'll skip discussing this part of the recipe. The first thing in configuring the solrconfig.xml file is adding the Velocity Response Writer definition. By adding it, we tell Solr that we will be using velocity templates to render the view. Now we add the search handler to use the Velocity Response Writer. Of course, we could pass the parameters with every query, but we don't want to do that, we want them to be added by Solr automatically. Let's go through the parameters: wt: The response writer type; in our case, we will use the Velocity Response Writer. v.template: The template that will be used for rendering the view; in our case, the template that Velocity will use is in the browse.vm file (the vm postfix is added by Velocity automatically). This parameter tells Velocity which file is responsible for rendering the actual page contents. v.layout: The layout that will be used for rendering the view; in our case, the template that velocity will use is in the layout.vm file (the vm postfix is added by velocity automatically). This parameter specifies how all the web pages rendered by Solritas will look like. title: The title of the page. defType: The parser that we want to use. q.alt: Alternate query for the dismax parser in case the q parameter is not defined. rows: How many maximum documents should be returned. fl: Fields that should be listed in the results. qf: The fields that we should be searched. Of course, the page generated by the Velocity Response Writer is just an example. To modify the page, you should modify the Velocity files, but this is beyond the scope of this article. There's more... If you are still using Solr 1.4.1 or 1.4, there is one more thing that can be useful. Running Solritas on Solr 1.4.1 or 1.4 Because the Velocity Response Writer is a contrib module in Solr 1.4.1, we need to do the following operations to use it. Copy the following libraries from the /contrib/velocity/ src/main/solr/lib directory to the /lib directory of your Solr instance: apache-solr-velocity-1.4.dev.jar commons-beanutils-1.7.0.jar commons-collections-3.2.1.jar velocity-1.6.1.jar velocity-tools-2.0-beta3.jar Then copy the contents of the /velocity (with the directory) directory from the code examples to your Solr configuration directory.
Read more
  • 0
  • 0
  • 1210

article-image-being-cross-platform-haxe
Packt
26 Jul 2011
10 min read
Save for later

Being Cross-platform with haXe

Packt
26 Jul 2011
10 min read
  haXe 2 Beginner's Guide Develop exciting applications with this multi-platform programming language What is cross-platform in the library The standard library includes a lot of classes and methods, which you will need most of the time in a web application. So, let's have a look at the different features. What we call standard library is simply a set of objects, which is available when you install haXe. Object storage The standard library offers several structures in which you can store objects. In haXe, you will see that, compared to many other languages, there are not many structures to store objects. This choice has been made because developers should be able to do what they need to do with their objects instead of dealing with a lot of structures, which they have to cast all the time. The basic structures are array, list, and hash. All of these have a different utility: Objects stored in an array can be directly accessed by using their index Objects in a list are linked together in an ordered way Objects in an hash are tied to what are called "keys", but instead of being an Int, keys are a String There is also the IntHash structure that is a hash-table using Int values as keys. These structures can be used seamlessly in all targets. This is also, why the hash only supports String as indexes: some platforms would require a complex class that would impair performances to support any kind of object as indexes. The Std class The Std class is a class that contains methods allowing you to do some basic tasks, such as parsing a Float or an Int from a String, transforming a Float to an Int, or obtaining a randomly generated number. This class can be used on all targets without any problems. The haxe package The haxe package (notice the lower-case x) contains a lot of class-specific to haXe such as the haxe.Serializer class that allows one to serialize any object to the haXe serialization format or its twin class haxe.Unserializer that allows one to unserialize objects (that is "reconstruct" them). This is basically a package offering extended cross-platform functionalities. The classes in the haxe package can be used on all platforms most of the time. The haxe.remoting package This package also contains a remoting package that contains several classes allowing us to use the haXe remoting protocol. This protocol allows several programs supporting it to communicate easily. Some classes in this package are only available for certain targets because of their limitations. For example, a browser environment won't allow one to open a TCP socket, or Flash won't allow one to create a server. Remoting will be discussed later, as it is a very interesting feature of haXe. The haxe.rtti package There's also the rtti package. RTTI means Run Time Type Information. A class can hold information about itself, such as what fields it contains and their declared types. This can be really interesting in some cases, such as, if you want to create automatically generated editors for some objects. The haxe.Http class The haxe.Http class is one you are certainly going to use quite often. It allows you to make HTTP requests and retrieve the answer pretty easily without having to deal with the HTTP protocol by yourself. If you don't know what HTTP is, then you should just know that it is the protocol used between web browsers and servers. On a side-note, the ability to make HTTPS requests depends on the platform. For example, at the moment, Neko doesn't provide any way to make one, whereas it's not a problem at all on JS because this functionality is provided by the browser. Also, some methods in this class are only available on some platforms. That's why, if you are writing a cross-platform library or program, you should pay attention to what methods you can use on all the platforms you want to target. You should note that on JS, the haxe.Http class uses HttpRequest objects and as such, they suffer from security restrictions, the most important one being the same-domain policy. This is something that you should keep in mind, when thinking about your solution's architecture. You can make a simple synchronous request by writing the following: var answer = Http.requestUrl("http://www.benjamindasnois.com"); It is also possible to make some asynchronous requests as follows: var myRequest = new Http("http://www.benjamindasnois.com"); myRequest.onData = function (d : String) { Lib.println(d); } myRequest.request(false); This method also allows you to get more information about the answer, such as the headers and the return code. The following is an example displaying the answer's headers: import haxe.Http; #if neko import neko.Lib; #elseif php import php.Lib; #end class Main { static function main() { var myRequest = new Http("http://www.benjamindasnois.com"); myRequest.onData = function (d : String) { for (k in myRequest.responseHeaders.keys()) { Lib.println(k + " : " + myRequest.responseHeaders.get(k)); } }; myRequest.request(false); } } The following is what it displays: X-Cache : MISS from rack1.tumblr.com X-Cache-Lookup : MISS from rack1.tumblr.com:80 Via : 1.0 rack1.tumblr.com:80 (squid/2.6.STABLE6) P3P : CP="ALL ADM DEV PSAi COM OUR OTRo STP IND ONL" Set-Cookie : tmgioct=h6NSbuBBgVV2IH3qzPEPPQLg; expires=Thu, 02-Jul-2020 23:30:11 GMT; path=/; httponly ETag : f85901c583a154f897ba718048d779ef Link : <http://assets.tumblr.com/images/default_avatar_16.gif>; rel=icon Vary : Accept-Encoding Content-Type : text/html; charset=UTF-8 Content-Length : 30091 Server : Apache/2.2.3 (Red Hat) Date : Mon, 05 Jul 2010 23:31:10 GMT X-Tumblr-Usec : D=78076 X-Tumblr-User : pignoufou X-Cache-Auto : hit Connection : close Regular expressions and XML handling haXe offers a cross-platform API for regular expressions and XML that can be used on most targets' target. Regular expressions The regular expression API is implemented as the EReg class. You can use this class on any platform to match a RegExp, split a string according to a RegExp, or do some replacement. This class is available on all targets, but on Flash, it only starts from Flash 9. The following is an example of a simple function that returns true or false depending on if a RegExp matches a string given as parameter: public static function matchesHello(str : String) : Bool { var helloRegExp = ~/.*hello.*/; return helloRegExp.match(str); } One can also replace what is matched by the RegExp and return this value. This one simply replaces the word "hello" with "bye", so it's a bit of an overkill to use a RegExp to do that, and you will find some more useful ways to use this possibility when making some real programs. Now, at least you will know how to do it: public static function replaceHello(str : String) : String { var helloRegExp = ~/hello/; helloRegExp.match(str); return helloRegExp.replace(str, "bye"); } XML handling The XML class is available on all platforms. It allows you to parse and emit XML the same way on many targets. Unfortunately, it is implemented using RegExp on most platforms, and therefore can become quite slow on big files. Such problems have already been raised on the JS targets, particularly on some browsers, but you should keep in mind that different browsers perform completely differently. For example, on the Flash platform, this API is now using the internal Flash XML libraries, which results in some incompatibilities. The following is an example of how to create a simple XML document: <pages> <page id="page1"/> <page id="page2"/> </pages> Now, the haXe code to generate it: var xmlDoc : Xml; var xmlRoot : Xml; xmlDoc = Xml.createDocument(); //Create the document xmlRoot = Xml.createElement("pages"); //Create the root node xmlDoc.addChild(xmlRoot); //Add the root node to the document var page1 : Xml; page1 = Xml.createElement("page"); //create the first page node page1.set("id", "page1"); xmlRoot.addChild(page1); //Add it to the root node var page2 : Xml; page2 = Xml.createElement("page"); page2.set("id", "page2"); xmlRoot.addChild(page2); trace(xmlDoc.toString()); //Print the generated XML Input and output Input and output are certainly the most important parts of an application; indeed, without them, an application is almost useless. If you think about how the different targets supported by haXe work and how the user may interact with them, you will quickly come to the conclusion that they use different ways of interacting with the user, which are as follows: JavaScript in the browser uses the DOM Flash has its own API to draw on screen and handle events Neko uses the classic input/output streams (stdin, stdout, stderr) and so do PHP and C++ So, we have three different main interfaces: DOM, Flash, and classic streams. The DOM interface The implementation of the DOM interface is available in the js package. This interface is implemented through typedefs. Unfortunately, the API doesn't provide any way to abstract the differences between browsers and you will have to deal with them in most cases by yourself. This API is simply telling the compiler what objects exist in the DOM environment; so, if you know how to manipulate the DOM in JavaScript, you will be able to manipulate it in haXe. The thing that you should know is that the document object can be accessed through js.Lib.document. The js package is accessible only when compiling to JS. The Flash interface In a way that is similar to how the Flash is implemented in the flash and flash9 packages, the js package implements the DOM interface. When reading this sentence, you may wonder why there are two packages. The reason is pretty simple, the Flash APIs pre and post Flash 9 are different. You also have to pay attention to the fact that, when compiling to Flash 9, the flash9 package is accessible through the flashpath and not through flash9. Also, at the time of writing, the documentation for flash and flash9 packages on haxe. org is almost non-existent; but, if you need some documentation, you can refer to the official documentation. The standard input/output interface The standard input/output interface refers to the three basic streams that exist on most systems, which are as follows: stdin (most of the time the keyboard). stdout (the standard output which is most of the time the console, or, when running as a web-application, the stream sent to the client). stderr (the standard error output which is most of the time directed to the console or the log file). Neko, PHP and C++ all make use of this kind of interface. Now, there are two pieces news for you: one good and one bad. The bad one is that the API for each platform is located in a platform-specific package. So, for example, when targeting Neko, you will have to use the neko package, which is not available in PHP or C++. The good news is that there is a workaround. Well, indeed, there are three. You just have to continue reading through this article and I'll tell you how to handle that.  
Read more
  • 0
  • 0
  • 1411
article-image-mootools-extending-and-implementing-elements
Packt
25 Jul 2011
7 min read
Save for later

MooTools: Extending and Implementing Elements

Packt
25 Jul 2011
7 min read
  MooTools 1.3 Cookbook Over 100 highly effective recipes to turbo-charge the user interface of any web-enabled Internet application and web page The reader can benefit from the previous article on Extending MooTools. Extending elements—preventing multiple form submissions Imagine a scenario where click-happy visitors may undo normalcy by double-clicking the submit button, or perhaps an otherwise normal albeit impatient user might click it a second time. Submit buttons frequently need to be disabled or removed using client-side code for just such a reason. Users that double-click everything It is not entirely known where double-clicking users originated from. Some believe that single-clicking-users needed to be able to double-click to survive in the wild. They therefore began to grow gills and double-click links, buttons, and menu items. Others maintain that there was a sudden, large explosion in the vapors of nothingness that resulted in hordes of users that could not fathom the ability of a link, button, or menu item that could be opened with just a single click. Either way, they are out there, and they mostly use Internet Explorer and are quickly identifiable by how they type valid URLs into search bars and then swear the desired website is no longer on the Inter-nets. How to do it... Extending elements uses the same syntax as extending classes. Add a method that can be called when appropriate. Our example, the following code, could be used in a library that is associated with every page so that no submit button could ever again be clicked twice, at least, without first removing the attribute that has it disabled: Element.implement({ better_submit_buttons: function() { if ( this.get('tag')=='input' && this.getProperty('type')=='submit') { this.addEvent('click', function(e) { this.set({ 'disabled':'disabled', 'value':'Form Submitted!' }); }); } } }); window.addEvent('load',function() { $$('input[type=submit]').better_submit_buttons(); }); How it works... The MooTools class Element extends DOM elements referenced by the single-dollar selector, the double-dollars selector, and the document.id selector. In the onLoad event, $$('input[type=submit]').submit_only_once(); all INPUT elements that have a type equal to submit are extended with the Element class methods and properties. Of course, before that infusion of Moo-goodness takes place, we have already implemented a new method that prevents those elements from being clicked twice by adding the property that disables the element. There's more... In our example, we disable the submit button permanently and return false upon submission. The only way to get the submit button live again is to click the Try again button that calls the page again. Note that reloading the page via refresh in some browsers may not clear the disabled attribute; however, calling the page again from the URL or by clicking a link will. On pages that submit a form to a second page for processing, the semi-permanently disabled button is desirable outright. If our form is processed via Ajax, then we can use the Ajax status events to manually remove the disabled property and reset the value of the button. See also Read the document on the MooTools Request class that shows the various statuses that could be used in conjunction with this extended element: http://mootools.net/docs/core/Request/Request.   Extending elements-prompt for confirmation on submit Launching off the last extension, the forms on our site may also need to ask for confirmation. It is not unthinkable that a slip of the carriage return could accidentally submit a form before a user is ready. It certainly happens to all of us occasionally and perhaps to some of us regularly. How to do it... Mutate the HTML DOM FORM elements to act upon the onSubmit event and prompt whether to continue with the submission. Element.implement({ polite_forms: function() { if (this.get('tag')=='form') { this.addEvent('submit',function(e) { if(!confirm('Okay to submit form?')) { e.stop(); } }); } } }); How it works... The polite_forms() method is added to all HTML DOM elements, but the execution is restricted to elements whose tag is form, if (this.get('tag')=='form') {...}. The onSubmit event of the form is bound to a function that prompts users via the raw JavaScript confirm() dialogue that either returns true for a positive response or false otherwise. If false, then we prevent the event from continuing by calling the MooTools-implemented Event.stop(). There's more... In order to mix the submit button enhancement with the polite form enhancement only a few small changes to the syntax are necessary. To stop our submit button from showing in process... if the form submission is canceled by the polite form request, we create a proprietary reset event that can be called via Element.fireEvent() and chained to the collection of INPUT children that match our double-dollar selector. // extend all elements with the method polite forms Element.implement({ better_submit_buttons: function() { if (this.get('tag')=='input'&&this.getProperty('type')=='submit') { this.addEvents({ 'click':function(e) { this.set({'disabled':'disabled','value':'in process...'}); }, 'reset':function() { this.set({'disabled':false,'value':'Submit!'}); } }); } }, polite_forms: function() { if (this.get('tag')=='form') { this.addEvent('submit',function(e) { if(!confirm('Okay to submit form?')) { e.stop(); this.getChildren('input[type=submit]').fireEvent('reset'); } }); } } }); // enhance the forms window.addEvent('load',function() { $$('input[type=submit]').better_submit_buttons(); $$('form').polite_forms(); });   Extending typeOf, fixing undefined var testing We could not properly return the type of an undeclared variable. This oddity has its roots in the fact that undefined, undeclared variables cannot be dereferenced during a function call. In short, undeclared variables can not be used as arguments to a function. Getting ready Get ready to see how we can still extend MooTools' typeOf function by passing a missing variable using the global scope: // will throw a ReferenceError myfunction(oops_var); // will not throw a ReferenceError myfunction(window.oops_var); How to do it... Extend the typeOf function with a new method and call that rather than the parent method. // it is possible to extend functions with new methods typeOf.extend('defined',function(item) { if (typeof(item)=='undefined') return 'undefined'; else return typeOf(item); }); //var oops_var; // commented out "on purpose" function report_typeOf(ismoo) { if (ismoo==0) { document.write('oops_var1 is: '+typeof(oops_var)+'<br/>'); } else { // concat parent to avoid error from derefrencing an undeclared var document.write('oops_var2 is: '+typeOf.defined( window.oops_var)+'<br/>'); } } The output from calling typeof() and typeOf.defined() is identical for an undefined, undeclared variable passed via the global scope to avoid a reference error. <h2>without moo:</h2> <script type="text/javascript"> report_typeOf(0); </script> <h2><strong>with</strong> moo:</h2> <script type="text/javascript"> report_typeOf(1); </script> The output is: without moo: oops_var1 is: undefined with moo: oops_var2 is: undefined How it works... The prototype for the typeOf function object has been extended with a new method. The original method is still applied when the function is executed. However, we are now able to call the property defined, which is itself a function that can still reference and call the original function. There's more... For those that are not satisfied at the new turn of syntax, the proxy pattern should suffice to help keep us using a much similar syntax. // proxying in raw javascript is cleaner in this case var oldTypeOf = typeOf; var typeOf = function(item) { if (typeof(item)=='undefined') return 'undefined'; else return oldTypeOf(item); }; The old typeOf function has been renamed using the proxy pattern but is still available. Meanwhile, all calls to typeOf are now handled by the new version. See also The Proxy Pattern The proxy pattern is one of many JavaScript design patterns. Here is one good link to follow for more information: http://www.summasolutions.net/blogposts/design-patterns-javascript-part-1. Undeclared and Undefined Variables It can be quite daunting to have to deal with multiple layers of development. When we are unable to work alone and be sure all our variables are declared properly, testing every one can really cause code bloat. Certainly, the best practice is to always declare variables. Read more about it at http://javascriptweblog.wordpress.com/2010/08/16/understanding-undefined-and-preventing-referenceerrors/.  
Read more
  • 0
  • 0
  • 3899

article-image-extending-mootools
Packt
25 Jul 2011
8 min read
Save for later

Extending MooTools

Packt
25 Jul 2011
8 min read
  MooTools 1.3 Cookbook Over 100 highly effective recipes to turbo-charge the user interface of any web-enabled Internet application and web page         Read more about this book       (For more resources on this topic, see here.) The reader can benefit from the previous article on MooTools: Extending and Implementing Elements.   Making a Corvette out of a car-extending the base class The "base class" is a function, a method, that allows extension. Just what does extending a class entail? Buckle up and let us take a drive. Getting ready Just to show the output of our work, create a DIV that will be our canvas. <div id="mycanvas"></div> How to do it... Creating a class from the base class is as rudimentary as this: var Car = new Class();. That is not very instructive, so at the least, we add the constructor method to call at the time of instantiation: initialize. <script type="text/javascript"> var Car = new Class({ initialize: function(owner) { this.owner = owner; }}); The constructor method takes the form of a property named initialize and must be a function; however, it does not have to be the first property declared in the class. How it works... So far in our recipe, we have created an instance of the base class and assigned it to the variable Car. We like things to be sporty, of course. Let's mutate the Car into a Corvette using Extends and passing it the name of the Class to make a copy of and extend into a new class. var Corvette = new Class({ Extends: Car, mfg: 'Chevrolet', model: 'Corvette', setColor: function(color) { this.color = color; }}); Our Corvette is ready for purchase. An instantiation of the extended class will provide some new owner happiness for 5 years or 50,000 miles, whichever comes first. Make the author's red, please. var little_red = new Corvette('Jay Johnston'); little_red.setColor('red'); $('mycanvas').set('text',little_red.owner+"'s little "+little_red.color+' '+little_red.model+' made by '+little_red.mfg); </script> There's more... This entire example will work identically if Corvette Implements rather than Extends Car. Whether to Extend or to Implement Extending a class changes the prototype, creating a copy in which the this.parent property allows for the overridden parent class method to be referenced within the extended class's current method. To derive a mutation that takes class properties from multiple classes, we use Implements. Be sure to place the Extends or Implements property first before all other methods and properties. And if both extending and implementing, the Implements property follows the Extends property. See also See how Moo can muster so much class: http://mootools.net/docs/core/Class/Class#Class.   Giving a Corvette a supercharger-Implements versus Extends Be ready to watch for several things in this recipe. Firstly, note how the extended corvette methods can use this.parent. Secondly, note how the implemented corvette, the ZR1, can implement multiple classes. Getting ready Create a canvas to display some output. <h1>Speed Indexes:</h1><div id="mycanvas"></div> How to do it... Here we create a class to represent a car. This car does not have an engine until it goes through further steps of manufacturing, so if we ask what its speed is, the output is zero. Next, we create a class to represent a sporty engine, which has an arbitrary speed index of 10. // create two classes from the base Class var Car = new Class({ showSpeed: function() { return 0; } }); var SportyEngine = new Class({ speed: 10 }); Now we get to work. First, we begin by manufacturing corvettes, a process which is the extension of Car, they are faster than an empty chassis, of course, so we have them report their speed as an index rating one more than the parent class. // Extend one, Implement the other var Corvette = new Class({ Extends: Car, showSpeed: function() { // this.parent calls the overridden class return this.parent()+1; } }); Secondly, we implement both Car and SportyEngine simultaneously as ZR1. We cannot use this.parent so we return the speed if asked. Of course, the ZR1 would not have a speed if only a mutation of Car, but since it is also a mutation of SportyEngine it has the speed index of that class. var ZR1 = new Class({ // multiple classes may be implemented Implements: [Car, SportyEngine], // yep showSpeed: function() { // this.parent is not available //return this.parent()+1; // nope return this.speed; }}); How it works... When an instantiation of Corvette is created and its showSpeed() method called, it reports the speed of the parent class, Car, adding 1 to it. This is thanks to the magic Extends provides via this.parent(). var corvette = new Corvette(); var zr1 = new ZR1(); $('mycanvas').set('html', '<table>'+ '<tr><th>Corvette:</th>'+ '<td>'+corvette.showSpeed()+'</td></tr>'+ '<tr><th>ZR1:</th>'+ '<td>'+zr1.showSpeed()+'</td></tr>'+ '</table>'); And so, the output of this would be: Corvette: 1ZR1: 10 An instantiation of ZR1 has the properties of all classes passed to Implements. When showSpeed() is called, the value conjured by this.speed comes from the property defined within SportyEngine.   Upgrading some Corvettes—Extends versus Implements Now that we have reviewed some of the reasons to extend versus implement, we are ready to examine more closely how inheritance within Extends can be useful in our scripting. Getting ready Create a display area for the output of our manufacturing plant. <h1>Speeds Before</h1><div id="before"></div><h1>Speeds After</h1><div id="after"></div> How to do it... Create two classes, one that represents all car chassis with no engine and one that represents a fast engine that can be ordered as an upgrade. This section is identical to the last recipe; if necessary, review once more before continuing as the jist will be to alter our instantiations to display how inheritance patterns affect them. // create two classes from the base Class var Car = new Class({ showSpeed: function() { return 0; } }); var SportyEngine = new Class({ speed: 10 }); // Extend one, Implement the other var Corvette = new Class({ Extends: Car, speed: 1, showSpeed: function() { // this.parent calls the overridden class return this.parent()+1; } }); var ZR1 = new Class({ // multiple classes may be implemented Implements: [Car, SportyEngine], // yep showSpeed: function() { // this.parent is not available //return this.parent()+1; // nope return this.speed; } }); Note that the output before mutation is identical to the end of the previous recipe. var corvette = new Corvette(); var zr1 = new ZR1(); $('before').set('html', '<table>'+ '<tr><th>Corvette:</th>'+ '<td>'+corvette.showSpeed()+'</td></tr>'+ '<tr><th>ZR1</th>'+ '<td>'+zr1.showSpeed()+'</td></tr>'+ '</table>'); Here is what happens when the manufacturing plant decides to start putting engines in the base car chassis. That gives them a speed, where they did not have one previously. Mutate the base class by having it return an index of five rather than zero. // the mfg changes base Car speed to be +5 fasterCar = Car.implement({ showSpeed: function() { return 5; }});// but SportyEngine doesn't use the parent method$('after').set('html', '<table>'+ '<tr><th>New Corvette:</th>'+ '<td>'+corvette.showSpeed()+'</td></tr>'+ '<tr><th>New ZR1</th>'+ '<td>'+zr1.showSpeed()+'</td></tr>'+ '</table>'); How it works... The zr1 instantiation did not mutate. The corvette instantiation did. Since zr1 used implements, there is no inheritance that lets it call the parent method. In our example, this makes perfect sense. The base chassis comes with an engine rated with a speed of five. The ZR1 model, during manufacturing/instantiation is given a completely different engine/a completely different property, so any change/recall of the original chassis would not be applicable to that model. For the naysayer, the next recipe shows how to effect a manufacturer recall that will alter all Corvettes, even the ZR1s. There's more... There is an interesting syntax used to mutate the new version of Car, Class.implement(). That same syntax is not available to extend elements. See also Here is a link to the MooTool documentation for Class.implement(): http://mootools.net/docs/core/Class/Class#Class:implement.  
Read more
  • 0
  • 0
  • 3152