Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-skin-customization-jboss-richfaces-33
Packt
30 Nov 2009
5 min read
Save for later

Skin Customization in JBoss RichFaces 3.3

Packt
30 Nov 2009
5 min read
Skinnability Every RichFaces component gives the support for skinnability and it means that just by changing the skin, we change the look for all of the components. That's very good for giving our application a consistent look and not repeating the same CSS values for each component every time. RichFaces still uses CSS, but it also enhances it in order to make it simpler to manage and maintain. Customize skin parameters A skin file contains the basic settings (such as font, colors, and so on) that we'll use for all the components—just by changing those settings, we can customize the basic look and feel for the RichFaces framework. As you might know, RichFaces comes with some built-in skins (and other external plug 'n' skin ones)—you can start with those skins in order to create your own custom skin. The built-in skins are: Plain emeraldTown blueSky wine japanCherry ruby classic deepMarine The plug 'n' skin ones are: laguna darkX glassX The plug 'n' skin skins are packaged in external jar files (that you can download from the same location as that of the RichFaces framework) that must be added into the project in order to be able to use them. Remember that the skin used by the application can be set as context-param in the web.xml file: <context-param> <param-name>org.richfaces.SKIN</param-name> <param-value>emeraldTown</param-value></context-param> This is an example with the emeralTown skin set: If we change the skin to japanCherry, we have the following screenshot: That's without changing a single line of CSS or XHTML! Edit a basic skin Now let's start creating our own basic skin. In order to do that, we are going to reuse one of the built-in skin files and change it. You can find the skin files in the richfaces-impl-3.x.x.jar file inside the META-INF/skins directory. Let's open the file and then open, for example, the emeraldTown.skin.properties file that looks like this (yes, the skin file is a .properties file!): #ColorsheaderBackgroundColor=#005000headerGradientColor=#70BA70headerTextColor=#FFFFFFheaderWeightFont=boldgeneralBackgroundColor=#f1f1f1generalTextColor=#000000generalSizeFont=18pxgeneralFamilyFont=Arial, Verdana, sans-serifcontrolTextColor=#000000controlBackgroundColor=#ffffffadditionalBackgroundColor=#E2F6E2shadowBackgroundColor=#000000shadowOpacity=1panelBorderColor=#C0C0C0subBorderColor=#fffffftabBackgroundColor=#ADCDADtabDisabledTextColor=#67AA67trimColor=#BBECBBtipBackgroundColor=#FAE6B0tipBorderColor=#E5973EselectControlColor=#FF9409generalLinkColor=#43BD43hoverLinkColor=#FF9409visitedLinkColor=#43BD43# FontsheaderSizeFont=18pxheaderFamilyFont=Arial, Verdana, sans-seriftabSizeFont=11tabFamilyFont=Arial, Verdana, sans-serifbuttonSizeFont=18buttonFamilyFont=Arial, Verdana, sans-seriftableBackgroundColor=#FFFFFFtableFooterBackgroundColor=#cccccctableSubfooterBackgroundColor=#f1f1f1tableBorderColor=#C0C0C0tableBorderWidth=2px#Calendar colorscalendarWeekBackgroundColor=#f5f5f5calendarHolidaysBackgroundColor=#FFEBDAcalendarHolidaysTextColor=#FF7800calendarCurrentBackgroundColor=#FF7800calendarCurrentTextColor=#FFEBDAcalendarSpecBackgroundColor=#E2F6E2calendarSpecTextColor=#000000warningColor=#FFE6E6warningBackgroundColor=#FF0000editorBackgroundColor=#F1F1F1editBackgroundColor=#FEFFDA#GradientsgradientType=plain In order to test it, let's open our application project, create a file called mySkin.skin.properties inside the directory /resources/WEB-INF/, and add the above text. Then, let's open the build.xml file and edit it, and add the following code into the war target: <copy tofile="${war.dir}/WEB-INF/classes/mySkin.skin.properties"file="${basedir}/resources/WEB-INF/mySkin.skin.properties"overwrite="true"/> Also, as our application supports multiple skins, let's open the components.xml file and add support to it: <property name="defaultSkin">mySkin</property><property name="availableSkins"> <value>mySkin</value> <value>laguna</value> <value>darkX</value> <value>glassX</value> <value>blueSky</value> <value>classic</value> <value>ruby</value> <value>wine</value> <value>deepMarine</value> <value>emeraldTown</value> <value>japanCherry</value></property> If you just want to select the new skin as the fixed skin, you would just edit the web.xml file and select the new skin by inserting the name into the context parameter (as explained before). Just to make an (bad looking, but understandable) example, let's change some parameters in the skin file: #ColorsheaderBackgroundColor=#005000headerGradientColor=#70BA70headerTextColor=#FFFFFFheaderWeightFont=boldgeneralBackgroundColor=#f1f1f1generalTextColor=#000000generalSizeFont=18pxgeneralFamilyFont=Arial, Verdana, sans-serifcontrolTextColor=#000000controlBackgroundColor=#ffffffadditionalBackgroundColor=#E2F6E2shadowBackgroundColor=#000000shadowOpacity=1panelBorderColor=#C0C0C0subBorderColor=#fffffftabBackgroundColor=#ADCDADtabDisabledTextColor=#67AA67trimColor=#BBECBBtipBackgroundColor=#FAE6B0tipBorderColor=#E5973EselectControlColor=#FF9409generalLinkColor=#43BD43hoverLinkColor=#FF9409visitedLinkColor=#43BD43# FontsheaderSizeFont=18pxheaderFamilyFont=Arial, Verdana, sans-seriftabSizeFont=11tabFamilyFont=Arial, Verdana, sans-serifbuttonSizeFont=18buttonFamilyFont=Arial, Verdana, sans-seriftableBackgroundColor=#FFFFFFtableFooterBackgroundColor=#cccccctableSubfooterBackgroundColor=#f1f1f1tableBorderColor=#C0C0C0tableBorderWidth=2px#Calendar colorscalendarWeekBackgroundColor=#f5f5f5calendarHolidaysBackgroundColor=#FFEBDAcalendarHolidaysTextColor=#FF7800calendarCurrentBackgroundColor=#FF7800calendarCurrentTextColor=#FFEBDAcalendarSpecBackgroundColor=#E2F6E2calendarSpecTextColor=#000000warningColor=#FFE6E6warningBackgroundColor=#FF0000editorBackgroundColor=#F1F1F1editBackgroundColor=#FEFFDA#GradientsgradientType=plain Here is the screenshot of what happened with the new skin: How do I know which parameters to change? The official RichFaces Developer Guide contains, for every component, a table with the correspondences between the skin parameters and the CSS properties they are connected to.
Read more
  • 0
  • 0
  • 3920

article-image-report-components-nav-2009-part-2
Packt
30 Nov 2009
6 min read
Save for later

Report components in NAV 2009: Part 2

Packt
30 Nov 2009
6 min read
Data item Sections Earlier in our discussion on reports, we referred to the primary components of a report. The Triggers and Properties we have reviewed so far are the data processing components. Next in the report processing sequence are Sections. In Classic RD reports, Sections are the output layout and formatting components. In RTC reports, Sections have a much more limited, but still critically important, role. In the process of creating the initial report design, you may be entering data either completely manually as we've done in our example work, or you may use the Classic Report Wizard. If you use the Wizard, you will end up with Sections defined suitable for Classic Client Report processing. Those Sections may be only rough draft equivalents of what you may want your final report to look like, but they are a suitable starting place for the Classic RD layout work, if that were the tool you were going to use. If you are creating your report completely manually, that is by not using the Wizard, you may also find it appropriate to define Sections to the point that the Classic Client could print a basic, readable report. In our case, we are focusing our production report development effort on the RoleTailored Client, so we will invest minimal effort on Classic Client compatible report layouts. We might do just enough to allow test report runs for data examination purposes and logic flow debugging. However, creating basic Section layouts provides us with another benefit relative to our VS RD layout work, especially if we can create them using the Report Wizard, because all the fields to be used by VS RD must be specified in the Sections. Creating RTC reports via the Classic Report Wizard Let's look at the RTC report development flow again. The preceding image is very similar to the one we studied earlier in this articles, but this flowchart only shows the steps that are pertinent to VS RD. In Step 6 of this flow, there is an option to Create Layout Suggestion in the Visual Studio Report Designer as shown in the following screenshot: When you choose Create Layout Suggestion, the C/SIDE Report Designer will invoke a process that transforms the layout in Sections to a layout in the Visual Studio Report Designer. If a VS RD layout previously existed, the newly created layout will overwrite it. Therefore, this option will normally be used only once, in the initial stages of report design. Let's experiment by using the Report Wizard to create a simple report listing the gifts received by ICAN. We will access the Report Wizard in the Object Designer. Click on Reports | New, then fill in the Wizard screen as shown in the following image. Then click on OK and choose fields to display in the report as shown in the following screenshot. Click on Next, then choose the sorting order (that is index or key) that starts with Donor ID. Click on Next again and choose to Group the data by Donor ID. Click on Next again and choose to create totals for the Estimated Value field. One more, click on Next and choose the List Style for the report, then click on Finish. At this point, you will have generated a Classic Client report using the Report Wizard. If you View | Sections, you should see a C/SIDE report layout that looks much like the following screenshot. Let's save our newly generated report so that, if we need to, we can come back to this point as a checkpoint. Click on File | Save As and assign the report to ID 50002 with the Name of Gifts by Donor. Now click on Tools | Create Layout Suggestion. The process of transforming the Classic Report Layout to a Visual Studio Report Designer Layout will take a few seconds. When the report layout transformation process completes, you should see a screen that looks very similar to the following screenshot. The primary data layout portion of the same VS RD screen is shown in the next image. Compare this to the Classic RD data layout we just looked at a couple of steps ago. You will see some similarities and some considerable differences. Without doing anything else, let's save the VS RD layout we just created for the RoleTailored Client, then run both versions of the report to see the differences in the generated results. To save the VS RD layout, start by simply exiting the VS Report Designer. Once the VS RD screen closes, you will see the following question. Respond by clicking Yes. Then, when you exit the Classic Report Designer, you will see this question. Respond by clicking Yes. You will then be presented with the following message. Again, click on Yes. If there were an error in the RDLC created within the VS RD (such as an incorrect variable name used), an error message similar to the following would display. Since, hopefully, we didn't get such an error message, we can proceed to test both the Classic Client and the RoleTailored Client versions of our generated report. We can test the Classic Client (or C/SIDE RD) version of Report 50002 from the same Object Designer screen where we did our initial design work. Highlight the line for Report 50002 and click on the Run button. You should see the following screen: If we were running this as users, we might want to make a selection of specific Donors here on which to report. As we are just testing, simply click on Preview to see our report onscreen. The report will then appear, looking like the following: As you can see, with minimum development effort (and a minimum of technical knowledge), we have designed and created a report listing Gifts by Donor with subtotals by Donor. The report has proper page and column headings. Not only that, but the report was initiated withs a Request Form allowing application of filters. Close the Classic Client report; now let's run the RTC version. Just like we could do with Pages, we will run our Report test from the Windows Run option. Click on Run and enter the command to run Report 50002, as shown in the next screenshot. Click on OK. If the RoleTailored Client is not active, after a short pause, it will be activated. Then the Request Page will appear. Compare the look and contents of this Request Page with the one we saw previously for the Classic Client. As before, click on Preview and view the report. Of course, this time we're looking at the RTC version. This method of automatic transformation is very useful for getting an initial base for a new report or, obviously, for the complete generation process for a simple report where the requirements for layout are not too restrictive.
Read more
  • 0
  • 0
  • 2556

article-image-linux-e-mail-customizing-spamassassin
Packt
30 Nov 2009
8 min read
Save for later

Linux E-mail: Customizing SpamAssassin

