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
Explore 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

1802 Articles
article-image-understanding-and-developing-node-modules
Packt
11 Aug 2011
5 min read
Save for later

Understanding and Developing Node Modules

Packt
11 Aug 2011
5 min read
Node Web Development A practical introduction to Node, the exciting new server-side JavaScript web development stack What's a module? Modules are the basic building block of constructing Node applications. We have already seen modules in action; every JavaScript file we use in Node is itself a module. It's time to see what they are and how they work. The following code to pull in the fs module, gives us access to its functions: var fs = require('fs'); The require function searches for modules, and loads the module definition into the Node runtime, making its functions available. The fs object (in this case) contains the code (and data) exported by the fs module. Let's look at a brief example of this before we start diving into the details. Ponder over this module, simple.js: var count = 0; exports.next = function() { return count++; } This defines an exported function and a local variable. Now let's use it: The object returned from require('./simple') is the same object, exports, we assigned a function to inside simple.js. Each call to s.next calls the function next in simple.js, which returns (and increments) the value of the count variable, explaining why s.next returns progressively bigger numbers. The rule is that, anything (functions, objects) assigned as a field of exports is exported from the module, and objects inside the module but not assigned to exports are not visible to any code outside the module. This is an example of encapsulation. Now that we've got a taste of modules, let's take a deeper look. Node modules Node's module implementation is strongly inspired by, but not identical to, the CommonJS module specification. The differences between them might only be important if you need to share code between Node and other CommonJS systems. A quick scan of the Modules/1.1.1 spec indicates that the differences are minor, and for our purposes it's enough to just get on with the task of learning to use Node without dwelling too long on the differences. How does Node resolve require('module')? In Node, modules are stored in files, one module per file. There are several ways to specify module names, and several ways to organize the deployment of modules in the file system. It's quite flexible, especially when used with npm, the de-facto standard package manager for Node. Module identifiers and path names Generally speaking the module name is a path name, but with the file extension removed. That is, when we write require('./simple'), Node knows to add .js to the file name and load in simple.js. Modules whose file names end in .js are of course expected to be written in JavaScript. Node also supports binary code native libraries as Node modules. In this case the file name extension to use is .node. It's outside our scope to discuss implementation of a native code Node module, but this gives you enough knowledge to recognize them when you come across them. Some Node modules are not files in the file system, but are baked into the Node executable. These are the Core modules, the ones documented on nodejs.org. Their original existence is as files in the Node source tree but the build process compiles them into the binary Node executable. There are three types of module identifiers: relative, absolute, and top-level. Relative module identifiers begin with "./" or "../" and absolute identifiers begin with "/". These are identical with POSIX file system semantics with path names being relative to the file being executed. Absolute module identifiers obviously are relative to the root of the file system. Top-level module identifiers do not begin with "." , "..", or "/" and instead are simply the module name. These modules are stored in one of several directories, such as a node_modules directory, or those directories listed in the array require.paths, designated by Node to hold these modules. Local modules within your application The universe of all possible modules is split neatly into two kinds, those modules that are part of a specific application, and those modules that aren't. Hopefully the modules that aren't part of a specific application were written to serve a generalized purpose. Let's begin with implementation of modules used within your application. Typically your application will have a directory structure of module files sitting next to each other in the source control system, and then deployed to servers. These modules will know the relative path to their sibling modules within the application, and should use that knowledge to refer to each other using relative module identifiers. For example, to help us understand this, let's look at the structure of an existing Node package, the Express web application framework. It includes several modules structured in a hierarchy that the Express developers found to be useful. You can imagine creating a similar hierarchy for applications reaching a certain level of complexity, subdividing the application into chunks larger than a module but smaller than an application. Unfortunately there isn't a word to describe this, in Node, so we're left with a clumsy phrase like "subdivide into chunks larger than a module". Each subdivided chunk would be implemented as a directory with a few modules in it. In this example, the most likely relative module reference is to utils.js. Depending on the source file which wants to use utils.js it would use one of the following require statements: var utils = require('./lib/utils'); var utils = require('./utils'); var utils = require('../utils');  
Read more
  • 0
  • 0
  • 3473

article-image-jquery-ui-themes-states-cues-overlays-and-shadows
Packt
05 Aug 2011
7 min read
Save for later

jQuery UI Themes: States, Cues, Overlays and Shadows

Packt
05 Aug 2011
7 min read
jQuery UI Themes Beginner's Guide Create new themes for your JQuery site with this step-by-step guide States jQueryUi widgets are always in one state or another. These states also play a role in themes. A widget in one state should look different than widgets in another state. These different appearances are controlled by CSS style properties within the theme. States are especially prevalent in widgets that interact with mouse events. When a user hovers over a widget that is interested in these types of events, the widget changes into a hover state. When the mouse leaves the widget, it returns to a default state. Even when nothing is happening with a widget—no events are taking place that the widget is interested in—the widget is in a default state. The reason we need a default state for widgets is so that they can return to their default appearance. The appearance of these states is entirely controlled through the applied theme. In this section, we'll change the ThemeRoller settings for widget states. Time for action - setting default state styles Some widgets that interact with the mouse have a default state applied to them. We can adjust how this state changes the appearance of the widget using ThemeRoller settings: Continuing with our theme design, expand the Clickable: default state section. In the Background color & texture section, click on the texture selector in the middle. Select the inset hard texture. In the Background color & texture section, set the background opacity to 65%. Change the Border color setting value to #b0b0b0. Change the Icon color setting value to #555555: What just happened? We've just changed the look and feel of the default widget state. We changed the background texture to match that of the header theme settings. Likewise, we also changed the background opacity to 65%, also to match the header theme settings. The border color is now slightly darker - this looks better with the new default state background settings. Finally, the icon color was updated to match the default state font color. Here is what the sample button looked like before we made our changes: Here is what the sample button looks like after we've updated our theme settings: Time for action - setting hover state styles The same widgets that may be in a default state, for instance, a button, may also be in a hover state. Widgets enter a hover state when a user moves the mouse pointer over the widget. We want our user interface to give some kind of visual indication that the user has hovered over something they can click. It's time to give our theme some hover state styles: Continuing with our theme design, expand the Clickable: hover state section. In the Background color & texture section, click on the texture selector in the middle. Select the inset hard texture. Change the Border color setting value to #787878. Change the Icon color setting value to #212121: What just happened? When we hover over widgets that support the hover state, their appearance is now harmonized with our theme settings. The background texture was updated to match the texture of the default state styles. The border color is now slightly darker. This makes the widget really stand out when the user hovers over it. At the same, it isn't so dark that it conflicts with the rest of the theme settings. Finally, we updated the icon color to match that of the font color. Here is what the sample button widget looked like before we change the hover state settings: Here is what the sample button widget looked like after we updated the hover state theme settings: Time for action - setting active state styles Some jQuery UI widgets, the same widgets that can be in either a default or hover state, can also be in an active state. Widgets become active after a user clicks them. For instance, the currently selected tab in a tabs widget is in an active state. We can control the appearance of active widgets through the ThemeRoller: Continuing with our theme design, expand the Clickable: active state section. In the Background color & texture section, change the color setting value on the left to #f9f9f9. In the Background color & texture section, click the texture selector in the middle. Select the flat texture. In the Background color & texture section, set the opacity setting value on the right-hand side to 100%. Change the Border color setting value to #808080. Change the Icon color setting value to #212121: What just happened? Widgets in the active state will now use our updated theme styles. We've changed the background color to something only marginally darker. The reason being, we are using the highlight soft texture in our content theme settings. This means that the color gets lighter toward the top. The color at the top is what we're aiming for in the active state styles. The texture has been changed to flat. Flat textures, unlike the others, have no pattern - they're simply a color. Accordingly, we've changed the background opacity to 100%. We do this because for these theme settings, we're only interested in showing the color. The active state border is slightly darker, a visual cue to show that the widget is in fact active. Finally, like other adjustments we've made in our theme, the icon color now mirrors the text color. Here is what the sample tabs widget looked like before we changed the active state theme settings: Here is what the sample tabs widget looks like after we've updated the active state theme settings. Notice that the selected tab's border stands out among the other tabs and how the selected tab blends better with the tab content. Cues In any web application, it is important to have the ability to notify users of events that have taken place. Perhaps an order was successfully processed, or a registration field was entered incorrectly. Both occurrences are worth letting the user know about. These are types of cues. The jQuery UI theming framework defines two types of cues used to notify the user. These are highlights and errors. A highlight cue is informational, something that needs to be brought to the user's attention. An error is something exceptional that should not have happened. Both cue categories can be customized to meet the requirements of any theme. It is important to keep in mind that cues are meant to aggressively grab the attention of the user - not to passively display information. So the theme styles applied to these elements really stand out. In this section we'll take a look at how to make this happen with the ThemeRoller. Time for action - changing the highlight cue A user of your jQuery UI application has just saved something. How do they know it was successful? Your application needs to inform them somehow—it needs to highlight the fact that something interesting just happened. To do this, your application will display a highlight cue. Let's add some highlight styles to our theme: Continuing with our theme design, expand the Highlight section. In the Background color & texture section, change the color setting value to #faf2c7. In the Background color & texture section, change the opacity setting value to 85%. Change the Border color setting value to #f8df49. Change the Text color setting value to #212121: What just happened? The theme settings for any highlight cues we display for the user have been updated. The background color is a shade darker and the opacity has been increased by 10%. The border color is now significantly darker than the background color. The contrast between the background and border colors defined here are now better aligned with the background-border contrast defined in other theme sections. Finally, we've updated the text color to be the same as the text in other sections. This is not for a noticeable difference (there isn't any), but for consistency reasons. Here is what the sample highlight cue looked like before we updated the theme settings: Here is what the sample highlight widget looks like after the theme setting changes:
Read more
  • 0
  • 0
  • 2825