Packt
30 Nov 2009
8 min read
SpamAssassin is very configurable. Almost every setting can be configured on a system-wide or user-specific basis. Reasons to customize If SpamAssassin is so good, then why configure it? Well, there are several reasons why it's worth improving spam filtering with SpamAssassin. SpamAssassin by default (that is, when installed but not customized) typically manages to detect over 80% of spam. After adding a few customizations, the detection rate can be greater than 95%. Everyone's spam is different and one user's spam might look like another user's ham. By trying to be general, SpamAssassin may fail to filter spam for every user. Some of the features of SpamAssassin are disabled by default. By enabling them, the spam recognition rate is increased. The following configuration options are discussed in this article: Altering the scores for rules: This allows rules to be disabled, poor rules to be given less weight, and better rules to be given a higher weight. Obtaining and using new rules: This can improve spam detection. Adding e-mail addresses to white and blacklists: This allows the e-mail from specified senders to always be treated as ham, no matter what the content is, or the opposite. Enabling SpamAssassin's Bayesian filter: This can increase filtering accuracy from 80% to 95% or more. Rules and scores The configuration files for standard, sitewide, and user-specific settings are saved in different directories as follows: Standard configuration settings are stored in /usr/share/spamassassin. Site-wide customizations and settings are stored in /etc/mail/spamassassin/. All files matching *.cf are examined by SpamAssassin. User-specific settings are stored in ~/.spamassassin/local.cf. The bulk of the standard configuration files is devoted to simple rules and their scores. A rule is typically a match for letters, numbers, or other printing characters. Rules are written using a technique called regular expressions, or regex for short. This is a shorthand method of specifying that certain combinations of characters will trigger the rule. A rule might try to detect a particular word, such as "Rolex", or it might look for particular words in certain orders, such as "buy Rolex online". The rules are stored in text files. Default files are stored in /usr/share/spamassassin. These are files that are shipped with SpamAssassin and may change with each release. It's best not to modify these files or place new files in this directory, as an upgrade to SpamAssassin will overwrite these files. Most of the rules that SpamAssassin uses, and the scores applied to each rule, are defined within files in this directory. The defaults can be overwritten by sitewide configuration files. These are placed in /etc/mail/spamassassin. SpamAssassin will read all files matching *.cf in this directory. Settings made here can overrule those in the default files. They can include defining new rules and new rule scores. User-specific customizations can be placed in the ~/.spamassassin/local.cf file. Settings made here can override sitewide settings defined in /etc/mail/spamassassin, and default settings in /usr/share/spamassassin/. New rules may be defined here, and scores for existing rules can be overridden. SpamAssassin first reads all the files in /usr/share/spamassassin in alphanumerical order; 10_misc.cf will be read before 23_bayes.cf. SpamAssassin then reads all the .cf files in /etc/mail/spamassassin/, again in alphanumeric order. Finally, SpamAssassin reads ~user/.spamassassin/user_prefs. If a rule or score is defined in two files, the setting in the last file read is used. This allows the administrator to override the defaults and a user to override the sitewide settings. Each line in a rules file can be blank or contain a comment or a command. The hash or pound (#) symbol is used for comments. Rules generally have three parts, the rule definition, a textual description, and the score or series of scores. Convention dictates that all rule scores for rules provided by SpamAssassin should be located together in a separate file. That file is /usr/share/spamassassin/50_scores.cf. Altering rule scores The simplest configuration change is to change a rule score. There are two reasons why this might be done: A rule is very good at detecting spam, but the rule has a low score. E-mails that fire the rule are not being detected as spam. A rule is acting on non spam. As a result, e-mails that fire the rule are wrongly being detected as spam. The rules that give a positive result when SpamAssassin is run are listed in the X-Spam-Status: header of the e-mail: X-Spam-Status: Yes, score=5.8 required=5.0 tests=BAYES_05,HTML_00_10,HTML_MESSAGE,MPART_ALT_DIFF autolearn=noversion=3.1.0-r54722 The rules applied to the e-mail are listed after tests=. If one continually appears in e-mail that should be marked as spam, but isn't, then the score for the rule should be increased. If a rule often fires in e-mail that is wrongly classified as spam, the score should be decreased. To find the current score, use the grep utility in all the locations where a score can be defined. grep score.*BAYES /usr/share/spamassassin/* /etc/mail/spamassassin/*~/.spamassassin/local.cf/etc/mail/spamassassin/local_scores.cf:score RULE_NAME 0 0 1.665 2.599/etc/mail/spamassassin/local_scores.cf: 4.34 In the previous example, the rule has a default score that is overridden in /etc/mail/spamassassin/local_scores.cf. The original score for the rule had four values. SpamAssassin changes the scores it uses, depending on whether network tests (for example, those that test open relays) are in use and whether the Bayesian Filter is in use. Four scores are listed, which are used in the following circumstances: //===INSERT TABLE 02=== If only one score is given, as overridden in /etc/mail/spamassassin/local_scores.cf, it is used in all circumstances. In the previous example, the system administrator has overridden the default score in /etc/mail/spamassassin/local_scores.cf with a single value in /etc/mail/spamassassin/local_scores.cf. To change this value for a particular user, their ~/.spamassassin/local.cf might read: score RULE_NAME 1.2 This changes the score used from 4.34, set in /etc/mail/spamassassin/local_scores.cf, to 1.2. To disable the rule entirely, the score can be set to zero. score RULE_NAME 0 Endless hours can be spent configuring rule scores. SpamAssassin includes tools to recalculate optimal rule scores, by examining existing e-mails, both spam and non spam. They are covered in detail in the book SpamAssassin published by Packt. Using other rulesets SpamAssassin has a large following, and the design of SpamAssassin has made it easy to add new rulesets, which are sets of rules and default scores for those rules. There are many different rulesets available. Most are based on a particular theme, for example finding the names of drugs often sold with spam or telephone numbers found in spam e-mails. Most custom rulesets are listed on the Custom Rulesets page of the SpamAssassin Wiki at http://wiki.apache.org/spamassassin/CustomRulesets. As the battle against spam is so aggressive, rulesets have been developed that may possibly be uploaded daily. SpamAssassin provides this ability with the sa-update utility. You can choose to use sa-update on a regular basis, or to download a particular ruleset and keep it, or to manually update the rulesets that you choose. To obtain the best results in filtering spam, use of sa-update is recommended. If you wish to install rulesets manually, the Wiki page gives a general description of each ruleset and a URL to download it. Once a ruleset has been chosen, we install it as follows: In a browser, follow the link on the SpamAssassin Wiki page. In most cases, the link will be to a file with a name matching *.cf, and a browser will open it as a text file. Save the file using the browser (normally, the File menu has a Save as option). Copy the file to /etc/mail/spamassassin—the rules will be automatically run if the file is placed in this location. Check that the file has scores in it, otherwise the rules will not be used. Monitor spam performance to ensure that legitimate e-mail is not being detected as spam. Adding rules to SpamAssassin will increase the memory used by SpamAssassin, and the time that it takes to process e-mails. It is best to be cautious and add new rulesets gradually, to ensure that the effect on the machine is understood. You may manually monitor the ruleset and update it on your system using the same process. If you choose to use sa-update, you should plan your use of it. sa-update can use several channels, which are basically sources of rulesets. By default, the channel updates.spamassassin.org is used; another popular channel is the OpenProtect channel, called saupdates.openprotect.com. To enable sa-update, it must be run regularly, for example via cron. Add a cron entry to your system calling the following commands, to update the base rulesets: sa-update If you use an additional channel, the command might look like: sa-update –channel saupdates.openprotect.com To protect against DNS poisoning and impersonation, SpamAssassin allows digital signing of rulesets. To use a signed ruleset, use the –gpgkey parameter to sa-update. The correct value to use with the –gpgkey parameter will be described in the SpamAssassin wiki page for the ruleset.
Read more
  • 0
  • 0
  • 3528

article-image-facelets-components-jsf-12
Packt
30 Nov 2009
12 min read
Save for later

Facelets Components in JSF 1.2

Packt
30 Nov 2009
12 min read
One of the more advanced features of the Facelets framework is the ability to define complex templates containing dynamic nested content. What is a template?The Merriam-Webster dictionary defines the word "template" as "a gauge, pattern, or mold (as a thin plate or board) used as a guide to the form of a piece being made" and as "something that establishes or serves as a pattern." In the context of user interface design for the Web, a template can be thought of as an abstraction of a set of pages in the web application.A template does not define content, but rather it defines placeholders for content, and provides the layout, orientation, flow, structure, and logical organization of the elements on the page. We can also think of templates as documents with "blanks" that will be filled in with real data and user interface controls at request time. One of the benefits of templating is the separation of content from presentation, making the maintenance of the views in our web application much easier. The <ui:insert> tag has a name attribute that is used to specify a dynamic content region that will be inserted by the template client. When Facelets renders a UI composition template, it attempts to substitute any <ui:insert> tags in the Facelets template document with corresponding <ui:define> tags from the Facelets template client document. Conceptually, the Facelets composition template transformation process can be visualized as follows: In this scenario, the browser requests a Facelets template client document in our JSF application. This document contains two <ui:define> tags that specify named content elements and references a Facelets template document using the <ui:composition> tag's template attribute. The Facelets template document contains two <ui:insert> tags that have the same names as the <ui:define> tags in the client document, and three <ui:include> tags for the header, footer, and navigation menu. This is a good example of the excellent support that Facelets provides for the Composite View design pattern. Facelets transforms the template client document by merging any content it defines using <ui:define> tags with the content insertion points specified in the Facelets template document using the <ui:insert> tag. The result of merging the Facelets template client document with the Facelets template document is rendered in the browser as a composite view. While this concept may seem a bit complicated at first, it is actually a powerful feature of the Facelets view defi nition framework that can greatly simplify user interface templating in a web application. In fact, the Facelets composition template document can itself be a template client by referencing another composition template. In this way, a complex hierarchy of templates can be used to construct a flexible, multi-layered presentation tier for a JSF application. Without the Facelets templating system, we would have to copy and paste view elements such as headers, footers, and menus from one page to the next to achieve a consistent look and feel across our web application. Facelets templating enables us to define our look and feel in one document and to reuse it across multiple pages. Therefore, if we decide to change the look and feel, we only have to update one document and the change is immediately propagated to all the views of the JSF application. Let's look at some examples of how to use the Facelets templating feature. A simple Facelets template The following is an example of a simple Facelets template. It simply renders a message within an HTML <h2> element. Facelets will replace the "unnamed" <ui:insert> tag (without the name attribute) in the template document with the content of the <ui:composition> tag from the template client document. template01.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Facelets template example</title><link rel="stylesheet" type="text/css" href="/css/style.css" /></head><body><h2><ui:insert /></h2></body></html> A simple Facelets template client Let's look at a simple example of Facelets templating. The following page is a Facelets template client document. (Remember: you can identify a Facelets template client by looking for the existence of the template attribute on the <ui:composition> tag.) The <ui:composition> tag simply contains the text Hello World. templateClient01.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:composition example</title></head><body><ui:composition template="/WEB-INF/templates/template01.jsf">Hello World</ui:composition><ui:debug /></body></html> The following screenshot displays the result of the Facelets UI composition template transformation when the browser requests templateClient01.jsf. Another simple Facelets template client The following Facelets template client example demonstrates how a template can be reused across multiple pages in the JSF application: templateClient01a.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:composition example</title></head><body><ui:composition template="/WEB-INF/templates/template01.jsf">How are you today?</ui:composition><ui:debug /></body></html> The following screenshot displays the result of the Facelets UI composition template transformation when the browser requests templateClient01a.jsf: A more complex Facelets template The Facelets template in the previous example is quite simple and does not demonstrate some of the more advanced capabilities of Facelets templating. In particular, the template in the previous example only has a single <ui:insert> tag, with no name attribute specified. The behavior of the unnamed <ui:insert> tag is to include any content in the referencing template client page. In more complex templates, multiple <ui:insert> tags can be used to enable template client documents to defi ne several custom content elements that will be inserted throughout the template. The following Facelets template document declares three named <ui:insert> elements. Notice carefully where these tags are located. template02.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title><ui:insert name="title" /></title><link rel="stylesheet" type="text/css" href="/css/style.css" /></head><body><ui:include src="/WEB-INF/includes/header.jsf" /><h2><ui:insert name="header" /></h2><ui:insert name="content" /><ui:include src="/WEB-INF/includes/footer.jsf" /></body></html> In the following example, the template client document defines three content elements named title, header, and content using the <ui:define> tag. Their position in the client document is not important because the template document determines where this content will be positioned. templateClient02.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:composition example</title></head><body><ui:composition template="/WEB-INF/templates/template02.jsf"><ui:define name="title">Facelet template example</ui:define><ui:define name="header">Hello World</ui:define><ui:define name="content">Page content goes here.</ui:define></ui:composition><ui:debug /></body></html> The following screenshot displays the result of a more complex Facelets UI composition template transformation when the browser requests the page named templateClient02.jsf. The next example demonstrates reusing a more advanced Facelets UI composition template. At this stage, we should have a good understanding of the basic concepts of Facelets templating and reuse. templateClient02a.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:composition example</title></head><body>Facelets Components[ 78 ]<ui:composition template="/WEB-INF/templates/template02.jsf"><ui:define name="title">Facelet template example</ui:define><ui:define name="header">Thanks for visiting!</ui:define><ui:define name="content">We hope you enjoyed our site.</ui:define></ui:composition><ui:debug /></body></html> The next screenshot displays the result of the Facelets UI composition transformation when the browser requests templateClient02a.jsf. We can follow this pattern to make a number of JSF pages reuse the template in this manner to achieve a consistent look and feel across our web application. Decorating the user interface The Facelets framework supports the definition of smaller, reusable view elements that can be combined at runtime using the Facelets UI tag library. Some of these tags, such as the <ui:composition> and <ui:component> tags, trim their surrounding content. This behavior is desirable when including content from one complete XHTML document within another complete XHTML document. There are cases, however, when we do not want Facelets to trim the content outside the Facelets tag, such as when we are decorating content on one page with additional JSF or HTML markup defi ned in another page. For example, suppose there is a section of content in our XHTML document that we want to wrap or "decorate" with an HTML <div> element defined in another Facelets page. In this scenario, we want all the content on the page to be displayed, and we are simply surrounding part of the content with additional markup defined in another Facelets template. Facelets provides the <ui:decoration> tag for this purpose. Decorating content on a Facelets page The following example demonstrates how to decorate content on a Facelets page with markup from another Facelets page using the <ui:decoration> tag. The <ui:decoration> tag has a template attribute and behaves like the <ui:composition> tag. Facelets templating typically uses the <ui:composition>. It references a Facelets template document that contains markup to be included in the current document. The main difference between the <ui:composition> tag and the <ui:decoration> tag is that Facelets trims the content outside the <ui:composition> tag but does not trim the content outside the <ui:decoration> tag. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:decorate example</title><link rel="stylesheet" type="text/css" href="css/style.css" /></head><body>Text before will stay.<ui:decorate template="/WEB-INF/templates/box.jsf"><span class="header">Information Box</span><p>This is the first line of information.</p><p>This is the second line of information.</p><p>This is the third line of information.</p></ui:decorate>Text after will stay.<ui:debug /></body></html> Creating a Facelets decoration Let's examine the Facelets decoration template referenced by the previous example. The following source code demonstrates how to create a Facelets template to provide the decoration that will surround the content on another page. As we are using a <ui:composition> tag, only the content inside this tag will be used. In this example, we declare an HTML <div> element with the "box" CSS style class that contains a single Facelets <ui:insert> tag. When Facelets renders the above Facelets page, it encounters the <ui:decorate> tag that references the box.jsf page. The <ui:decorate> tag will be merged together with the associated decoration template and then rendered in the view. In this scenario, Facelets will insert the child content of the <ui:decorate> tag into the Facelets decoration template where the <ui:insert> tag is declared. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Box</title></head><body><ui:composition><div class="box"><ui:insert /></div></ui:composition></body></html> The result is that our content is surrounded or "decorated" by the <div> element. Any text before or after the <ui:decoration> is still rendered on the page, as shown in the next screenshot: The included decoration is rendered as is, and is not nested inside a UI component as demonstrated in the following Facelets debug page:
Read more
  • 0
  • 0
  • 4033

article-image-drag-and-drop-yui-part-3
Packt
30 Nov 2009
6 min read
Save for later

Drag-and-Drop with the YUI: Part-3

Packt
30 Nov 2009
6 min read
Visual Selection with the Slider Control So far in this chapter we've focused on the functionality provided by the Drag-and-Drop utility. Let's shift our focus back to the interface controls section of the library and look at one of the components which is related very closely to drag-and-drop—the Slider control. A slider can be defined using a very minimal set of HTML. All you need are two elements: the slider background and the slider thumb, with the thumb appearing as a child of the background element: <div id="slider_bg" title="the slider background"><div id="slider_thumb" title="the slider thumb"><img src="images/slider_thumb.gif"></div></div> These elements go together to form the basic Slider control, as shown in below: The Slider control works as a specific implementation of DragDrop in that the slider thumb can be dragged along the slider background either vertically or horizontally. The DragDrop classes are extended to provide additional properties, methods, and events specific to Slider. One of the main concepts differentiating Slider from DragDrop is that with a basic slider, the slider thumb is constrained to just one axis of motion, either X or Y depending on whether the Slider is horizontal or vertical respectively. The Slider is another control that can be animated by including a reference to the Animation control in the head of the page. Including this means that when any part of the slider background is clicked on, the slider thumb will gracefully slide to that point of the background rather than just moving there instantly. The Constructor and Factory Methods The constructor for the slider control is always called in conjunction with one of the three factory methods, depending on which type of slider you want to display. To generate a horizontal slider the YAHOO.widget.Slider.getHorizSlider is called, with the appropriate arguments. To generate a vertical slider, on the other hand, the YAHOO.widget.Slider.getVertSlider would instead be used. There is also another type of slider that can be created—the YAHOO.widget.Slider.getSliderRegion constructor and factory method combination creates a two-dimensional slider, the thumb of which can be moved both vertically and horizontally. There are a range of arguments used with the different types of slider constructor. The first two arguments are the same for all of them, with the first argument corresponding to the id of the background HTML element and the second corresponding to the id of the thumb element. The type of slider you are creating denotes what the next two (or four when using the SliderRegion) arguments relate to. With the horizontal slider or region slider the third argument is the number of pixels that the thumb element can move left, but with the horizontal slider it is the number of pixels it can move up. The fourth argument is either the number of pixels which the thumb can move right, or the number of pixels it can move down. When using the region slider, the fifth and sixth arguments are the number of pixels the thumb element can move up and down, so with this type of slider all four directions must be specified. Alternatively, with either the horizontal or vertical sliders, only two directions need to be accounted for. The final argument (either argument number five for the horizontal or vertical sliders, or argument number seven for the region slider) is optional and refers to the number of pixels between each tick, also known as the tick size. This is optional because you may not use ticks in your slider, therefore making the Slider control analogue rather than digital. Class of Two There are just two classes that make up the Slider control—the YAHOO.widget.Slider class is a subclass of the YAHOO.util.DragDrop class and inherits a whole bunch of its most powerful properties and methods, as well as defining a load more of its own natively. The YAHOO.widget.SliderThumb class is a subclass of the YAHOO.util.DD class and inherits properties and methods from this class (as well as defining a few of its own natively). Some of the native properties defined by the Slider class and available for you to use include: animate—a boolean indicating whether the slider thumb should animate. Defaults to true if the Animation utility is included, false if not animationDuration—an integer specifying the duration of the animation in seconds. The default is 0.2 backgroundEnabled—a boolean indicating whether the slider thumb should automatically move to the part of the background that is selected when clicked. Defaults to true enableKeys—another boolean which enables the home, end and arrow keys on the visitors keyboard to control the slider. Defaults to true, although the slider control must be clicked once with the mouse before this will work keyIncrement—an integer specifying the number of pixels the slider thumb will move when an arrow key is pressed. Defaults to 25 pixels A large number of native methods are also defined in the class, but a good deal of them are used internally by the slider control and will therefore never need to be called directly by you in your own code. There are a few of them that you may need at some point however, including: .getThumb()—returns a reference to the slider thumb .getValue()—returns an integer determining the number of pixels the slider thumb has moved from the start position .getXValue()—an integer representing the number of pixels the slider has moved along the X axis from the start position .getYValue()—an integer representing the number of pixels the slider has moved along the Y axis from the start position .onAvailable()—executed when the slider becomes available in the DOM .setRegionValue() and .setValue()—allow you to programmatically set the value of the region slider's thumb More often than not, you'll find the custom events defined by the Slider control to be most beneficial to you in your implementations. You can capture the slider thumb being moved using the change event, or detect the beginning or end of a slider interaction by subscribing to slideStart or slideEnd respectively. The YAHOO.widget.SliderThumb class is a subclass of the DD class; this is a much smaller class than the one that we have just looked at and all of the properties are private, meaning that you need not take much notice of them. The available methods are similar to those defined by the Slider class, and once again, these are not something that you need to concern yourself with in most basic implementations of the control.
Read more
  • 0
  • 0
  • 2502

article-image-user-interface-design-icefaces-18-part-1
Packt
30 Nov 2009
9 min read
Save for later

User Interface Design in ICEfaces 1.8: Part 1

Packt
30 Nov 2009
9 min read
Before we take a more detailed look at the ICEfaces components, we will discuss the desktop character of modern web applications in this article. Desktop technology  is about 40 years old now and there are best practices that can help us in our web application design. An important part of the user interface design is the page layout. We will have a look at the corresponding design process using a mockup tool. The Facelets example will be extended to show how to implement such a mockup design using Facelets templating. Finally, we will have a look at the production-ready templating of ICEfusion. Revival of the desktop The number of desktop-like web applications is growing faster and faster. The demand for this is not a big surprise. Using full-featured desktops meant that users had to suffer from the limited-user model of the first generation Web. This usage gap is now filled by web applications that mimic desktop behavior. However, there is a difference between the desktop and the Web. Although equipped with desktop-like presentations, web applications have to fulfill different user expectations. So, we have a revival of the desktop metaphor in the Web context but it is mixed with user habits based on the first decade of the Web. Nevertheless, the demand for a purer desktop presentation is already foreseeable. If you primarily followed the traditional web programming model in the past, namely the request-response pattern, you may first have to shift your mind to components and events. If you already have some desktop-programming experience you will discover a lot of similarities. However, you will also recognize how limited the Web 2.0 programming world is in comparison to modern desktops. The difference is understandable because desktop design has a long tradition. The first system was built at the end of the 1960s. There is a lot of experience in this domain. Best of all, we have established rules we can follow. Web design is still a challenge compared to desktop design. Although this article cannot discuss all of the important details of today's desktop design, we will have a quick look at the basics that are applicable to nearly all user interface designs. We can subsume all this with the following question: What makes a software system user-friendly? Software ergonomics Have you ever heard of the ISO standard 9241, Ergonomics of Human System Interaction (http://en.wikipedia.org/wiki/ISO_9241)? This standard describes how a system has to be designed to be human-engineered. There are a lot of aspects in it, from the hardware design for a machine that has to be used by a human to the user interface design of software applications. A poor hardware or interface design can result in not only injury, but also mental distress that leads to wastage of working time. The primary target is to prevent humans from damage. The most important part of ISO 9241 for software developers is part 110, dialog principles. It considers the design of dialogs between humans and information systems with a focus on: Suitability for the task Suitability for learning Suitability for individualization Conformity with user expectations Self-descriptiveness Controllability Error tolerance We will take a deeper look at these later. ISO 9241-110 has its roots in a German industry standard based on research work from the early 1980s. I frst had a look at all this during a study almost 20 years ago. Most interesting with part 110 is the stability of the theoretical model behind it. Independent of the technical advances of the IT industry in the last two decades, we can still apply these standards to modern web application design. Challenges The principles of ISO 9241-110 can help you to get better results, but they only serve as a rule. Even if you follow such principles slavishly, the result will not be automatically valuable. Creating a useful interface is still a challenging business. You have to accept a process of trial and error, ask for customer feedback, and accept a lot of iterations in development before usability becomes your friend. The technical limitations that derive from your framework decisions can be additionally frustrating. The problems that we have with today's AJAX technology are a good example of it, especially if you are already experienced with desktop development and its design rules. Apply Occam's razor Everything should be made as simple as possible, but not simpler. Albert Einstein's quote mentions two important aspects in creative processes that are also true for user interface design: Reduction Oversimplification Reduction Have you ever realized how difficult it is to recognize what is important or necessary, and what is superfluous when you enter a new domain? Often, things seem to be clear and pretty simple at the first sight. However, such a perception is based on experiences that were made outside of the domain. There is a lack of essential experiences in a majority of the cases. You may have to invest several years to get the whole picture and develop an accurate understanding before you come to an adequate decision. If your new domain is user interface design, these findings can help you to understand your customers better. If you keep questioning the eye-catching solutions that come to your mind and try to slip into the customer's role, you  will get better results faster. Oversimplification Oversimplification makes user interfaces more complex to use. This phenomenon arises if the target group for a user interface is defined as less experienced than it is in reality. For advanced users, a beginner's design is more time-consuming to use. In many cases, it is assumed that a bigger part of the users consists of beginners. However, reality shows us that advanced users make up the bigger part, whereas beginners and super users may have a portion of up to 10% each. Designing a user interface for beginners that can be used by all users may be an intuitive idea at first sight, but it is not. You have to consider the advanced users if you want to be successful with your design. This is indeed an essential experience to come to an adequate decision. User interface design principles Besides the aforementioned recommendations, the following are the most influential principles for an adequate interface design: Suitability for the task Self-descriptiveness Controllability Conformity with user expectations Error tolerance Suitability for individualization Suitability for learning Suitability for the task Although it seems to be a trivial requirement, the functionality of a web application seldom delivers what the user requires to fulfill his needs. Additionally, the presentation, navigation, or lingo often does not work for the user or is not well-suited for the function it represents. A good user interface design is based on the customer's lingo. You can write a glossary that describes the meaning of terms you use. A requirements management that results in a detailed use case model can help in implementing the adequate functionality. The iterative development of interactive user interface prototypes to get customer feedback allows finding a suitable presentation and navigation. Self-Descriptiveness Ergonomic applications have an interface design that allows answering the following questions at any time: What is the context I am working in at the moment? What is the next possible step? The answers to these questions become immediately important when a user is, for example, disrupted by a telephone call and continues his work after attending to it. The shorter the time to recognize the last working step, the better the design is. A rule of thumb is to have a caption for every web page that describes its context. Navigational elements, such as buttons, show descriptive text that allows recognizing the function behind it. If possible, separate a page into subsections that also have their captions for a better orientation. Controllability Applications have to offer their functionality in a way that the user can decide for himself when and how the application is fulfilling his requirements. For this, it is important that the application offers different ways to start a function. Beginners may prefer using the mouse to select an entry in a pull-down menu. Advanced users normally work with the keyboard because hotkeys let them use the application faster. It is also important that the user must be able to stop his/her work at any time; for example, for a lunch break or telephone call, without any disadvantages. It is not acceptable that the user has to start the last function again. With web application, this cannot be fulfilled in any case because of security reasons or limited server resources. Conformity with User Expectations User expectations are, maybe, the most important principle, but also the most sophisticated one. The expectations are closely connected to the cultural background of the target group. So, the interface designer has to have a similar socialization. We need to have a look at the use of words of the target language. Although target groups share the same language, certain terms can have different meanings; for example, the correct use of colors or pictures in icon bars is pretty important because we use these in contexts without extra explanation. However, there are cases when a color or an image can mean the opposite of what it was designed for. The behavior of an application can also be a problem when it differs from the standards of real-world processes. The advantage of standardization is an immediate understanding of processing steps, or the correct use of tools without education. If an application does not consider this and varies, the standard users have to rethink every step before they can fulfill their duties. This needs extra energy, is annoying, and is pretty bad for the acceptance of the application in the long run. If we look at the design itself, consistency in presentation, navigation, or form use is another important part. The user expects immutable behavior of the application in similar contexts. Contexts should be learned only once, and the learned ones are reusable in all other occurrences. Following this concept also helps to reuse the visual components during development. So, you have a single implementation for each context that is reused in different web pages.
Read more
  • 0
  • 0
  • 1978
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 €18.99/month. Cancel anytime
article-image-extending-tabs-jquery-ui-17
Packt
30 Nov 2009
4 min read
Save for later

Extending Tabs in jQuery UI 1.7

Packt
30 Nov 2009
4 min read
  The tab widget defines a series of useful options that allow you to add callback functions to perform different actions when certain events exposed by the widget are detected. The following table lists the configuration options that are able to accept executable functions on an event: Property Usage add Execute a function when a new tab is added. disable Execute a function when a tab is disabled. enable Execute a function when a tab is enabled. load Execute a function when a tab's remote data has loaded. remove Execute a function when a tab is removed. select Execute a function when a tab is selected. show Execute a function when the content section of a tab is shown.   Each component of the library has callback options (such as those in the previous table), which are tuned to look for key moments in any visitor interaction. Any function we use with these callbacks are usually executed before the change happens. Therefore, you can return false from your callback and prevent the action from occurring. In our next example, we will look at how easy it is to react to a particular tab being selected using the standard non-bind technique. Change the final <script> element in tabs7.html so that it appears as follows: <script type="text/javascript"> $(function(){ function handleSelect(event, tab) { $("<p>").text("The tab at index " + tab.index +  " was selected").addClass("status-message ui-corner-all") .appendTo($(".ui-tabs-nav","#myTabs")).fadeOut(5000); } var tabOpts = { select:handleSelect }; $("#myTabs").tabs(tabOpts); });</script> Save this file as tabs8.html. We also need a little CSS to complete this example, in the <head> of the page we just created add the following <link> element: <link rel="stylesheet" type="text/css" href="css/tabSelect.css"> Then in a new page in your text editor add the following code: .status-message { position:absolute; right:3px; top:4px; margin:0; padding:11px 8px 10px; font-size:11px; background-color:#ffffff; border:1px solid #aaaaaa;} Save this file as tabSelect.css in the css folder. We made use of the select callback in this example, although the principle is the same for any of the other custom events fired by tabs. The name of our callback function is provided as the value of the select property in our configuration object. Two arguments will be passed automatically to the function we define by the widget when it is executed. These are the original event object and a custom object containing useful properties from the tab which is in the function's execution context. To find out which of the tabs was clicked, we can look at the index property of the second object (remember these are zero-based indices). This is added, along with a little explanatory text, to a paragraph element that we create on the fly and append to the widget header. In this example, the callback function was defined outside the configuration object, and was instead referenced by the object. We can also define these callback functions inside our configuration object to make our code more efficient. For example, our function and configuration object from the previous example could have been defined like this: var tabOpts = { select: function(event, tab) { $("<p>").text("The tab at index " + tab.index + " was selected") .addClass("status-message ui-corner-all").appendTo($(".ui-tabs-nav", "#myTabs")).fadeOut(5000); }} Check tabs8inline.html in the code download for further clarification on this way of using event callbacks. Whenever a tab is selected, you should see the paragraph before it fades away. Note that the event is fired before the change occurs. Binding to events Using the event callbacks exposed by each component is the standard way of handling interactions. However, in addition to the callbacks listed in the previous table we can also hook into another set of events fired by each component at different times. We can use the standard jQuery bind() method to bind an event handler to a custom event fired by the tabs widget in the same way that we could bind to a standard DOM event, such as a click. The following table lists the tab widget's custom binding events and their triggers: Event Trigger tabsselect A tab is selected. tabsload A remote tab has loaded. tabsshow A tab is shown. tabsadd A tab has been added to the interface. tabsremove A tab has been removed from the interface. tabsdisable A tab has been disabled. tabsenable A tab has been enabled.
Read more
  • 0
  • 0
  • 2255

article-image-drag-and-drop-yui-part-1
Packt
30 Nov 2009
7 min read
Save for later

Drag-and-Drop with the YUI: Part-1

Packt
30 Nov 2009
7 min read
Dynamic Drag-and-Drop without the Hassle Like most of the other library components, when creating your own drag-and-drop elements, there are a range of different options available to you that allow you to tailor those objects to your requirements. These properties, like those of most other library components, can be set using an object literal supplied with the constructor, but in most cases even this is not required. The most challenging aspects of any drag-and-drop scenario in your web applications are going to center around the design of your specific implementation rather than in getting drag-and-drop to work in the first place. This utility is yet another example of the huge benefits the YUI can provide in reducing the amount of coding and troubleshooting that you need to concern yourself with. The Different Components of Drag-and-Drop In addition to the configurable properties used in your object literal, you also have several constructors that can be used to enable drag-and-drop. The first constructor YAHOO.util.DD allows for drag-and-drop at its most basic level. The supplied element will be transformed into an object that can be dragged around the page. The mechanics of drag-and-drop result in a burden of fairly high processing. The library has to keep track of the mouse pointer whilst it is moving, the draggable object needs to be repositioned, and different events are almost continually firing while the drag is taking place. In order to minimize the amount of information that needs to be processed, especially when the draggable object is fairly large, you can make use of a proxy element that will track across the page with the mouse pointer. When the proxy element reaches its final destination, it disappears and is replaced by the actual element. If a proxy element is required, we can use the YAHOO.util.DDProxy constructor instead of the basic constructor. As the proxy element is just an empty <div>, it's much easier to track and can even be shared between different drag objects on the page, reducing the overall processing that's required. Personally I think the default appearance of the proxy element is perfectly adequate, however you can also create your own custom elements to use as a proxy. The figure below shows the default proxy-element appearance: Design Considerations When working with DragDrop implementations, it is useful to consider the following aspects of the design: Can any part of the drag object be clicked on to initiate the drag, or should a drag handle be defined? Can the object be dropped on to any part of the page or should a specific drop target be defined? Should anything occur whilst the object is being dragged? Should anything occur when the item is dropped on a non-valid target? Should anything occur when the object is dropped on to a valid target? Events Events are an integral aspect of many DragDrop situations. Sometimes, however, being able to move something around the screen is the only behavior that's required, but generally you'll want something to happen either while the object is being dragged, or when it is dropped. The YAHOO.util.DragDrop utility provides a series of custom events which allow you to hook into and respond to events such as startDrag, endDrag, onDrag, onDragDrop, and onInvalidDrop. Valid targets also expose events of their own including onDragEnter, onDragOut, and onDragOver. We will be looking at a number of these events during the example that follows. Allowing Your Visitors to Drag-and-Drop The Drag-and-Drop utility uses tried and tested DHTML techniques, as well as some innovative new features, to allow you to easily create objects that can be dragged and then dropped. All that you need to do to make an element on your page dragable is to create a new instance of the YAHOO.util.DD class and feed in the id or element reference of the element that drag is to be enabled for. DragDrop Classes The base class of the Drag-and-Drop utility is YAHOO.util. DragDrop, but you'll use one of its extending subclasses, like YAHOO.util.DD, most of the time. This subclass inherits all of the properties and methods of the base class and even adds a few of its own, so it's more than capable of handling most of your drag-and-drop requirements. The YAHOO.util.DD class also has its own subclasses to deal with additional drag-and-drop requirements for different situations. The subclasses are YAHOO.util.DDProxy and YAHOO.widget.SliderThumb. As you can see, the Drag-and-Drop utility provides some of the basic functionality of another of the controls found in the YUI, the Slider Control (which we will look at in more detail towards the end of this article). Let's examine the DDProxy class, as that is relevant specifically to the Drag-and-Drop utility. Creating a proxy object that tracks with the cursor when a drag object is being dragged instead of allowing the actual drag object to track can prevent problems that arise with large drag objects not tracking properly or obscuring other content on the page. The proxy object is a small, empty object that represents the drag object and shows only its borders. The proxy object is created on the mouseDown event of the drag object and the actual drag object does not move to its new position until the mouseUp event is fired. Using a proxy object is both visually appealing and better overall for all but the simplest of implementations performance wise. The Constructor The constructor for an instance of the DragDrop object can also take a second or third argument when you are instantiating objects for dragging. The second argument, which is optional, specifies the group to which the element being dragged belongs. This refers to interaction groups—the object being dragged can only interact with and fire events with other elements in its interaction group. The third argument, which is also optional, can be used to supply a configuration object, the members of which hold additional optional configuration properties that can easily be accessed and set. Every object instantiated with the drag-and-drop constructor is a member of one or more interaction group(s), even if the second argument is not passed. When the argument is not supplied, the object will simply belong to the 'default' group instead. There is no limit as to how many groups an object can belong to. The API provides just two methods that relate to group access. .addToGroup() is used to add the object to more than one group, so the first group membership is defined with the constructor and subsequent groups with the .addToGroup() method. To remove an object from a group, just call the .removeFromGroup() method. Target Practice There is no doubt that drag-and-drop adds a hands-on, fun element to surfing the net that is way more engaging than simple point-and-click scenarios, and there are many serious applications of this behavior too. But dragging is only half of the action; without assigned drop targets, the usefulness of being able to drag elements on the page around at leisure is almost wasted. Drop targets have a class of their own in the Drag-and-Drop utility. Which extends the YAHOO.util.DragDrop base class to cater for the creation of drag elements that aren't actually dragable and this is the defining attribute of a drop target. The constructor is exactly the same as for the DD and Proxy classes with regard to the arguments passed, but YAHOO.util.DDTarget is used instead. The Target class has no methods or properties of its own, but it inherits all of the same methods and properties as the other two classes, including all of the events.
Read more
  • 0
  • 0
  • 4507

article-image-navigating-your-site-using-codeigniter-17-part-2
Packt
30 Nov 2009
9 min read
Save for later

Navigating Your Site using CodeIgniter 1.7: Part 2

Packt
30 Nov 2009
9 min read
Designing a better view At this stage, you might ask: Why are we going through so much effort to serve a simple HTML page? Why not put everything in one file? For a simple site, that's a valid point—but whoever heard of a simple site? One of the coolest things about CI is the way it helps us to develop a consistent structure. So, as we add to and develop our site, it is internally consistent, well laid out, and simple to maintain. At the start, we need to take these three common steps: Write a view page Write a stylesheet Update our config file to specify where the stylesheet is After this is done, we need to update our controller to accept parameters from the URL, and pass variables to the view. First, let's redesign our view and save it as testview.php, at /www/codeigniter/application/views/testview.php. <html><head><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0Strict//EN'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'><html ><title>Web test Site</title><link rel="stylesheet" type="text/css" href="<?php echo$base."/".$css;?>"></head><body><h1><?php echo $mytitle; ?> </h1><p class='test'> <?php echo $mytext; ?> </p></body></html> It's still mostly HTML, but notice the PHP "code islands" in the highlighted lines. You'll notice that the first bits of PHP code build a link to a stylesheet. Let's save a simple stylesheet as styles.css, at www/codeigniter/css/styles.css. It just says: h1{margin: 5px;padding-left: 10px;padding-right: 10px;background: #ffffff;color: blue;width: 100%;font-size: 36px;}.test{margin: 5px;padding-left: 10px;padding-right: 10px;background: #ffffff;color: red;width: 100%;font-size: 36px;} This gives us two styles to play with, and you'll see we've used both of them in the view. Firstly, let's add an entry to the config file: $config['css'] = 'css/styles.css'; This is simply to tell the name and address of the CSS file that we've just written to the site. But note that the link to the stylesheet is referenced at $base/$css: Where do those variables, $base and $css, get their values? And come to think of it, those variables $mytitle and $mytext at the end of the code? We need a new controller! Designing a better controller Now, we need a new controller. We'll call it Start and save it as start.php, at /www/codeigniter/application/controllers/start.php. This controller has to do several things: Call a view Provide the view with the base URL and the location of the CSS file we just wrote Provide the view with some data—it's expecting a title ($mytitle) and some text ($mytext) Lastly, accept a parameter from the user (that is using the URL request) In other words, we have to populate the variables in the view. So let's start with our Start controller. This is an OO class: <?phpclass Start extends Controller{var $base;var $css; Notice that here we've declared the $base and $css (the CSS filename) as variables or class properties. This saves us from having to redeclare them if we write more than one function in each class. But you can define and use them as local variables within one function, if you prefer. The constructor function now defines the properties we've declared, by looking them up in the config file. To do this, we use the syntax: $this->config->item('name_of_config_variable'); As in: function Start(){parent::Controller();$this->base = $this->config->item('base_url');$this->css = $this->config->item('css');} CI recovers whatever we entered in the config file against that name. Using this system, no matter how many controllers and functions we write, we'll have to change these fundamental variables only once. This is true even if our site becomes so popular that we have to move it to a bigger server. Getting parameters to a function Now, within the Start controller class, let's define the function that will actually do the work. function hello($name = 'Guest'){$data['css'] = $this->css;$data['base'] = $this->base;$data['mytitle'] = 'Welcome to this site';$data['mytext'] = "Hello, $name, now we're getting dynamic!";$this->load->view('testview', $data);} This function expects the parameter $name, but you can set a default value—myfunction($myvariable = 0), which it uses to build the string assigned to the $mytext variable. Well, as we just asked, where does that come from? In this case, it needs to come from the URL request, where it will be the third parameter. So, it comes through the HTTP request: http://127.0.0.1/codeigniter/start/hello/Jose This example code doesn't "clean" the passed variable Jose, or check it in any way. You might want to do this while writing the code. We'll look at how to check form inputs. Normally, variables passed by hyperlinks in this way are generated by your own site. A malicious user can easily add his or her own, just by sending a URL such as: http://www.mysite.com/index.php/start/hello/my_malicious_variable. So, you might want to check that the variables you receive are within the range you expect, before handling them. The last segment of the URL is passed to the function as a parameter. In fact, you can add more segments of extra parameters if you like, subject to the practical limits imposed by your browser. Let's recap on how CI handles URLs, since we've covered it all now: URL segment   What it does   http://www.mysite.com   The base URL that finds your site.   /index.php   Finds the CI router that sets about reading the rest of the URL and selecting the correct route into your site. If you have added the .htaccess file in the previous chapter, this part will not be visible, but will still work as supposed.   /start   The name of the controller that CI will call (If no name is set, CI will call whichever default controller you've specified).   /hello   The name of a function that CI will call, inside the selected controller (If no function is specified, it defaults to the index function, unless you've used _remap).   /Jose   CI passes this to the function as a variable.   If there is a further URL segment, for example, /bert   CI passes this to the function as the second variable. More variables   CI will pass further URL segments as consequent variables.   Passing data to a view Let's go back to the hello function: function hello($name){$data['css'] = $this->css;$data['base'] = $this->base;$data['mytitle'] = 'Welcome to this site';$data['mytext'] = "Hello, $name, now we're getting dynamic!";$this->load->view('testview', $data);} Notice how the hello() function first creates an array called $data, taking a mixture of object properties set up by the constructor and text. Then it loads the view by name, with the array it has just built as the second parameter. Behind the scenes, CI makes good use of another PHP function—extract(). This takes each value in the $data array and turns it into a new variable in its own right. So, the $data array that we've just defined is received by the view as a series of separate variables; $text (equal to "Hello, $name, now we're getting dynamic"), $css (equal to the value from the config file), and so on. In other words, when built, the $data array looks like this: Array([css] => 'mystyles.css';[base] => 'http://127.0.0.1/packt';[mytitle] => 'Welcome to this site';[mytext] => 'Hello, fred, now we're getting dynamic!';) But on its way to the view, it is unpacked, and the following variables are created in the view to correspond to each key/value pair in the array: $css = 'mystyles.css';$base = 'http://127.0.0.1/packt';$mytitle = 'Welcome to this site';$mytext = 'Hello, fred, now we're getting dynamic!';) Although you can only pass one variable to a view, you can pack a lot of information into it. Each value in the $data array can itself be another array, so you can pass pieces of information to the view in a tightly structured manner. Now navigate to http://127.0.0.1/codeigniter/start/hello/jose (note that the URL is different—it is looking for the start function we wrote in the index controller) and you'll see the result—a dynamic page written using MVC architecture. (well, VC at least! We haven't really used the M yet). You can see that the parameter jose is the last segment of the URL. It has been passed into the function, and then to the view. Please remember that your view must be written in parallel with your controller. If the view does not expect and make a place for a variable, it won't be displayed. If the view is expecting a variable to be set and it isn't, you are likely to get an error message (your view can of course accept variables conditionally). Also, a controller can use more than one view; this way we can separate our pages into sections such as the header, the menu, and so on. Each of these views can be nested one inside the other. Child views can even inherit variables passed by the controller to their parent view. Loading a view from inside another view is very easy; just put something like this PHP snippet in your HTML code: <body><div id="menu"><?php $this->load->view('menu'); ?> This way we can load a view inside a view, with all variables in the first one also available into the nested one.
Read more
  • 0
  • 0
  • 3765

article-image-drag-and-drop-yui-part-2
Packt
30 Nov 2009
12 min read
Save for later

Drag-and-Drop with the YUI: Part-2

Packt
30 Nov 2009
12 min read
Scripting DragDrop There are two ways that we could go about achieving our objective. We could take the easy way and treat each draggable object as an independent module, with its own independent properties and event handlers. This would make the code simpler, but would mean that we would require a good deal more of it. If there are just one or two objects on your page which can be dragged and dropped then this way is fine. However, when you begin to have more than just a couple of objects that can be moved, the amount of code required to handle these objects efficiently increases dramatically. The second way may be a little more complex and therefore will require a greater degree of understanding. However, this way allows for sharing properties and event handlers across similar drag-and-drop objects. This reduces the overall footprint of your application and saves us an incredible amount of typing. Creating Individual Drag Objects We can look at both methods, so you can see just how much work the second way saves us. We'll start with the easy method. Add the following <script> tag directly before the closing </body> tag: <script type="text/javascript">//create the namespace object for this exampleYAHOO.namespace("yuibook.dd");//define the setDDs functionYAHOO.yuibook.dd.setDDs = function() {//detect the useragentvar ua = YAHOO.env.ua;if (ua.ie != 0) {ua.data = "ie";}//define variablesvar basketTotal = 0;var basketTot = 0;var Dom = YAHOO.util.Dom;//create the 3 DragDropProxy objectsvar dd1 = new YAHOO.util.DDProxy("prod1");dd1.isTarget = false;dd1.scroll = false;var dd2 = new YAHOO.util.DDProxy("prod2");dd2.isTarget = false;dd2.scroll = false;var dd3 = new YAHOO.util.DDProxy("prod3");dd3.isTarget = false;dd3.scroll = false;var basket = new YAHOO.util.DDTarget("basket");//define function to call when dd1 starts being draggeddd1.startDrag = function() {//set cursor position to top-left of proxydd1.setDelta(0,0);}//define function to call when dd1 stops being dragdeddd1.endDrag = function() {}//define function to call when dd1 enters basketdd1.onDragEnter = function(e, id) {//has dd1 been dragged into basket?if (id == "basket") {//add 1 to the total number of itemsbasketTotal += 1;var tot = YAHOO.util.Dom.get("basketTotal")tot.innerHTML = basketTotal;//create new p element to hold product summaryvar p = document.createElement("p");Dom.addClass(p, "prod");p.id = "prod" + basketTotal;//add icon for product 1 to basketvar ico = document.createElement("img");ico.setAttribute("src", "images/prod1_ico.jpg");ico.id = "imageico" + basketTotal;Dom.addClass(ico, "icon");//add product 1 summary to basketp.appendChild(ico);Dom.get("basketBody").appendChild(p);//create new p element for product 1 titlevar p2 = document.createElement("p");var info = Dom.get("prod1info");//is the browser IE?if (ua.data == "ie") {var infos = info.innerHTML.split("<BR>");} else {var infos = info.innerHTML.split("<br>");}//set product 1 titlevar title = document.createTextNode(infos[0]);Dom.addClass(p2, "prodTitle");p2.id = "prodTitle" + basketTotal;//add title to basketp2.appendChild(title);Dom.insertAfter(p2, Dom.get(ico));//create p element for product 1 pricevar p3 = document.createElement("p");var price = document.createTextNode(infos[1]);Dom.addClass(p3, "prodPrice");p3.id = "prodPrice" + basketTotal;//add product 1 price to basketp3.appendChild(price);Dom.insertAfter(p3, Dom.get(p2));//update total basket priceprice = Dom.get(p3).innerHTML;var rawPrice = price.slice(1,6);var cost = parseFloat(rawPrice);basketTot += cost;var newBasketTot = Dom.get("basketCost");newBasketTot.innerHTML = basketTot;}}//define function to call when dd2 starts being draggeddd2.startDrag = function() {dd2.setDelta(0,0);}//define function to call when dd2 stops being draggeddd2.endDrag = function() {}//define function to call when dd2 enters basketdd2.onDragEnter = function(e, id) {if (id == "basket") {//add 1 to the total number of itemsbasketTotal += 1;var tot = YAHOO.util.Dom.get("basketTotal")tot.innerHTML = basketTotal;//create new p element to hold product summaryvar p = document.createElement("p");Dom.addClass(p, "prod");p.id = "prod" + basketTotal;//add icon for product 2 to basketvar ico = document.createElement("img");ico.setAttribute("src", "images/prod2_ico.jpg");ico.id = "imageico" + basketTotal;Dom.addClass(ico, "icon");//add product 2 summary to basketp.appendChild(ico);Dom.get("basketBody").appendChild(p);//create new p element for product 2 titlevar p2 = document.createElement("p");var info = Dom.get("prod2info");//is the browser IE?if (ua.data == "ie") {var infos = info.innerHTML.split("<BR>");} else {var infos = info.innerHTML.split("<br>");}//set product 2 titlevar title = document.createTextNode(infos[0]);Dom.addClass(p2, "prodTitle");p2.id = "prodTitle" + basketTotal;//add title to basketp2.appendChild(title);Dom.insertAfter(p2, Dom.get(ico));//create p element for product 2 pricevar p3 = document.createElement("p");var price = document.createTextNode(infos[1]);Dom.addClass(p3, "prodPrice");p3.id = "prodPrice" + basketTotal;//add product 2 price to basketp3.appendChild(price);Dom.insertAfter(p3, Dom.get(p2));//update total basket priceprice = Dom.get(p3).innerHTML;var rawPrice = price.slice(1,6);var cost = parseFloat(rawPrice);basketTot += cost;var newBasketTot = Dom.get("basketCost");newBasketTot.innerHTML = basketTot;}}//define function to call when dd3 starts being draggeddd3.startDrag = function() {dd3.setDelta(0,0);}//define function to call when dd3 stops being draggeddd3.endDrag = function() {}//define function for when dd3 enters basketdd3.onDragEnter = function(e, id) {if (id == "basket") {//add 1 to the total number of itemsbasketTotal += 1;var tot = YAHOO.util.Dom.get("basketTotal")tot.innerHTML = basketTotal;//create new p element to hold product summaryvar p = document.createElement("p");Dom.addClass(p, "prod");p.id = "prod" + basketTotal;//add icon for product 3 to basketvar ico = document.createElement("img");ico.setAttribute("src", "images/prod3_ico.jpg");ico.id = "imageico" + basketTotal;Dom.addClass(ico, "icon");//add product 3 summary to basketp.appendChild(ico);Dom.get("basketBody").appendChild(p);//create new p element for product 3 titlevar p2 = document.createElement("p");var info = Dom.get("prod3info");//is the browser IE?if (ua.data == "ie") {var infos = info.innerHTML.split("<BR>");} else {var infos = info.innerHTML.split("<br>");}//set product 3 titlevar title = document.createTextNode(infos[0]);Dom.addClass(p2, "prodTitle");p2.id = "prodTitle" + basketTotal;//add title to basketp2.appendChild(title);Dom.insertAfter(p2, Dom.get(ico));//create p element for product 3 pricevar p3 = document.createElement("p");var price = document.createTextNode(infos[1]);Dom.addClass(p3, "prodPrice");p3.id = "prodPrice" + basketTotal;//add product 3 price to basketp3.appendChild(price);Dom.insertAfter(p3, Dom.get(p2));//update total basket priceprice = Dom.get(p3).innerHTML;var rawPrice = price.slice(1,6);var cost = parseFloat(rawPrice);basketTot += cost;var newBasketTot = Dom.get("basketCost");newBasketTot.innerHTML = basketTot;}}}//execute setDDs when DOM is readyYAHOO.util.Event.onDOMReady(YAHOO.yuibook.dd.setDDs);</script> All of the code here sits within the setDDs() function, which is called using the Event utility's onDOMReady() method. The first section of code within the setDDs() function uses the .env.ua() method of the YAHOO global object to determine the user-agent string of the browsing environment. We can use this as a quick and easy way of detecting the browser being used to view the page. The ie property exists within the ua object even if IE is not in use, but if it isn't in use, the property is set to 0. Therefore, if the ie property does not equal to 0 it means that IE is the browser currently being used. In this case, the ie property will hold an integer representing the version of IE in use. When IE is being used, we set the data property of our ua variable to the string ie. We then create a series of variables for use in the script. The last variable is created purely for convenience. We'll be making heavy use of the DOM utility during this example, so defining that first part of the DOM call as a short variable helps make things easier on us. Next we create all three of the individual DDProxy objects. Remember, in this implementation, each object has to have its own properties and event handlers defined for it. We also define the basket as a DDTarget so that we can make use of the .onDragEnter() method. Because we want each product to interact only with our shopping basket and not the other products on the page, we have to set the .isTarget property to false. As well as being able to specifically create drop targets using the YAHOO.util.DDTarget class, any drag object is by default also a drop target. Additionally, we can switch off the .scroll property, which causes the viewport to scroll indefinitely when the dragged object exceeds the window boundary. Using DragDrop Events Three event handlers are required for this example: startDrag, endDrag, and onDragEnter. The startDrag event fires as soon as the left mouse button has been held down for the required length of time on a drag object, or the pointer moves the specified number of pixels. The .setDelta() method used in the startDrag event handler allows us to control where the pointer is relative to the drag object, or in this case, the proxy element. By specifying 0,0 as arguments for this method, we are instructing the pointer to appear at the top-left corner of the proxy element. This is needed so that the element is placed back where it began instead of where the pointer was relative to the drag object when the drag began. The endDrag event fires when a mouseup event is detected on the object being dragged. The anonymous function here has a very special purpose, even though it is just an empty function.What it does is ensure that the item being dragged is returned to its original position once it has been dropped instead of remaining where it was dropped. This is important because if we didn't keep the listing pictures in their proper locations, the page would soon be littered with abandoned drag objects. The onDragEnter event fires when the moving object is dragged over a legal target. Since the shopping basket is the only valid target on the page, this will fire whenever a product object is dragged over the basket. This function is where the bulk of our code lies. Two arguments are specified for this function. The first is the event object, which is automatically passed to our handler. The second argument is the id of the element that triggered the event, which in this example will be the basket. We first use our YAHOO.util.Dom shortcut to get the <span> element displaying the number of items in the basket, then use the innerHTML property to alter this value in accordance with the basketTotal variable. We create a new paragraph element and give it a class of prod. This new element will act as a container for a short summary of the item placed in the basket. We can go ahead and create the different items that will make up this short description of the product that has been purchased. A new <img> element is created and stored in the ico variable. Its src attribute is set to the icon representing the product. We then give it a class name so that we can style it and an id attribute so that we can identify it. Once created and configured, we can append the <img> to the new <p> element, and then append the <p> element to the body of the basket. Now let's work on extracting some of the listing description to display in the basket. We create another new <p> element and give it a class of prodTitle. We then need to do more detection to determine which product was dropped, getting the full listing text of the product in the title variable once we have. Each part of the listing text is separated by a <br> element, so we can create an array of each different bit of information contained in the listing text using the .split() method. This is the part of the script where we use the information gathered from the ua property earlier on. IE for some reason capitalizes all HTML elements in the DOM. This means that IE sees <BR> tags, while other browsers see <br>, and is the reason we need the if statement to determine the browser in use. The first item in the infos array is the name of the product, so we can use this as the title for the product summary and create a new textNode based on it. This title element is then inserted into the DOM directly after the icon element using the DOM utility's .insertAfter() method, which takes the element to insert and the element it should be inserted after as arguments. For good measure, let's add the price of the product to the product summary. A final element is created to hold a new textNode comprised of the second item in the infos array, which happens to be the price of the product. The class for the new <p> element is set and it is then inserted as a sibling of the previous element that was created. At the bottom of our basket is a price indicator showing the total cost of all items in the basket; we can easily update this using the same method as we updated the basket contents total earlier on. We recycle the price variable, updating it with the HTML element from the basket. As the price is currently a text string rather than a number, we have to convert it. Before we can do this however, we need to remove the currency symbol from the front of it, which we can do with the .slice() method. Then we can use the standard JavaScript parseFloat math function to convert the remaining string into a true floating-point number. We can then update the current cost by adding the cost of the dropped product to it. Finally, we set the innerHTML property of the basketCost span element to the new total. As each drag object is completely independent, the rest of our script is made up of identical event handlers tied to the other drag objects (products 2 and 3). This is what bloats our code to three times the size it actually needs to be, and imagine how much typing would need to be done if there were 30 products on the page
Read more
  • 0
  • 0
  • 1295
article-image-social-networks-and-extending-user-profile-drupal-part-2
Packt
27 Nov 2009
8 min read
Save for later

Social Networks and Extending the User Profile in Drupal: Part-2

Packt
27 Nov 2009
8 min read
Building the Profile The Content Profile module creates a new content type called Profile when it is enabled. By default, this content type is set to be used as a profile. We need to complete a few additional steps to make our profile fully functional. Edit the default settings for the Profile content type Configure the base Content Profile settings Add any required fields to the Profile content type Add any taxonomy terms to the Profile content type Assign rights to create and edit the Profile content type Edit the Settings of the Profile Content Type As mentioned above, when the Content Profile module is enabled, it creates a new content type named Profile. To use this new node type effectively, we need to change the default settings. To do this, click on the Administer | Site building | Content types link, or navigate to admin/content/types. Click the Edit link for the Profile content type. The Automatic Nodetitles module—enabled earlier in the first part of  this article—adds a new fieldset labeled Automatic title generation at the top of the administrative screens where we edit content types. As shown in the preceding screenshot, we have two options. For the first option, we want to select Automatically generate the title and hide the title field. For the second option—Pattern for the title—we should enter [author-name]'s profile. [author-name] is a token; when the node is created, the token will be replaced by the username of the person creating the node. So, if a user named Jill created the profile node, the title would be Jill's profile. The Token module allows us to use a wide range of tokens in addition to [author-name]. To see the full list of available tokens, expand the Replacement patterns fieldset as indicated in the preceding screenshot by Item 1. The settings listed here also need to be adjusted: In the Submission form settings section, delete the Body field label. We do not want this node type to have a body field; we will add all needed fields using CCK In the Workflow settings section, set the Default options to Published, and Attachments to Disabled In the Comment settings section, set the Default comment settings to Disabled After you have made the necessary adjustments, click the Save content type button to submit the form and save your changes. Configure the Base Content Profile Settings To configure the base Content Profile settings, click on the Administer  Site building | Content types link, or navigate to admin/content/types. Click the Edit link for the Profile content type. Then, click the Content Profile tab. The base settings allow us to configure how the node profile will be displayed on the user profile page. As shown in the preceding screenshot, in the User page display style section we have four options: Don't display this content profile on the user account page—only select this option if you will be overriding the core user profile page via the theming layer. This is an advanced theming technique; refer to the handbook page on overriding user profiles at http://drupal.org/node/35728. Display it as link to the profile content—select this option if you only want to link to the full profile node from the user profile page. Display the full content—this option displays the full node on the user profile page. Display the content's teaser—this option displays the teaser view on the profile page. As discussed later in this section, this option provides us some flexibility not found in the other options. For our example, choose this option. The final two options—Include an edit link to the display and Show a link to the content profile creation page, if there is no profile—should both be selected, as they improve usability. The Weight can be left at 0. When these settings have been adjusted as needed, click the Submit button to save the changes. Add Fields to the Profile Content Type Now that we have edited the defaults of the Profile node type, and adjusted the base settings of the Content Profile, we are ready to add fields and taxonomy terms to our profile. The CCK fields and Taxonomies will provide structure to our user profiles. For this example, we want to extend our profile by adding two fields, and one vocabulary. The fields we will add will both be text fields; one for a Brief bio, and the second for a Full bio. We will also add a Vocabulary to the Profile content type called Interests. Adding this vocabulary is covered in the next section of this article. Add the Brief Bio Field To add the text fields, go to the Content Types administration page by clicking the Administer | Content Management | Content Types link, or by navigating to admin/content/types. Click the manage fields link for the profile content type. In the Add section, we want to add a New field. Enter the following values: Label: Brief bio Field name: brief_bio Field type: text Widget type: text area (multiple rows) Click the Save button; this brings up the admin screen where you can configure the field. As shown in the preceding screenshot, the form to configure the text field has two sections: Profile settings and Global settings. Adjusting the Profile Settings In the Profile settings, we have two options; enter the values specified below: Rows: 3 Help text: Enter your brief bio. 500 characters maximum For this example, we do not need to set any Default value. Adjusting the Global Settings In the Global settings, we have four options; enter the values specified below: Required: No; leave unchecked Number of values: 1 Text processing: Plain text Maximum length: 500 For this example, we do not need to set any Allowed values. Once the field has been configured as needed, click the Save field settings button to save your changes. Adding the Full Bio Field Adding the Full Bio is nearly identical to adding the Brief bio. When adding the field, use the following values: Label: Full bio Field name: full_bio Field type: text Widget type: text area (multiple rows) Click the Save button; this brings up the admin screen where you can configure the field. In the Profile settings, enter: Rows: 5 Help text: Enter your full, extended biography. In the Global settings, we enter: Required: No; leave unchecked Number of values: 1 Text processing: Filtered text (user selects input format) Maximum length: none, leave blank Once the field has been configured as needed, click the Save field settings button to save your changes. Adjusting the Field Display As we discussed above when we configured the base options for Content Profiles, we want to show the node teaser on the user profile page. To take advantage of this option, we need to configure how we display our fields. To do this, go to the Content Types administration page by clicking the Administer | Content Management | Content Types link, or by navigating to admin/content/types. Click the edit link for the profile content type, and then, click the Display fields tab. As seen in the preceding screenshot, you can control how fields are displayed in the Teaser view and in the Full node view. In the settings shown in the preceding screenshot, we have set the Brief bio to show on the Teaser view (that is, on the user profile page), and the Full bio to display on the Full node view (that is, when the entire profile is being viewed). Our settings display a truncated overview on the user profile page, with a link to the more detailed full node view. Add Taxonomy Terms to the Profile Content Type As described above, we want to add an Interests vocabulary. To add new vocabularies, click on the Administer | Content management | Taxonomy| link, or navigate to admin/content/taxonomy. Click the Add vocabulary tab. Adding the Interest Vocabulary For Interests, enter the following values: Vocabulary name: Interests Description: none, leave blank Help text: Describe your interests. Separate each interest with a comma Content types: select Profile; leave others unchecked Settings: select Tags; leave others unchecked Weight: -6 Click the Save button to create the new vocabulary. Assign Rights to Profile Nodes Click on the Administer  User Management | Roles| link, or navigate to admin/user/roles. Select the role(s) that you would like to be able to create node-based profiles. Generally, users should be given the rights to create profile content, and edit own profile content. This will allow users to create their own profiles, and update them as needed, but also protects users from accidentally deleting their profile. Only site administrators or especially trusted users should be given the rights to edit any profile content or delete any profile content.
Read more
  • 0
  • 0
  • 1747

article-image-freebies-and-downloads-drupal-6-part-2
Packt
27 Nov 2009
3 min read
Save for later

Freebies and Downloads in Drupal 6: Part 2

Packt
27 Nov 2009
3 min read
Automatically generating PDF files for a page Good Eatin' Goal: Generate PDF files of our pages so that the users can automatically download the pages for printing, or for offline usage. Additional modules needed: Printer, email, and PDF (http://drupal.org/project/print). Basic steps As you continue to work on your web site, you will find that many users want access to your content, even if they aren't online. With the Printer, email, and PDF module, you can easily and automatically provide content in various formats for offline usage. To begin with, download and install the Printer, email, and PDF module. You can now configure the basic options for the module by selecting Site configuration and then Printer-friendly pages from the Administer menu. The general settings are accessed by clicking on the Settings tab. These settings are shown below, and include options to style the printable pages, and to determine whether or not URLs and comments are displayed on the page. You can also control how the page is opened, and also which logos are displayed on it. By expanding the Source URL section, you can cause the URL of the page to be included on the printed output. You can also optionally add the date and time when the page was generated to the printed output. The printable page (web page) configuration options include a variety of options to control how the links to the printable versions are displayed, as well as how the printable pages are displayed. We have modified the Printer-friendly page link to be in the Content corner rather than in the Links area. You can also optionally display the printable page in a new window and automatically call the print function, as needed. Opening the Advanced link options gives you additional options for how the link is displayed, and what pages it should be displayed on, as shown in the following screenshot: The Robots META tags section allows you to prevent search engines from indexing your printable version, which will help to ensure that visitors are directed only to your online content. This can also help prevent duplicate content penalties being imposed by search engines. To create PDFs, we need to install a third-party tool to handle the conversion. You can choose from either TCPDF or dompdf, which are available at the following locations: TCPDF: http://tcpdf.org dompdf: http://www.digitaljunkies.ca/dompdf/faq.php You can install and use either of these. You can also install both of them and switch between the two, while you evaluate which one will meet the needs of your site best. After you have installed TCPDF and/or dompdf, you can access the PDF tabbed page in the Printer-friendly pages configuration.
Read more
  • 0
  • 0
  • 1216

article-image-cissp-security-measures-access-control
Packt
27 Nov 2009
4 min read
Save for later

CISSP: Security Measures for Access Control

Packt
27 Nov 2009
4 min read
Knowledge requirements A candidate appearing for the CISSP exam should have knowledge in the following areas that relate to access control: Control access by applying concepts, methodologies, and techniques Identify, evaluate, and respond to access control attacks such as Brute force attack, dictionary, spoofing, denial of service, etc. Design, coordinate, and evaluate penetration test(s) Design, coordinate, and evaluate vulnerability test(s) The approach In accordance with the knowledge expected in the CISSP exam, this domain is broadly grouped under five sections as shown in the following diagram: Section 1: The Access Control domain consists of many concepts, methodologies, and some specific techniques that are used as best practices. This section coverssome of the basic concepts, access control models, and a few examples of access control techniques. Section 2: Authentication processes are critical for controlling access to facilities and systems. This section looks into important concepts that establish the relationship between access control mechanisms and authentication processes. Section 3: A system or facility becomes compromised primarily through unauthorized access either through the front door or the back door. We'll see some of the common and popular attacks on access control mechanisms, and also learn about the prevalent countermeasures to such attacks. Section 4: An IT system consists of an operating system software, applications, and embedded software in the devices to name a few. Vulnerabilities in such software are nothing but holes or errors. In this section we see some of the common vulnerabilities in IT systems, vulnerability assessment techniques, and vulnerability management principles. Section 5: Vulnerabilities are exploitable, in the sense that the IT systems can be compromised and unauthorized access can be gained by exploiting the vulnerabilities. Penetration testing or ethical hacking is an activity that tests the exploitability of vulnerabilities for gaining unauthorized access to an IT system. Today, we'll quickly review some of the important concepts in the Sections 1, 2,and 3. Access control concepts, methodologies, and techniques Controlling access to the information systems and the information processing facilities by means of administrative, physical, and technical safeguards is the primary goal of access control domain. Following topics provide insight into someof the important access control related concepts, methodologies, and techniques. Basic concepts One of the primary concepts in access control is to understand the subject and the object. A subject may be a person, a process, or a technology component that either seeks access or controls the access. For example, an employee trying to access his business email account is a subject. Similarly, the system that verifies the credentials such as username and password is also termed as a subject. An object can be a file, data, physical equipment, or premises which need controlled access. For example, the email stored in the mailbox is an object that a subject is trying to access. Controlling access to an object by a subject is the core requirement of an access control process and its associated mechanisms. In a nutshell, a subject either seeks or controls access to an object. An access control mechanism can be classified broadly into the following two types: If access to an object is controlled based on certain contextual parameters, such as location, time, sequence of responses, access history, and so on, then it is known as a context-dependent access control. In this type of control, the value of the asset being accessed is not a primary consideration. Providing the username and password combination followed by a challenge and response mechanism such as CAPTCHA, filtering the access based on MAC adresses in wireless connections, or a firewall filtering the data based on packet analysis are all examples of context-dependent access control mechanisms. Completely Automated Public Turing test to tell Computers and Humans Apart (CAPTCHA) is a challenge-response test to ensure that the input to an access control system is supplied by humans and not by machines. This mechanism is predominantly used by web sites to prevent Web Robots(WebBots) to access the controlled section of the web site by brute force methods The following is an example of CAPTCHA: If the access is provided based on the attributes or content of an object,then it is known as a content-dependent access control. In this type of control, the value and attributes of the content that is being accessed determines the control requirements. For example, hiding or showing menus in an application, views in databases, and access to confidential information are all content-dependent.
Read more
  • 0
  • 0
  • 10505
article-image-device-management-zenoss-core-network-and-system-monitoring-part-2
Packt
27 Nov 2009
9 min read
Save for later

Device Management in Zenoss Core Network and System Monitoring: Part 2

Packt
27 Nov 2009
9 min read
Model Devices When we talk about Zenoss, two related but different words often come up, monitoring and modeling. Monitoring refers to the availability of the device and answers the question, "Is the device accessible?" Modeling defines a relationship between devices and identifies the components available on a device, such as services, interfaces, and file systems. Zenoss models devices via SNMP, SSH, port scan, and telnet and gathers information via collector plug-ins. Each class has a default set of collector plug-ins that tells Zenoss how to model the devices assigned to the class. We can add or remove collector plug-ins at the device level for individual changes or at the class level for all the devices in the class. The collector plug-in names reflect the monitoring protocol they are used for. All the SNMP collectors contain "snmp" in the name. The SSH and telnet plug-in names contain "cmd," and the port scan plug-in contains "portscan" in the name. We'll step through modeling examples for SNMP, SSH, and port scan; however, we'll skip telnet because it's similar to SSH. SNMP Zenoss defaults to SNMP monitoring, and the monitored device needs to have SNMP installed and configured to work properly. Zenoss supports SNMP v1, v2c, and v3. The example commands used in this section to troubleshoot SNMP specify v1. Test SNMP If we're unsure of our SNMP setup, we can test it by running the snmpwalk command to retrieve the values of the MIB tree on the monitored device. We'll demonstrate both working and broken SNMP configurations on the MillRace network. From the Device List, select the device named Coyote. From the Device Status page menu, choose Run Commands > snmpwalk. A new window opens and we see the results of the snmpwalk command as shown in the following screenshot. Now we select the device Bobcat from the Device List view. Run the snmpwalk command from the Device Status page. This time, we receive a Timeout error, which indicates that we have a problem with SNMP on the device Bobcat as shown in the following screenshot. Assuming that SNMP is properly configured on the device and that the monitored device accepts traffic on port 161, we may need to update the device's community string. To update the community: Select the device from the Device List view. From the Device Status page menu, select More > zProperties. Find the Community field and enter the correct value. Save the changes. After updating the SNMP community string in the zProperties, we run the snmpwalk command again to see if we have fixed the problem. If we continue to encounter problems getting Zenoss to model a device with SNMP, we can try to narrow down the problem by running the following snmpwalk command from the monitored devices shell prompt: snmpwalk -v1 -c public localhost system Replace public with the correct community string. If the command is successful when using localhost, edit the snmpd configuration file. As root, edit /etc/default/snmpd or /etc/default/snmp and remove 127.0.0.1 from the following line: SNMPDPORTS = '-Lsd -Lf /dev/null -u snmp -I -smux -p /var/run/snmpd.pid 127.0.0.1' After editing the /etc/default/snmpd file, restart the snmpd service as root. For example: /etc/init.d/snmpd stop/etc/init.d/snmpd start Retest the snmpwalk command to confirm that SNMP is working correctly.Windows users can run wbemtest from the command line to test SNMP. Windows Considerations In order to collect information from WMI,regarding the Windows SNMP installation we need to configure the zProperties for the Windows device. Navigate to the Windows device and open the zProperties page by selecting the More > zProperties from the page menu. Scroll to the bottom of the page and make the following changes: Set zWinEventLog to true. Enter the Windows user's password in the zWinPassword field. Enter the user name with administrative rights in the zWinUser field in the following formats: .user for local user accounts DOMAINuser for domain user accounts Set zWMIMonitorIgnore to false. Save the changes, and Zenoss is ready to model the information on the Windows device. We can force a model by selecting Manage > Model Device from thepage menu. SNMP Collector Plug-ins The Collector Plug-ins assigned to the device determines how Zenoss models the device. Let's take a look at our example device Coyote and see what collectors are currently assigned. From the Device Status page for Coyote, select More > Collector Plug-ins from the page menu. A page showing the assigned collector plugi-ns displays in the left column of the page with an Add Fields link on the right. When we click on the Add Fields link, a column of unassigned plug-ins appears and the link name changes to Hide Fields as shown in the following screenshot. The plug-in names are intuitive in that the name suggests the type of information we expect to be modeling. For example, zenoss.snmp.IpServiceMap returns a list of active IP services on the device, such as HTTP. The Dell specif?i c plugi-ns retrieve more detailed information from Dell devices using OpenManage, and the HPplugi-ns provide more information about devices using Insight Management agents. To remove a plug-in from the assigned plug-in list, click on the "x" next to the plug-in name. To assign a plug-in, drag the plug-in name from available list to the assigned list. To see how our devices are affected, let's remove the zenoss.snmp.IpServiceMap and add zenoss.cmd.df. After we make the changes to the plug-ins for Coyote, scroll to the bottom of the page and click Save. Model Device Zenoss automatically models each device in our inventory every six hours, but we can manually force Zenoss to model the device. From the Device Status page, select Manage > Model Device from the page menu. Zenoss displays the results of the zenmodeler command in the window as shown in the following screenshot. Zenoss first determines which plugi-ns are available and then collects information based on those plug-ins. Notice that no cmd plug-ins are found, which means that the zenoss.cmd.df plug-in we added to Coyote will not be collected. After Zenoss models the device, we can review the device overview page to see what component types Zenoss discovered. IpService should not be listed. If we go back to the Collector Plug-ins page for Coyote, we can add the zenoss.snmp.IpService plug-in and then model the device again. Now, IpServices is displayed in the Component Type list as shown in the following screenshot. The Component Type list gets updated as part of the modeling process and so does the OS fields in the Device Information table (the greyed-out fields in the screen shot). If we enter values in these fields during the Add Device step, the values would be overwritten with the SNMP values. Our example made changes to the device level, which means that if we view the collector plug-ins for the /Server/Linux device class, the original plug-ins are specified. To view the plug-ins for the class: Select Devices from the navigation panel. Select Server from the sub-devices list. Select Linux from the sub-devices list. From the /Devices/Server/Linux page menu, select More > CollectorPlug-ins. Devices automatically inherit any changes we make to the class collector plug-ins the next time Zenoss models the devices. SSH Modeling If the monitored device does not support SNMP, or if we need to monitor a device behind a firewall, SSH provides an alternative to SNMP. Unlike SNMP, SSH needs the Zenoss Plug-ins installed on each monitored device and platform support is limited to Linux, Darwin, and FreeBSD. We also need to make sure that the monitored device has an SSH server installed so that the Zenoss system can log in and retrieve information. OpenSSH from openssh.com offers a good cross-platform SSH solution. The level of modeling provided by the Zenoss Plug-ins varies between platforms. For this reason, we may not achieve the same level of detail as we do with SNMP, but SSH modeling provides more detail than a port scan. To help us setup our SSH monitoring, Zenoss provides the /Server/Cmd class which is already configured with the command plug-ins we need to monitor via SSH. SSH Collector Plug-ins From the navigation panel, select Devices. Navigate to the /Server/Cmd class and click on the zProperties tab. Find the zCollectorPlug-ins field and click on the Edit link. A list of the assigned collector plug-ins is displayed as shown in the following screenshot. The important thing to note with the command collector plug-ins is the new level of specificity in the name. The zenoss.cmd.uname and zenoss.cmd.df plug-ins are common to all architectures, while the plug-ins with "linux" in the name work with Linux systems. Mac OS X platforms use the plug-ins with "darwin" in the name. If we did not have any any OS X systems to monitor, then we could remove allthe Darwin-based plug-ins from the /Server/Cmd class or, if we know that wedon't want to monitor the memory usage for any of our devices, we can removethat plug-in. We'll leave the collector plug-ins as they are for the /Server/Cmd class and change our test device Coyote to use SSH instead of SNMP. Zenoss Plug-ins Zenoss will monitor and retrieve some data using the SSH modeler even if we do not install the Zenoss plug-ins, but the device model will be incomplete. For example, file systems will be detected along with the size of each drive., but the usage statistics will not be reported. Zenoss also generates warning events if it cannot find the zenplugin.py command on the monitored system. The monitored system needs a Python environment installed. This can beinstalled using your distribution's package manager. If you have setuptoolsinstalled, you can install the Zenoss-Plug-ins package from the Cheese Shop (http://pypi.python.org/pypi/) with the following command as root: easy_install Zenoss-Plugins We can also build the Zenoss Plug-ins package from source: Download the Zenoss Plug-ins package from http://www.zenoss.com/download/. Extract the plug-in file. From the plug-in source directory, run the following commands as root: python setup.py build python setup.py install The setuptools procedure installs zenplugin.py to /usr/bin, which is important because we need to configure the device zProperties to look for the plug-ins in the correct location. To ensure that the plug-in file is working correctly, run the following command on the monitored device, which is Coyote in our example: zenplugin.py –list-plugins The command outputs the detected platform and the supported plug-ins as shown in the following screenshot.
Read more
  • 0
  • 0
  • 3930

article-image-business-rules-management-bpm-and-soa
Packt
27 Nov 2009
13 min read
Save for later

Business Rules Management, BPM, and SOA

Packt
27 Nov 2009
13 min read
Introduction to Business Rules Management Let us start by understanding some key concepts around business rules. What are Business Rules? Business rules can be defined as the key decisions and policies of the business. Rules are virtually everywhere in an organization; an example is the rule in a bank to deny a loan for a customer if his or her annual income is less than $15,000. We can generally categorize business rules under the following categories: Business Policies: These are rules associated with general business policies of a company, for example, loan approval policies, escalation policies, and so on. Constraints: These are the rules which business has to keep in mind, and work within the scope of while going about their operations. Rules associated with regulatory requirements will fall under this category. Computation: These are the rules associated with decisions involving any calculations, for example, discounting rules, premium adjustments, and so on. Reasoning capabilities: These are the rules that apply logic and inference course of actions based on multiple criteria. For example, rules associated with the up-sell or cross-sell of products and services to customers based on their profile. Allocation Rules: There are some rules that are applicable in terms of determining the course of action for the process, based on information from the previous tasks. They also include rules that manage the receiving, assignment, routing, and tracking of work. Business Rules Anatomy To understand the anatomy of a business rule, we can divide a business rule primarily into the following four blocks: Definitions of Terms: This helps in providing a vocabulary for expressing the rules. Defining a term acts as the category for the rules. For example, customer, car, claims, and so on define the entities for the business. Facts: These are used to relate terms in definitions with each other. For example, a customer may apply for a claim. Constraints: These are the constraints, limitations, or controls on how an organization wants to use and update the data. For example, for opening an account, a customer's passport details or social security details are required. Inference: This basically applies to logical assertions such as 'if X, then Y' to a fact, and infers new facts. For example, if we have a single account validation rule (if an applicant is a defaulter, then the applicant is high-risk), and we know that Harry (the applicant) has defaulted earlier on his payments for other bank services, we can infer that Harry is a high-risk customer. Automating Business Rules As we discuss the externalization and automation of business rules, it's important to understand the distinction between implicit and explicit rules. An implicit rule can be viewed as a rule that is a part of a larger context within the system. It's like multiple rules that are implemented in traditional applications to implement decision logic, for example, assessing the risk level for a loan. Its implementation is usually part of the application it is being developed for, and is never considered beyond the scope of the application, perhaps to be re-used. So Typically, in the IT world, these implicit rules are embedded within the complex application code and spread across multiple systems, making it extremely difficult to introduce changes quickly, and without creating a domino effect across systems. Some of these issues can be resolved by implementing a Business Rules Management System (BRMS) in collaboration with the BPM system in place. This allows the decision logic, which is being used by the process during its execution, to be driven by a central repository where all the rules are stored and managed. This repository provides a way to abstract the decision logic from the applications, and helps in managing this logic centrally, allowing for better management and flexibility for change and re-use. Hence, these rules are explicit in nature. For the loan approval example, business rules such as these would traditionally be embedded in application code, and might appear in an application as follows: public boolean checkAnnualIncome(Customer customer){boolean declineLoan = false;int income = customer.getincome();if( income < 10000 ){declineLoan = true;}return declineLoan;} The above example shows that this rule is obviously difficult for the business users to understand. In today's world, with the need for an organization to be agile, (considering our previous example) the business has to wait for weeks before a small change can be implemented by IT. What is required is the ability of the business users to define and control their own rules, and to be able to get the changes out in the market faster. Business Rules Management and related technology tries to solve this problem. Automating Business Rules for Business Issues Automation of business rules via BRMS is ideal for use, where the following issues are being faced by an organization: Dynamism and Volatility: Companies need to repeatedly change business policies, procedures, and products to meet the market needs. In this case, the rules change very dynamically, and having a BRMS can help in implementing these changes faster, and reducing the time to market and cost of implementation. Time to Market: In this case, the organization might want a particular set of changes to be released quickly due to market pressure, or to gain a competitive advantage. So, Even though the rules are not changed very often, a delay in their implementation could lead to a serious business loss. In this case, the organization needs to have the ability to get these changes in quickly, without roadblocks, which can be addressed by a BRMS. Regulatory Compliance: Failure to comply with regulatory requirements such as Anti-Money Laundering (AML) laws can result in millions of dollars in fines, and legal issues for the organizations. To solve these issues, institutions can combine business rules with SOA to create an effective strategy for enforcing compliance. Business rules technology helps in implementing these rules quickly, and helps them to be kept up–to-date across an enterprise. Business Participation: There could be rules which might be better off being controlled and owned by the business users. In this case, a BRMS can expose certain rules to be managed and edited by selected business users, providing an easy to use interface. Rules related to product configuration, customer eligibility, discounts and so on, are some examples where business users can manage the rules, and change them as required by changing scenarios. Complexity: Some scenarios, such as complex product and service pricing, require extremely complex dependencies between several rules to implement the scenario logic. These kinds of rules are best suited for implementation inside a BRMS rather than a procedural language, as is being done traditionally. Telecom Fraud Management, for example, is an area where rules management is being used along with BAM to identify potential frauds. There are similar applications in credit card and banking industries. Consistency: Rules managed centrally provides a more consistent way of managing certain policies requiring re-use and consistency across the enterprise. This is especially true in cases where inconsistency was an issue due to multiple applications, databases, and different lines of businesses. Business Rules Management, BPM, and SOA Business Rules Management, BPM, and SOA share a synergistic relationship, especially, when used together to provide agility to an organization. The term 'Agility' can be defined as "the ability of an enterprise to sense and predict change in their environment and respond quickly, efficiently, and effectively to that change". Agility, requires the organization to be flexible enough in introducing change and in modifying their current operations, to achieve higher levels of performance or output. A process-driven approach to SOA allows business users to introduce changes to the process for faster execution, and with less cost. This value is amplified by using a Business Rules platform alongside process orchestration. If we look at the BPM reference architecture again, rules functionality features in various layers of the architecture, in the initial rules discovery phase, during process mapping, and in its orchestration in the SOA environment. Business Rules-related technologies have been in the market for a number of years now. However, with the acceptance of BPM and SOA as enablers for increasing an organization's agility, today's enterprises are increasingly looking at using rules management to externalize their rules. Business rules management helps automate decisions and apply policies within processes. Automation of these decisions requires determining the meaning of a given situation, and applying a business policy in response to this. Business rules platforms provide tools to define this 'reasoning' logic for use by either developers or business analysts, and business stakeholders. Organizations are looking at Business Rules Management to deploy rules related to policy decisions, work allocation, compliance and control, business exception management, and even data validation. For example, a major financial services company uses business rules to apply privacy and anti-fraud policies to all of its transactions. Even more, these Business Rules are being considered as an asset for an organization that should be managed centrally and re-used across departments and systems, instead of being hard-coded into an application. So, it is important to ensure that business rules have a place in your SOA. Carefully defining and exposing your rules as services will enable all of the applications and services within your architecture to have simple access to a common rules repository. From an SOA perspective, before beginning a business rules implementation, you should: Incorporate a business rules platform into your SOA: This would be a service-enabled repository of your business rules, where instead of data you would maintain and execute rulesets using a business rules engine. Create standards and best practices for developing business rules: To maximize benefits from your rules implementation, you should focus on developing common standards and best practices for discovery, design, development, and interfacing of your rules. Some of the best practices for writing and designing business rules are: Declarative: Business rules should be declared, and not stated as procedures as in coding. How a rule will be enforced should not be part of a rule definition. For example, "If the customer is a premium customer, offer him further 5% discount." Precise: It's easier for business rules definitions to be misinterpreted due to the use of natural language syntax by business. One business rule should be open to only one interpretation, and would need rephrasing if it was found to be ambiguous. Consistency and non-redundancy: Business rules should be consistent and not conflict other rules. Similarly, you should look out for business rules that are redundant. Business Focused and Owned: Business rules should be declared using the business vocabulary so that they can understood by relevant business stakeholders. Avoid using technical jargons in business rules. Also business rules are best left under the ownership of the business, community, as that is the source for the rules. Key Considerations for Selecting a BRMS The following are some key considerations when selecting a BRMS to work with BPM and SOA: Standards-based Integration capability: The ability to integrate with the SOA landscape using a service layer. Business User Interface: The ability to provide the capability for business users to access and modify business rules through a user-friendly interface. Rule Language: The ability to provide support for natural languages for easily expressing a complex set of rules. Performance: The ability to provide support for high-volume transactions for mission-critical applications, which is normally measured in terms of the number of rules processed per second. Rules Monitoring and Reporting: The ability to feature support for rules debugging, rules reporting, and real time monitoring of rules. Rules Repository: The ability to provide a centralized repository for storing all rule-specific artifacts. The repository should also support change management by storing different versions of rules, and providing audit capabilities. Key components of a BRMS—A Brief Look into Oracle Business Rules Typically, a BRMS will comprise four main components: Business UI: This is a user interface component for writing and editing business rules. Typically, it will be a web-based interface for business users to log in and access existing business rules, create new ones, and so on. Rules Development Environment: Developers will be working in this environment to convert business rules defined by business users into code that can be implemented in the business rules engine. This will be also an environment where the service layer for the rules will be defined and implemented for integration with other applications and SOA components. Rules Repository: This will be a centralized repository where all rules-related information will be stored. Rules Execution Engine: This is the heart of the rules management system and will be responsible for executing the business rules in the run time environment. In SOA terms, this component will receive request for rules processing from the business process orchestration environment, based on which, it will run appropriate rules and provide decision information that will be sent back to the orchestration layer. Oracle also provides a suite of components under its Oracle Business Rules product to support rules management and execution, which are as follows: Oracle Rule Author: Rule Author provides a web-based graphical authoring environment that enables the easy creation of business rules via a web browser. The application developer uses Rule Author to define a data model and an initial set of rules. The business analyst uses Rule Author either to work with the initial set of rules, or to modify and customize the initial set of rules according to business needs. Using Rule Author, a business analyst can create and customize rules with little or no assistance from a programmer. Rules Engine: This is the heart of the rules system and executes and manages rules in a proper and efficient manner. This allows inference-based rule execution, based on the very popular Rete algorithm. The Rete algorithm is an efficient pattern-matching algorithm used for rules and facts, and stores partially-matched results in a single network of nodes in current working memory, allowing the rules engine to avoid unnecessary rechecking when facts are deleted, added, or modified. Oracle's rules engine provides a data-driven forward-changing system. This means that the facts will determine which rules can be triggered. When a particular rule is triggered, based on pattern matching within a set of facts, the rule may further add new facts. The new facts are again run against the rules as an iterative process untill it reaches an end state. This allows rules to be interlinked and triggered in a cycle, also referred to as an inference cycle.The rules engine also provides a web service interface with its SOA environment using 'Decision Services', which is available in a JDeveloper environment during the coding of business processes in BPEL. This can also be used to make a web service call to rules running in the rules engine. It also exposes a Rules API, which is based on JSR 94, a runtime specification for rules engines to integrate business rules application with other applications in an organization. Rule Repository: A rule repository is the database that stores business rules. The Oracle rules repository allows rules to be grouped as rulesets, and make it part of the rules dictionary in a central repository. These dictionaries can be versioned for better governance. Oracle's rules repository supports a WebDAV (Web Distributed Authoring and Versioning) repository and a file repository. Rules SDK: This allows users to develop and integrate the Rules Repository in to a custom authoring environment. This component also allows the development of a customized UI for business users to access and update the Rules repository, if required.
Read more
  • 0
  • 0
  • 4156
Modal Close icon
Modal Close icon