article-image-jquery-ui-themes-using-themeroller
Packt
04 Aug 2011
8 min read
Save for later

jQuery UI Themes: Using the ThemeRoller

Packt
04 Aug 2011
8 min read
jQuery UI Themes Beginner's Guide Create new themes for your JQuery site with this step-by-step guide ThemeRoller basics Before we start using the ThemeRoller application to design and build our own themes, we'll take a quick look at what makes it such a handy tool. There is a lot more to the ThemeRoller than simply changing themes—we also use it to build them. You can think of it as an IDE for jQuery UI themes. Instant feedback What makes the ThemeRoller application such a powerful development tool is the speed with which you get feedback to changes made in the theme design. Any change made in the ThemeRoller is instantaneously reflected in the sample widgets provided on the page. For instance, if I were to change a font setting, that change would be reflected immediately in the sample widgets provided on the same page. There is no need to update the application you're building to see the results of small adjustments made to theme style settings. The same is true of prepackaged themes in the ThemeRoller gallery. Selecting a theme will apply it to the same widgets - you get immediate feedback. This is very helpful in deciding on prepackaged themes. If you can see how it looks with jQuery UI widgets right away, that may dissuade you from using the theme or it may close the deal. The idea behind this feedback mechanism offered by the ThemeRoller is a sped-up development cycle. Eliminating several steps when developing anything, themes included, is a welcome feature. The dev tool The ThemeRoller dev tool is a simple bookmarket for Firefox that brings the entire ThemeRoller application into any page with jQuery UI widgets. The benefit of the dev tool is that it allows you to see immediate theme changes in the context of the application you're building. If you use the ThemeRoller application from the jQuery UI website, you can only see changes as they apply to the sample widgets provided. This can give you a better idea of what the theme changes will look like on a finished product. There are some limitations to using the dev tool though. If you're developing your application locally, not on a development server, you can't use the dev tool due to security restrictions. The dev tool is better suited for viewing changes to themes, or viewing different themes entirely, on a deployed user interface. Having said that, if you're designing a user interface with several collaborators, you might have a remote development server. In this scenario, the dev tool suits its name. Portability The ThemeRoller application is portable in more ways than one. The dev tool for Firefox allows us to use the application within any jQuery UI application. This means that we can design and tweak our jQuery UI themes as we build the widgets. This portability between applications means that we can build a single theme that works for a suite of applications, or a product line, if we're so inclined. We can also use the ThemeRoller application directly from the jQueryUI website. This is handy if we don't have any widgets built or if you're trying jQuery UI out for the first time and just want to browse the wide selection of prepackaged themes. Whatever approach you take, the application is the same and will always be consistent, as it is a hosted application. You don't need to concern yourself with installing an IDE for theme authors to collaborate with. The ThemeRoller application is available wherever they are. ThemeRoller gallery It is nice to have a wide variety of prepackaged themes to choose from. It isn't all that helpful if you can't see how they look. The ThemeRoller application has a gallery where we can not only browse prepackaged themes but also take them for a test drive. This section is about using the ThemeRoller gallery to view themes and get a feel of the variety available to us. Viewing themes The ThemeRoller application doesn't hide anything about the prepackaged themes in the gallery. When we preview a theme, we get to see how it looks when applied to widgets. The theme gallery even gives us a thumbnail in the browser to show a bird's eye view of the theme. So if you see a lot of black and you're looking for something bright, you don't need to bother selecting it to see how the widgets look with it. Time for action - previewing a theme It's time for us to preview a jQuery UI theme before we actually download it. We can get an idea of what a theme in the ThemeRoller gallery will look like when applied to widgets: Point your web browser to http://jqueryui.com/themeroller/. Select the Gallery tab in the ThemeRoller section on the right-hand side. Move your mouse pointer over any theme in the gallery. A visual indicator will be displayed. Select the theme thumbnail:   What just happened? We've just selected a theme to preview from the ThemeRoller gallery. You'll notice that all the sample widgets to the right are instantly updated with the new theme. If we wanted to, we could change our theme selection and the sample widgets are once again updated with the theme changes. You'll notice that once you make a theme selection, the URL in your address bar is now long and ugly. These are the individual theme settings for the chosen theme being passed to the ThemeRoller page with the sample widgets. You'll also notice that the theme selection on the left-hand side of the page isn't preserved. This is because we're passing individual theme settings and not the name of the theme itself, for example, instancetheme=darkness. We'll see why this distinction is important in a little bit. Downloading themes Once you've selected a theme from the gallery and you're happy with how it looks, it is time to download it and use it with your jQuery UI project. Downloading a theme is easy—each prepackaged theme has a download button that will take you to the jQuery UI download page. If we wanted to, we could download all themes in a single package to experiment with, locally. This would also eliminate the need for the ThemeRoller application, which you probably don't want to do. Time for action - downloading a theme The gallery is a nice way to preview a theme, but now we want to use it in our application. To do this, we need to download it. This is similar to downloading the jQuery UI toolkit: Point your web browser to http://jqueryui.com/themeroller/. Select the Gallery tab in the ThemeRoller section on the left-hand side. Find a theme you wish to download. Click on the Download button underneath the theme thumbnail. This will bring you to the jQuery UI download page. Notice that your chosen theme is selected on the right-hand side of the page. Click on the Download button to download your theme: What just happened? We've just selected a prepackaged theme from the ThemeRoller gallery and downloaded it. In fact, you just downloaded jQuery UI again. The difference being, the downloaded ZIP archive contains the theme you selected from the gallery. The same principles apply for extracting the archive and using your theme with your jQuery UI application. The downside is that if you're downloading a theme, chances are you already have a jQuery UI application under development. In this case, downloading jQuery UI JavaScript files is redundant. However, there is no easy way around this. This is one of the drawbacks to having a useful tool available to us—a minor drawback at that. If you're only interested in the theme, you simply need to extract the theme folder from the ZIP archive and copy it to your jQuery UI application directory. You then need to update your path in your HTML in including the appropriate CSS file. You'll also notice that after clicking on the Download button from the theme gallery, you're brought to the download page with an ugly URL. That is, you'll see something like /download/?themeParams=%3FffDefault instead of just /download. This is a requirement of the ThemeRoller application that allows developers to edit existing themes or to roll their own. Without these parameters, we wouldn't be able to download themes we have made changes to. The jQuery UI download page also includes an Advanced Settings section that is hidden by default. This is because you rarely need to use it. It allows you to set the CSS scope for your theme, useful if you're using multiple themes in a single user interface. This isn't a recommended practice; the key idea behind jQuery UI themes is consistency. The advanced settings also lets you change the name of the downloaded theme folder. This can be useful if you plan on changing your theme later, but you can always rename the folder after downloading it.
Read more
  • 0
  • 0
  • 3440

article-image-play-framework-binding-and-validating-objects-and-rendering-json-output
Packt
03 Aug 2011
4 min read
Save for later

Play Framework: Binding and Validating Objects and Rendering JSON Output

Packt
03 Aug 2011
4 min read
Binding and validating objects using custom binders Read the Play documentation about binding and validating objects. As validation is extremely important in any application, it basically has to fulfill several tasks. First, it should not allow the user to enter wrong data. After a user has filled a form, he should get a positive or negative feedback, irrespective of whether the entered content was valid or not. The same goes for storing data. Before storing data you should make sure that storing it does not pose any future problems as now the model and the view layer should make sure that only valid data is stored or shown in the application. The perfect place to put such a validation is the controller. As a HTTP request basically is composed of a list of keys and values, the web framework needs to have a certain logic to create real objects out of this argument to make sure the application developer does not have to do this tedious task. You can find the source code of this example in the chapter2/binder directory. How to do it... Create or reuse a class you want created from an item as shown in the following code snippet: public class OrderItem { @Required public String itemId; public Boolean hazardous; public Boolean bulk; public Boolean toxic; public Integer piecesIncluded; public String toString() { return MessageFormat.format("{0}/{1}/{2}/{3}/{4}", itemId, piecesIncluded, bulk, toxic, hazardous); } } Create an appropriate form snippet for the index.xml template: #{form @Application.createOrder()} <input type="text" name="item" /><br /> <input type="submit" value="Create Order"> #{/form} Create the controller: public static void createOrder(@Valid OrderItem item) { if (validation.hasErrors()) { render("@index"); } renderText(item.toString()); } Create the type binder doing this magic: @Global public class OrderItemBinder implements TypeBinder<OrderItem> { @Override public Object bind(String name, Annotation[] annotations, String value, Class actualClass) throws Exception { OrderItem item = new OrderItem(); List<String> identifier = Arrays.asList(value.split("-", 3)); if (identifier.size() >= 3) { item.piecesIncluded = Integer.parseInt(identifier.get(2)); } if (identifier.size() >= 2) { int c = Integer.parseInt(identifier.get(1)); item.bulk = (c & 4) == 4; item.hazardous = (c & 2) == 2; item.toxic = (c & 1) == 1; } if (identifier.size() >= 1) { item.itemId = identifier.get(0); } return item; } } How it works... With the exception of the binder definition all of the preceding code has been seen earlier. By working with the Play samples you already got to know how to handle objects as arguments in controllers. This specific example creates a complete object out of a simple String. By naming the string in the form value (<input …name="item" />) the same as the controller argument name (createOrder(@Valid OrderItem item)) and using the controller argument class type in the OrderItemBinder definition (OrderItemBinder implements TypeBinder<OrderItem>), the mapping is done. The binder splits the string by a hyphen, uses the first value for item ID, the last for piìesIncluded, and checks certain bits in order to set some Boolean properties. By using curl you can verify the behavior very easily as shown: curl -v -X POST --data "item=Foo-3-5" localhost:9000/order Foo/5/false/true/true Here Foo resembles the item ID, 5 is the piecesIncluded property, and 3 is the argument means that the first two bits are set and so the hazardous and toxic properties are set, while bulk is not. There's more... The TypeBinder feature has been introduced in Play 1.1 and is documented at http://www.playframework.org/documentation/1.2/controllers#custombinding. Using type binders on objects Currently, it is only possible to create objects out of one single string with a TypeBinder. If you want to create one object out of several submitted form values you will have to create your own plugin for this as workaround. You can check more about this at: http://groups.google.com/group/play-framework/browse_thread/thread/62e7fbeac2c9e42d Be careful with JPA using model classes As soon as you try to use model classes with a type binder you will stumble upon strange behavior, as your objects will always only have null or default values when freshly instanced. The JPA plugin already uses a binding and overwrites every binding you are doing.
Read more
  • 0
  • 0
  • 6207

article-image-integrating-phplist-2-facebook
Packt
02 Aug 2011
3 min read
Save for later

Integrating phpList 2 with Facebook

Packt
02 Aug 2011
3 min read
  PHPList 2 E-mail Campaign Manager Prerequisites For this section, we'll make the following assumptions: We already have a Facebook account We already have a Facebook page We already have the Facebook developer's application installed (http://www.facebook.com/developers) Preparing phpList Facebook allows us to include any content on our page in an iframe with a maximum width of 520 px. phpList's default theming won't fit in 520 px and so it will either get cut off and look odd, or will invoke awkward scroll bars in the middle of the page. To resolve this, we'll need to change the styling of phpList. Note that this will also affect how the public URLs to our phpList site are displayed outside of Facebook (that is, the default sign up page). Navigate to the configure page in phpList's admin interface, using the right-hand navigation panel: Scroll down to the section starting with Header of public pages and click on edit. This is the HTML code that is added to the top of every public (not admin) page. In the following example, we've removed the background image, the HTML table, and images, but left the CSS styling unchanged: Having saved your changes, edit the next section labeled Footer of public pages and make the corresponding changes: Remember that the actual content that the user sees will be "sandwiched" between the header and footer. This means that if you open a tag in the header, you need to make sure it's closed again in the footer. Again in this example, we just closed the HTML body tag in the footer: Having changed the header and footer of the public pages, browse to your default public page (http://your-site.com/lists/, for example) to see how the page looks: Note that there is hardly any styling now, but that there are no fixed-width elements which will cause issues with our iframe. Tweaking the design of using the public header and footer code is a task left to the reader. Creating the Facebook app Before we can add phpList to our Facebook page, we need to create an App. From http://www.facebook.com/developers/, click on the Set Up New App button: Click the radio button to indicate that you agree to the Facebook terms and then click on Create App: Prove you're a human by completing the CAPTCHA: You're taken to the edit page for your new app. Under the Facebook Integration section, enter at least the following details: IFrame Size: Auto-resize (we don't want scrollbars) Tab Name (what the tab will be called when your page is displayed) Tab URL (the full URL to the page you want loaded in your iframe. Generally, this would be a phpList subscribe page) Once you've saved your changes, you're taken to your list of applications. Click on Application Profile Page to see the application as other Facebook users would see it (as opposed to the developer): On the application's profile page, click on Add to My Page to add this application to your Facebook page: When prompted, choose which of your pages you want to add the application to. In this example, we've created a page for this article, so we add the application to this page:  
Read more
  • 0
  • 0
  • 1795

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
  • 2951
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 $19.99/month. Cancel anytime
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
  • 5732

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
  • 4809

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
  • 1970

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
  • 5930
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
  • 1992

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
  • 3925

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
  • 2418
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
  • 2799

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
  • 2914
Modal Close icon
Modal Close icon