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-slider-dynamic-applications-using-scriptaculous-part-2
Packt
08 Oct 2009
4 min read
Save for later

Slider for Dynamic Applications using script.aculo.us (part 2)

Packt
08 Oct 2009
4 min read
Code usage for sliders with options We are now done with the most important part of the slider: the implementation of the slider in our applications. But wait, we need the slider to suit our applications, right? So let's customize our slider with options. We have mentioned earlier that track is the range of values. So let's first define the range for our slider. window.onload = function() { new Control.Slider('handle1' , 'track1', { axis:'vertical', range:$R(1,100)} The range option uses the Prototypes' objectRange instance. Hence, we declare it using $R (minimum, Maximum). Everything looks neat until here. Let's add some more options to our constructor, onSlide(). Using the onSlide() callback every time, we drag the slider and the callback is invoked. The default parameter passed to onSlide() is the current slider value. window.onload = function() { new Control.Slider('handle1' , 'track1', { axis:'vertical', range:$R(1,100), onSlide: function(v) { $('value1').innerHTML = "New Slide Value="+v;} }} We have added a div called value1 in our HTML code. On dragging the slider, we will update the value1 with the current slider value. OK, so let's see what happened to our slider to this point. Check out the following screenshot: Impressed? And, we are not done yet. Let's add more options to the slider now. You may ask me, what if the slider in the application needs to be at a particular value by default? And I will say use the sliderValue option. Let's make our slider value 10 by default. Here is the snippet for the same: window.onload = function() {      new Control.Slider('handle1' , 'track1',     {   axis:'vertical',   range:$R(1,100),   sliderValue: 10,   onSlide: function(v) { $('value1').innerHTML = "New Slide                                                 Value="+v;}} And, you should see the slider value at 10 when you run the code. Now your dear friend will ask, what if we don't want to give the range, but we need to pass the fixed set of values? And you proudly say, use the values option. Check out the usage of the values options in the constructor. window.onload = function() { new Control.Slider('handle1' , 'track1', { range:$R(1,25), values:[1, 5,10,15,20,25], onSlide:function(v){ $('value1').innerHTML = "New Slide Value="+v;} } );} We have added a set of values in the array form and passed it to our constructor. Let's see what it looks like. Tips and tricks with the slider After covering all the aspects of the slider feature, here is a list of simple tips and tricks which we can make use of in our applications with ease. Reading the current value of the slider script.aculo.us "genie" provides us with two callbacks for the slider to read the current value of the slider. They are: onSlide onChange Both these callbacks are used as a part of options in the slider. onSlide contains the current sliding value while the drag is on. The callback syntax is shown as follows: onSlide: function(value) {// do something with the value while sliding. Write or Edit thevalue //of current slider value while sliding} onChange callback will contain the value of the slider while the sliding or the drag event ends. After the drag is completed and if the value of the slider has changed then the onChange function will be called. For example, if the slider's current value is set to 10 and after sliding we change it to 15, then the onChange callback will be fired. The callback syntax is shown as follows: onChange: function(value){// do anything with the "changed" and current value} Multiple handles in the slider Now, a thought comes to our mind at this point: Is it possible for us to have two handles in one track? And, the mighty script.aculo.us library says yes! Check out the following code snippet and screenshot for a quick glance of having two handles in one track: HTML code<div id="track1"><div id="handle1"></div><div id="handle2"></div></div> JavaScript code for the same: window.onload = function() { new Control.Slider(['handle1','handle2'] , 'track1');} Now, check out the resulting screenshot having two handles and one track: The same can also be applied for the vertical slider too.
Read more
  • 0
  • 0
  • 2130

article-image-schema-validation-using-sax-and-dom-parser-oracle-jdeveloper-xdk-11g
Packt
08 Oct 2009
6 min read
Save for later

Schema Validation using SAX and DOM Parser with Oracle JDeveloper - XDK 11g

Packt
08 Oct 2009
6 min read
The choice of validation method depends on the additional functionality required in the validation application. SAXParser is recommended if SAX parsing event notification is required in addition to validation with a schema. DOMParser is recommended if the DOM tree structure of an XML document is required for random access and modification of the XML document. Schema validation with a SAX parser In this section we shall validate the example XML document catalog.xml with XML schema document catalog.xsd, with the SAXParser class. Import the oracle.xml.parser.schema and oracle.xml.parser.v2 packages. Creating a SAX parser Create a SAXParser object and set the validation mode of the SAXParser object to SCHEMA_VALIDATION, as shown in the following listing: SAXParser saxParser=new SAXParser();saxParser.setValidationMode(XMLParser.SCHEMA_VALIDATION); The different validation modes that may be set on a SAXParser are discussed in the following table; but we only need the SCHEMA-based validation modes: Validation Mode Description NONVALIDATING The parser does not validate the XML document. PARTIAL_VALIDATION The parser validates the complete or a partial XML document with a DTD or an XML schema if specified. DTD_VALIDATION The parser validates the XML document with a DTD if any. SCHEMA_VALIDATION The parser validates the XML document with an XML schema if any specified. SCHEMA_LAX_VALIDATION Validates the complete or partial XML document with an XML schema if the parser is able to locate a schema. The parser does not raise an error if a schema is not found. SCHEMA_STRICT_VALIDATION Validates the complete XML document with an XML schema if the parser is able to find a schema. If the parser is not able find a schema or if the XML document does not conform to the schema, an error is raised. Next, create an XMLSchema object from the schema document with which an XML document is to be validated. An XMLSchema object represents the DOM structure of an XML schema document and is created with an XSDBuilder class object. Create an XSDBuilder object and invoke the build(InputSource) method of the XSDBuilder object to obtain an XMLSchema object. The InputSource object is created with an InputStream object created from the example XML schema document, catalog.xsd. As discussed before, we have used an InputSource object because most SAX implementations are InputSource based. The procedure to obtain an XMLSchema object is shown in the following listing: XSDBuilder builder = new XSDBuilder();InputStream inputStream=new FileInputStream(new File("catalog.xsd"));InputSource inputSource=new InputSource(inputStream);XMLSchema schema = builder.build(inputSource); Set the XMLSchema object on the SAXParser object with setXMLSchema(XMLSchema) method: saxParser.setXMLSchema(schema); Setting the error handler As in the previous section, define an error handling class, CustomErrorHandler that extends DefaultHandler class. Create an object of type CustomErrorHandler, and register the ErrorHandler object with the SAXParser as shown here: CustomErrorHandler errorHandler = new CustomErrorHandler();saxParser.setErrorHandler(errorHandler); Validating the XML document The SAXParser class extends the XMLParser class, which provides the overloaded parse methods discussed in the following table to parse an XML document: Method Description parse(InputSource in) Parses an XML document from an org.xml.sax.InputSouce object. The InputSource-based parse method is the preferred method because SAX parsers convert the input to InputSource no matter what the input type is. parse(java.io.InputStream in) Parses an XML document from an InputStream. parse(java.io.Reader r) Parses an XML document from a Reader. parse(java.lang.String in) Parses an XML document from a String URL for the XML document. parse(java.net.URL url) Parses an XML document from the specified URL object for the XML document. Create an InputSource object from the XML document to be validated, and parse the XML document with the parse(InputSource) object: InputStream inputStream=new FileInputStream(newFile("catalog.xml"));InputSource inputSource=new InputSource(inputStream);saxParser.parse(inputSource); Running the Java application The validation application SAXValidator.java is listed in the following listing with additional explanations: First we declare the import statements for the classes that we need. import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import oracle.xml.parser.schema.*;import oracle.xml.parser.v2.*;import java.io.IOException;import java.io.InputStream;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;import org.xml.sax.helpers.DefaultHandler;import org.xml.sax.InputSource; We define the Java class SAXValidator for SAX validation. public class SAXValidator { In the Java class we define a method validateXMLDocument. public void validateXMLDocument(InputSource input) {try { In the method we create a SAXParser and set the XML schema on the SAXParser. SAXParser saxParser = new SAXParser();saxParser.setValidationMode(XMLParser.SCHEMA_VALIDATION);XMLSchema schema=getXMLSchema();saxParser.setXMLSchema(schema); To handle errors we create a custom error handler. We set the error handler on the SAXParser object and parse the XML document to be validated and also output validation errors if any. CustomErrorHandler errorHandler = new CustomErrorHandler();saxParser.setErrorHandler(errorHandler);saxParser.parse(input);if (errorHandler.hasValidationError == true) {System.err.println("XML Document hasValidation Error:" + errorHandler.saxParseException.getMessage());} else {System.out.println("XML Document validateswith XML schema");}} catch (IOException e) {System.err.println("IOException " + e.getMessage());} catch (SAXException e) {System.err.println("SAXException " + e.getMessage());}} We add the Java method getXMLSchema to create an XMLSchema object. try {XSDBuilder builder = new XSDBuilder();InputStream inputStream =new FileInputStream(new File("catalog.xsd"));InputSource inputSource = newInputSource(inputStream);XMLSchema schema = builder.build(inputSource);return schema;} catch (XSDException e) {System.err.println("XSDException " + e.getMessage());} catch (FileNotFoundException e) {System.err.println("FileNotFoundException " +e.getMessage());}return null;} We define the main method in which we create an instance of the SAXValidator class and invoke the validateXMLDocument method. public static void main(String[] argv) {try { InputStream inputStream = new FileInputStream(new File("catalog.xml")); InputSource inputSource=new InputSource(inputStream); SAXValidator validator = new SAXValidator(); validator.validateXMLDocument(inputSource); } catch (FileNotFoundException e) { System.err.println("FileNotFoundException " + e.getMessage()); }} Finally, we define the custom error handler class as an inner class CustomErrorHandler to handle validation errors. private class CustomErrorHandler extends DefaultHandler {protected boolean hasValidationError = false;protected SAXParseException saxParseException = null;public void error(SAXParseException exception){hasValidationError = true;saxParseException = exception;}public void fatalError(SAXParseException exception){hasValidationError = true;saxParseException = exception;}public void warning(SAXParseException exception){}}} Copy the SAXValidator.java application to SAXValidator.java in the SchemaValidation project. To demonstrate error handling, add a title element to the journal element. To run the SAXValidator.java application, right-click on SAXValidator.java in Application Navigator, and select Run. A validation error gets outputted. The validation error indicates that the title element is not expected.
Read more
  • 0
  • 0
  • 6063

article-image-creating-new-zen-cart-template
Packt
08 Oct 2009
11 min read
Save for later

Creating a new Zen Cart Template

Packt
08 Oct 2009
11 min read
Creating A File System Let us start building a new template for Zen Cart by creating a new folder under includes/templates/. Let us name it Packt (or whatever you like). But remember to use underscore instead of spaces in a long name. Avoid using Book Shop. Instead, use book_shop or BookShop. images' folder —will contain all the images needed for the template. css' folder — will contain all the CSS files for the template. It's better to copy all the files from the includes/templates/template_default/css directory to this css folder. common' folder — will contain the common files for the template. You may copy the files from the includes/templates/template_default/common folder, and edit those to suit your needs. sideboxes'folder — will contain module-specific sideboxes. Here, you can add new sideboxes, which you are going to use. templates folder — contains page-specific templates. Whenever you want to change a page's layout, copy the template for that page to this directory and modify it as required. Information regarding a template is located in the template_info.php file. You need to create a new template_info.php file for the new template. Copy the file called includes/templates/template_default/template_info.php into the new template folder, and then open the template_info.php file in your favorite text editor. Change the text between each set of single quotes to suit your new template. <?php $template_name = 'Packt Publishing'; $template_version = 'Version 1.0'; $template_author = 'Suhreed Sarkar'; $template_description = 'This template is designed for Packt Publishing'; $template_screenshot = ''; ?> Remember to keep the single quotes. Your template name does not need to be identical to your folder name, and you can use spaces to make it read well, but it is best to keep them similar. Leave the space between the quotes for the template screenshot field empty for now, as you don't have one yet. When you've finished, your new file structure should appear as follows: Open your Admin panel and navigate to Tools | Template Selection. Click the Edit button, then choose Packt Publishing from the drop-down menu and click the Update button. Now, navigate to Tools | Layout boxes controller, and click the Reset button at the bottom of the page. Your new template is now enabled and ready to be customized. Using Overrides When building a new template for Zen Cart, you can use its powerful overriding feature. Overriding means using some template as the base and extending it by adding different properties through separate templates. For example, you may want to make some modifications to the default template—template_default. You could modify the files in the template_default directory to do this. But due to its overriding character, you can add the changes in the new template, say packt, which will apply the changes to the shop. In fact, you can override any file in the path includes/templates/ template_default. Files in this directory generally determine the layout and the HTML formatting of your web pages. By default, Zen Cart has two standard templates: template_default and classic, both of which are located in the includes/templates/ folder. Out of these two standard templates, only template_default contains a full set of files. Every other template contains only the files that differ from template_default. If your template does not contain a particular file, Zen Cart will pull that file from template_default. Graphics You need to add your templates graphics to the appropriate folders. The header image, logo, background image, background image for sidebox headings, and so on should be placed in the images directory under your template directory. If you want to change the buttons and icons, create the graphic files in the GIF, JPG or PNG format and put them in the /includes/templates/template_name/buttons/language_name folder. Then, update the button_names.php file to define the button image file name, and the ALT texts for those images. Sideboxes You do not need to copy existing sideboxes from the template_default directory, as these will automatically be displayed. If you are planning to develop a new sidebox, put the template for that sidebox in the sideboxes folder under your template directory. A sidebox consists of three files, which are located in the includes directory: modules/sideboxes/template_name/name_of_sidebox.php' languages/english/extra_definitions/template_name/ name_of_sidebox_defines.php ' templates/template_name/sideboxes/tpl_name_of_sidebox.php ' You need to replace template_name and name_of_sidebox with you template name and the sidebox name respectively. For example, let us build a sidebox named my_sidebox. Then, my_sidebox.php file will read like this: <?php $show_my_sidebox = true; if ($show_my_sidebox == true){ require($template->get_template_dir('tpl_my_sidebox.php', DIR_WS_TEMPLATE, $current_page_base,'sideboxes'). '/tpl_my_sidebox.php'); $title = BOX_HEADING_MY_SIDEBOX; $left_corner = false; $right_corner = false; $right_arrow = false; require($template->get_template_dir($column_box_default, DIR_WS_TEMPLATE, $current_page_base,'common') . '/' . $column_box_default); } ?> This page actually defines what is to be shown in that sidebox. Note that this page also includes the corresponding template file. Here, we have used a constant BOX_HEADING_MY_SIDEBOX. You need to define this in the includes/languages/english/extra_definitions/packt/my_sidebox_defines.php file. This file will look like this: <?php define('BOX_HEADING_MY_SIDEBOX', 'My Sidebox'); ?> Now, you have to build its template file includes/templates/packt/sideboxes/tpl_my_sidebox.php, which will read as: <?php $content = "This is my first Sidebox. I have created it in 5 minutes. Although it is not of practical use yet, I hope I can eventually build a good sidebox."; ?> If you have created these files for the packt template, you can try it by going to Tools | Layout Boxes Controller in the administration panel. From here, turn the sidebox ON and set it up to display in the left or the right side column. This sidebox will look like the following figure. Stylesheets All stylesheets for your new template should be placed in the /includes/templates/template_name/css folder. You should follow stylesheet naming conventions. It is a good idea to copy an old stylesheet and then modify it to suit your needs. You can have multiple stylesheets for your shop you can even add a stylesheet for each page. As a design rule, try to keep the declarations minimal, simple, and self explanatory. Try to restrain yourself from changing the class and ID names in the core files. Creating and Modifying Email Templates As a store owner, you need to send several mails to your existing and potential customers. All these emails use some templates that reside in the /email folder under the Zen Cart installation directory. To change these emails to your style, you may edit these templates. The email's structure is determined in one of two ways. If you are sending plain text emails, the email structure is determined by the way you put together the various items (customer greeting, order number, link to detailed invoice, and so on) in a string variable that is then passed to the zen_mail() function. If you are sending HTML emails, the structure is determined by the template you use. Text Email Template You can rearrange, add, or delete items in a plain text email. To do so, you will need to edit the Zen Cart files where the email is created. For example, if you want to edit the order confirmation email, you will need to edit the file includes/classes/order.php. In your example, open up includes/classes/order.php and scroll down to the bottom of the file, in the function send_order_email(). There, you will see the lines that construct the plain text email message: [Line 827]$email_order = EMAIL_TEXT_HEADER . EMAIL_TEXT_FROM . STORE_NAME . "nn" . $this->customer['firstname'] . ' ' . $this->customer['lastname'] . "nn" . EMAIL_THANKS_FOR_SHOPPING . "n" . EMAIL_DETAILS_FOLLOW . "n" . EMAIL_SEPARATOR . "n" . EMAIL_TEXT_ORDER_NUMBER . ' ' . $zf_insert_id . "n" . EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "n" . EMAIL_TEXT_INVOICE_URL . ' ' . zen_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $zf_insert_id, 'SSL' [Line 848]$email_order .= zen_db_output($this->info['comments']) . "nn";[Line 855]$email_order .= EMAIL_TEXT_PRODUCTS . "n" . EMAIL_SEPARATOR . "n" . $this->products_ordered . EMAIL_SEPARATOR . "n"; In this file, the variable that holds the plain text email message is called $email_order. It generally has a different name in each file, such as $email or $email_text. Whatever its name, this is the place where you will make your changes. You can add, delete, and rearrange the order of the items to suit your wishes. HTML Email Templates HTML Email templates have two parts: embedded CSS and HTML codes. You may be surprised to see the embedded stylesheet in each mail template, and may want to know why linked stylesheets have not been used. One reason for not using the linked stylesheet is that you may not know how the email clients will behave. Most email clients used today can handle HTML emails and stylesheets to some extent. But there is no guarantee that every customer will have an email client that can retrieve linked stylesheets and render the emails in the desired format. Stylesheets The first portion of the email template is devoted to defining styles for different parts of the mail. Open the /email/email_template_welcome.html file in your favorite text editor to examine the stylesheet in an email template. The stylesheet in this template will appear as follows: <style type="text/css">.body {background-color:#ffffff; color:#000000; font-family:Verdana, Arial, Helvetica, sans-serif;}....header {font-size:10px; padding:0px; width:550px;}.content {font-size:10px; padding:5px; width:550px;}.content-line {padding:5px;}.coupon-block { padding: 5px; border: 1px #cccccc solid; background-color: #FFFF99; }....disclaimer1 a:link {color:#666666;}.disclaimer1 a:visited {color:#666666;}.disclaimer2 { color: #666666; padding: 5px; }.copyright { border-bottom: 0px #9a9a9a solid; padding: 5px; }</style> Style declarations in this stylesheet are straight-forward. First, it has defined style for the body and hyperlinks. Then, it defines the content and email related styles. Most of the style names are self-explanatory. You will find the HTML blocks with these names in the template. HTML with variables The main part of the email template is the HTML code with style classes and variables. The following are some of the variables used to construct content for the email: $EMAIL_GREETING $EMAIL_WELCOME $COUPON_BLOCK $GV_BLOCK $EMAIL_MESSAGE_HTML $EMAIL_CONTACT_OWNER $EMAIL_CLOSURE $EMAIL_FOOTER_COPYRIGHT $EMAIL_DISCLAIMER $EMAIL_SPAM_DISCLAIMER $EXTRA_INFO These variables are defined in several PHP files, such as create_account.php. Once you have found the files that need to be edited, you may want to add a definition for your new HTML item to each one. For example, you have added an item called $EMAIL_HOURS_OF_OPERATION to the email_template_order_status.html template. One of the files that you will need to edit is admin/orders.php. Find the part of that file where the email message is being constructed. In this case, it begins around line 100. You can see that the HTML message is constructed with several statements such as: $html_msg['EMAIL_CUSTOMERS_NAME'] = $check_status->fields['customers_name'];$html_msg['EMAIL_TEXT_ORDER_NUMBER'] = EMAIL_TEXT_ORDER_NUMBER . ' ' . $oID; All you need to do is add a new statement under all of these, to define your new item: $html_msg['EMAIL_HOURS_OF_OPERATION'] = 'We are open from 9 AM to 5 PMevery day of the week.'; Use a $ in front of the name of your new item in the HTML template, but do not use the $ where you define it. To change the text displayed in your emails, edit the corresponding language file. You can change an existing text, or add a new one (if you've added it to your email structure). You add or change text values using the define() statements: define(EMAIL_LOVELY_YOU_DROPPED_BY,'We are just so immeasurably delighted that you stopped by our store today!'); There is another language file you need to modify when altering text for your emails, includes/languages/english/email_extras.php. This file contains several text strings common to all emails sent from your store. Summary Thus we have seen how to create new template using Zen Cart.   If you have read this article you may be interested to view : Integrating Zen Cart with Content Management Systems Installing Zen Cart Troubleshooting Zen Cart  
Read more
  • 0
  • 0
  • 4215

article-image-social-bookmarking-wordpress-plugin
Packt
08 Oct 2009
6 min read
Save for later

Social Bookmarking with WordPress Plugin

Packt
08 Oct 2009
6 min read
You will learn these by creating a Social Bookmarking type of plugin that adds a Digg button to each post on your blog As you probably know, Digg is a very popular service for promoting interesting content on the Internet. The purpose of a Digg button on your blog is to make it easier for Digg users to vote for your article and also to bring in more visitors to your blog. The plugin we'll create in this article will automatically insert the necessary code to each of your posts. So let's get started with WordPress plugin development! Plugging in your first plugin Usually, the first step in plugin creation is coming up with a plugin name. We usually want to use a name that is associated with what the plugin does, so we will call this plugin, WP Digg This. WP is a common prefix used to name WordPress plugins. To introduce the plugin to WordPress, we need to create a standard plugin header. This will always be the first piece of code in the plugin file and it is used to identify the plugin to WordPress. Time for action – Create your first plugin In this example, we're going to write the code to register the plugin with WordPress, describe what the plugin does for the user, check whether it works on the currently installed version of WordPress, and to activate it. Create a file called wp-digg-this.php in your favorite text editor. It is common practice to use the plugin name as the name for the plugin file, with dashes '-' instead of spaces. Next, add a plugin information header. The format of the header is always the same and you only need to change the relevant information for every plugin: <?php /* Plugin Name: WP Digg This Version: 0.1 Description: Automatically adds Digg This button to your posts. Author: Vladimir Prelovac Author URI: http://www.prelovac.com/vladimir Plugin URI: http://www.prelovac.com/vladimir/wordpress-plugins/ wp-digg-this */ ?> Now add the code to check the WordPress version: /* Version check */ global $wp_version; $exit_msg='WP Digg This requires WordPress 2.5 or newer. <a href="http://codex.wordpress.org/Upgrading_WordPress">Please update!</a>'; if (version_compare($wp_version,"2.5","<")) { exit ($exit_msg); } ?> Upload your plugin file to the wp-content/plugins folder on your server using your FTP client. Go to your WordPress Plugins admin panel. You should now see your plugin listed among other plugins: This means we have just completed the necessary steps to display our plugin in WordPress. Our plugin can be even activated now—although it does not do anything useful (yet). What just happened? We created a working plugin template by using a plugin information header and the version check code. The plugin header allows the plugin to be identified and displayed properly in the plugins admin panel. The version check code will warn users of our plugin who have older WordPress versions to upgrade their WordPress installation and prevent compatibility problems. The plugin information header To identify the plugin to WordPress, we need to include a plugin information header with each plugin. The header is written as a PHP comment and contains several fields with important information. This code alone is enough for the plugin to be registered, displayed in the admin panel and readied for activation. If your future plugin has more than one PHP file, the plugin information should be placed only in your main file, the one which will include() or require()  the other plugin PHP files. Checking WordPress versions To ensure that our plugin is not activated on incompatible WordPress versions, we will perform a simple WordPress version check at the very beginning of our code. WordPress provides the global variable $wp_version that provides the current WordPress version in standard format. We can then use PHP function version_compare() to compare this and our required version for the plugin, using the following code: if (version_compare($wp_version,"2.6","<")) { // do something if WordPress version is lower then 2.6 } If we want to stop the execution of the plugin upon activation, we can use the exit() function with the error message we want to show. In our case, we want to show the required version information and display the link to the WordPress upgrade site. $exit_msg='WP Digg This requires WordPress 2.6 or newer. <a href="http://codex.wordpress.org/Upgrading_WordPress">Please update!</a>'; if (version_compare($wp_version,"2.6","<")) { exit ($exit_msg); } While being simple, this piece of code is also very effective. With the constant development of WordPress, and newer versions evolving relatively often, you can use version checking to prevent potential incompatibility problems. The version number of your current WordPress installation can be found in the footer text of the admin menu. To begin with, you can use that version in your plugin version check (for example, 2.6). Later, when you learn about WordPress versions and their differences, you'll be able to lower the version requirement to the minimal your plugin will be compatible with. This will allow your plugin to be used on more blogs, as not all blogs always use the latest version of WordPress. Checking the plugin You can go ahead and activate the plugin. The plugin will be activated but will do nothing at this moment. Time for Action – Testing the version check Deactivate the plugin and change the version check code to a higher version. For example, replace 2.6 with 5.0. if (version_compare($wp_version,"5.0","<")) Re-upload the plugin and try to activate it again. You will see a WordPress error and a message from the plugin: What just happened? The version check fails and the plugin exits with our predefined error message. The same thing will happen to a user trying to use your plugin with outdated WordPress installation, requiring them to update to a newer version. Have a go Hero We created a basic plugin that you can now customize. Change the plugin description to include HTML formatting (add bold or links to the description). Test your plugin to see what happens if you have two plugins with the same name (upload a copy of the file under a different name).
Read more
  • 0
  • 0
  • 7031

article-image-liferay-mail-and-sms-text-messenger-portlet
Packt
08 Oct 2009
5 min read
Save for later

Liferay Mail and SMS Text Messenger Portlet

Packt
08 Oct 2009
5 min read
Working with Mail Portlet For the purpose of this article, we will use an intranet website called book.com  which is created  for a fictions company named "Palm Tree Publications". In order to let employees manage their emails, we can use the Liferay Mail portlet. As an administrator of "Palm Tree Publications", you need to create a Page called "Mail" under the Page, "Community" at the Book Lovers Community Public Pages and also add the Mail portlet in the Page, "Mail". Experiencing Mail Management First of all, login as "Palm Tree". Then, let's do the above as follows: Add a Page called "Mail" under the Page "Community" at the Book Lovers Community Public Pages, if the Page is not already present. If the Mail portlet is not already present, add it in the Page, "Mail" of the Book Lovers Community where you want to manage mails. You will see the Mail portlet as shown in the following figure. Let's assume that we set up the mail domain as "cignex.com" in the Enterprise Admin portlet for testing purposes, as we have a mail engine with this mail domain already. Of course, you could set up the mail domain as "book.com", or something else, if you had a mail engine with this mail domain in your hand. As an editor of the editorial department, "Lotti Stein", you may want to manage your mails in the mail domain, "cignex.com". You can first choose a user name for your personal company the email address, say "admin1234" and register. Let's do it as follows: Login as "Lotti Stein". Go to the Page "Mail" under the Page, "Community", at the Book Lovers community Public Pages. Locate the Mail portlet. Input the value for User name as "admin1234". Click the Register button. Your new email address is "admin1234@cignex.com". This email address will also serve as your login, as shown in the following figure. You can now check for new messages in your inbox, by clicking the Inbox link first. Then, you can view the Unread messages, and either Check Mail or create a New mail, as shown in the following figure: You can go to the Page of Mail management by clicking on any link of Unread Messages, or Check Mail button or New button. Further, you can manage emails through the Mail portlet of your current account. Email management includes the following features (as shown in the following figure): Create a New email. Check Mail. Reply to an email. Reply All emails. Forward emails. Delete emails. Print emails, and Search. Note that the first email with the subject, "Users in Staging server", is sent through the SMS Text Messenger portlet. For more details, refer to the forthcoming section. How to Set up Mail Server? In order to make the Mail portlet work, we have to set up a mail server with IMAP, POP and SMTP protocols. Suppose that the Enterprise "Palm Tree Publications" has a mail server with the domain "exg3.exghost.com", an account "admin@cignex.com/admin1234", and protocol IMAP, POP and SMTP. As an administrator, you need to integrate this mail server with IMAP, POP and SMTP protocol in Liferay. Let's do it as follows: Find the file ROOT.xml in $TOMCAT_DIR/conf/Catalina/localhost. Find the mail configuration first. Then configure it as follows: <!-- Mail --><Resourcename="mail/MailSession"auth="Container"type="javax.mail.Session"mail.imap.host="exg3.exghost.com"mail.imap.port="143"mail.pop.host="exg3.exghost.com"mail.pop.port="110"mail.store.protocol="imap"mail.transport.protocol="smtp"mail.smtp.host="exg3.exghost.com"mail.smtp.port="2525"mail.smtp.auth="true"mail.smtp.starttls.enable="true"mail.smtp.user="admin@cignex.com"password="admin1234"mail.smtp.socketFactory.class="javax.net.ssl.SSLSocketFactory"/> In short, a Mail portlet is an AJAX web-mail client. We can configure it to work with any mail server. It reduces page refreshes, since it displays message previews and message lists in a dual pane window. How to Set up Mail Portlet? If you have proper Permissions, you can change the preferences of the Mail portlet. To change the preferences, you can simply click the Preferences icon to the upper right of the Mail portlet. With the Recipients tab selected, you can find potential recipients from the Directory (Enabled or Disabled) and the Organization (My Organization or All Available). Click the Save button after making any changes. Using the Filters tab, you can set the values to filter emails associated with an email address to a Folder. Click the Save button after making any changes. Note that the maximum number of email addresses is ten. This number is also configurable at the portal-ext.properties Similarly, the Forward Address tab allows all emails to be forwarded to the email address you want. Enter one email address Per Line. Remove all entries to disable email forwarding. Select Yes to leave, or No to not leave a copy of the forwarded message. Click the Save button after making any changes. Further, the Signature tab also allows you to set up your signature using HTML text editor. The signature you have set up will be added to each outgoing message. Click the Save button after making any changes. The Vacation Message tab allows you to set up vacation messages using HTML text editor. The vacation message notifies others of your absence (as shown in the following figure). Click the Save button after making any changes.
Read more
  • 0
  • 0
  • 3715

article-image-jquery-ui-dialog-part-1
Packt
08 Oct 2009
8 min read
Save for later

jQuery UI—The Dialog: Part 1

Packt
08 Oct 2009
8 min read
The following screenshot shows a dialog widget and the different elements that it is made of: A basic dialog A dialog has a lot of default behavior built-in, but few methods are needed to control it programmatically, making this a very easy widget to use that is also highly configurable. Generating it on the page is very simple and requires a minimal underlying mark-up structure. The following page contains the minimum mark-up that's required to implement the dialog widget: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.dialog.css"> <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.resizable.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Dialog Example 1</title> </head> <body> <div id="myDialog" class="flora" title="This is the title">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpat ligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti. Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.dialog.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.resizable.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.draggable.js"></script> <script type="text/javascript"> //define function to be executed on document ready $(function(){ //create the dialog $("#myDialog").dialog(); }); </script> </body></html> Dialog properties An options object can be used in a dialog's constructor method to configure various dialog properties. Let's look at the available properties: Save this as dialog1.html in the jqueryui folder. A few more source files are required, specifically the ui.resizable.js and ui.draggable.js files and the flora.resizable.css stylesheet. The JavaScript files are low-level interaction helpers and are only required if the dialog is going to be resizable and draggable. The widget will still function without them. The dialog flora theme file is a mandatory requirement for this component, although the resizable one isn't. Other than that, the widget is initialized in the same way as other widgets. When you run this page in your browser, you should see the default dialog widget shown in the previous screenshot, complete with draggable and resizable behaviors. One more feature that I think deserves mentioning here is modality. The dialog comes with modality built-in, although it is disabled by default. When modality is enabled, a modal overlay element, which covers the underlying page, will be applied. The dialog will sit above the overlay while the rest of the page will be below it. The benefit of this feature is that it ensures the dialog is closed before the underlying page becomes interactive again, and gives a clear visual indicator that the dialog must be closed before the visitor can proceed. Custom dialog skins The dialog's appearance is easy to change from the flora theme used in the first example. Like some of the other widgets, certain aspects of the default or flora themes are required to make the widget function correctly. Therefore, when overriding styles, we need to be careful to just override the rules related to the dialog's display. When creating a new skin for the default implementation, including resizable behavior, we have a lot of new files that will need to be created. Apart from new images for the different components of the dialog, we also have to create new images for the resizing handles. The following files need to be replaced when skinning a dialog: dialog-e.gif dialog-n.gif dialog-ne.gif dialog-nw.gif dialog-s.gif dialog-se.gif dialog-sw.gif dialog-title.gif dialog-titlebar-close.png dialog-titlebar-close.png To make it easier to remember which image corresponds to which part of the dialog, these images are named after the compass points at which they appear. The following image illustrates this: Note that these are file names as opposed to class names. The class names given to each of the different elements that make up the dialog, including resizable elements, are similar, but are prefixed with ui- as we'll see in the next example code. Let's replace these images with some of our own. In a new file in your text editor, create the following stylesheet: .flora .ui-dialog, .flora.ui-dialog { background-color:#99ccff;}.flora .ui-dialog .ui-dialog-titlebar, .flora.ui-dialog.ui-dialog-titlebar { background:url(../img/dialog/my-title.gif) repeat-x; background-color:#003399;}.flora .ui-dialog .ui-dialog-titlebar-close, .flora.ui-dialog.ui-dialog-titlebar-close { background:url(../img/dialog/my-title-close.gif) no-repeat; }.flora .ui-dialog .ui-dialog-titlebar-close-hover, .flora.ui-dialog.ui-dialog-titlebar-close-hover { background:url(../img/dialog/my-title-close-hover.gif) norepeat;}.flora .ui-dialog .ui-resizable-n, .flora.ui-dialog .ui-resizable-n { background:url(../img/dialog/my-n.gif) repeat center top;}.flora .ui-dialog .ui-resizable-s, .flora.ui-dialog .ui-resizable-s { background:url(../img/dialog/my-s.gif) repeat center top;}.flora .ui-dialog .ui-resizable-e, .flora.ui-dialog .ui-resizable-e { background:url(../img/dialog/my-e.gif) repeat right center; }.flora .ui-dialog .ui-resizable-w, .flora.ui-dialog .ui-resizable-w { background:url(../img/dialog/my-w.gif) repeat left center;}.flora .ui-dialog .ui-resizable-ne, .flora.ui-dialog .ui-resizable-ne{ background:url(../img/dialog/my-ne.gif) repeat;}.flora .ui-dialog .ui-resizable-se, .flora.ui-dialog .ui-resizable-se{ background:url(../img/dialog/my-se.gif) repeat;}.flora .ui-dialog .ui-resizable-sw, .flora.ui-dialog .ui-resizable-sw{ background:url(../img/dialog/my-sw.gif) repeat;}.flora .ui-dialog .ui-resizable-nw, .flora.ui-dialog .ui-resizable-nw{ background:url(../img/dialog/my-nw.gif) repeat;} Save this as dialogTheme.css in the styles folder. We should also create a new folder within our img folder called dialog. This folder will be used to store all of our dialog-specific images. All we need to do is specify new images to replace the existing ones used by flora. All other rules can stay the same. In dialog1.html, link to the new file with the following code, which should appear directly after the link to the resizable stylesheet: <link rel="stylesheet" type="text/css" href="styles/dialogTheme.css"> Save the change as dialog2.html. These changes will result in a dialog that should appear similar to the following screenshot: So you can see that skinning the dialog to make it fit in with your existing content is very easy. The existing image files used by the default theme give you something to start with, and it's really just a case of playing around with colors in an image editor until you get the desired effect. Dialog properties An options object can be used in a dialog's constructor method to configure various dialog properties. Let's look at the available properties: Property Default Value Usage autoOpen true Shows the dialog as soon as the dialog method is called bgiframe true Creates an <iframe> shim to prevent <select> elements showing through the dialog in IE6 - at present, the bgiframe plugin is required, although this may not be the case in future versions of this widget buttons   {} Supplies an object containing buttons to be used with the dialog dialogClass ui-dialog Sets additional class names on the dialog for theming purposes draggable true Makes the dialog draggable (use ui.draggable.js) height 200(px) Sets the starting height of the dialog hide none Sets an effect to be used when the dialog is closed maxHeight none Sets a maximum height for the dialog maxWidth none Sets a maximum width for the dialog minHeight 100(px) Sets a minimum height for the dialog minWidth 150(px) Sets a minimum width for the dialog modal false Enables modality while the dialog is open overlay {} Object with CSS properties for the modal overlay position center Sets the starting position of the dialog in the viewport resizable true Makes the dialog resizable (also requires ui.resizable.js) show none Sets an effect to be used when the dialog is opened stack true Causes the focused dialog to move to the front when several dialogs are open title none Alternative to specifying title on source element width 300(px) Sets the original width of the dialog
Read more
  • 0
  • 0
  • 1768
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-microsoft-office-excel-programming-using-vsto-30
Packt
08 Oct 2009
10 min read
Save for later

Microsoft Office Excel Programming Using VSTO 3.0

Packt
08 Oct 2009
10 min read
Microsoft Office Excel is the most frequently-used Microsoft application and one of the leading spreadsheet programs available. A spreadsheet program is a program that uses a huge grid to display data in rows and columns. The spreadsheet program can then be used to do calculation, data manipulation, and various similar tasks, against this data. Programming in Excel Microsoft Office Excel is one of the powerful Office tools that provides uncomplicated data management. It is loaded with features such as graphing, charting, pivot tables, and calculation. Even though Excel is loaded with numerous features for users, there may be some functionality that cannot be achieved by using the standard Microsoft Excel environment. In Microsoft Office Excel 2007, automation is a great mechanism for populating business documents (for example, reports) with data from backend system. This can be achieved by using VSTO 3.0 and Visual Studio 2008. Microsoft Office Excel 2007 is more programmable than ever before with support for Visual Studio Tools for Office. VSTO is aimed at Microsoft Office Excel users who want to develop Excel-based applications for other Microsoft Office Excel users. VSTO 3.0 is shipped with all of the newly-enhanced Excel objects, including improved features for building Microsoft Office based solutions. VSTO 3.0 is loaded with new features, including support for Windows form controls from within Microsoft Office tools customization. It provides the support for using .NET frameworks, objects and classes for Microsoft Office tools customization. For example, System.Data is the .NET frameworks object that can be used inside the Excel solution to process database operations. This new feature is tightly integrated with the Visual Studio 2008 IDE and gives you the comfort of design time customization of Excel documents for data display and UI customization. Similar to other Microsoft Office Tools, with Microsoft Office Excel 2007 customization using VSTO 3.0, you have two levels of customization— document-level customization and application-level customization. Document-level customization is a solution created for document-level programming and is specific to the document that is part of that particular solution. Application-level customization is a solution created for application-level programming and is specific to the application, and therefore common to all documents based on that application. In a simple Hello World demonstration, let's learn about the document level customization approach. We'll step through a simple task, showing how to create an Excel document that will display a Hello World message on startup. Hello World example using Visual Studio 2008 Open Visual Studio 2008, and create a new Excel 2007 Workbook project. Select New Project. Under Office select 2007, and then select the Excel 2007 Workbook template and name the project ExcelHelloWorld, as shown in the following image: The document selection dialog box is displayed. At this point, you need to choose the template for your design. In this example, you select a new blank template and click on the OK button. Refer to the following screenshot: The solution will be created with all of the supporting files required for our development of an Excel solution. Each solution is created with three worksheets, with default names: Sheet1, Sheet2, and Sheet3 for the workbook you're going to customize , as shown in the following image. The number of sheets in a new workbook depends on the settings in Excel. The following image also shows you the Excel-supported controls, placed on the leftmost side of the Visual Studio 2008 toolbox panel. You can also see the visual representation of Excel 2007 inside Visual Studio 2008. Let's write our Hello World message in a cell when we load the Excel 2007 document. Write the following code inside the ThisWorkbook.cs file. // The Startup event of workbook in our Excel solution// Startup event common to all Office application// Startup event will be fired at the start of the applicationprivate void ThisWorkbook_Startup(object sender,System.EventArgs e){// Creating the instance of active WorkSheet of Excel DocumentExcel.Worksheet AuthorWorkSheet = ThisApplication.ActiveSheetas Excel.Worksheet;// Get the range using number index through Excel cellsby setting AuthorExchange to an Excel range object starting at(1,1) and ending at (1,1)Excel.Range AuthorExcelRange = ThisApplication.get_Range(AuthorWorkSheet.Cells[1, 1],AuthorWorkSheet.Cells[1, 1]);// Setting the value in the cellAuthorExcelRange.Value2 = "Hello! this is my VSTO program forExcel 2007";} The following screenshot results after adding and executing the preceding code: Manipulation Microsoft Office Excel is one of the most comprehensive data management tools for all kinds of users. It is a tool that can be easily understood and quickly learnt. The most important feature of Microsoft Office Excel is its capability to manipulate data from different sources. Excel is one of the most powerful and user-friendly data manipulation applications. You could use Excel to predict what's ahead for your business by creating detailed financial forecasts. This powerful application has pivot table functionality that allows you to drop in your data and rearrange it to answer all kinds of business data analysis type questions. Excel helps you to build various useful analytical tools such as your monthly sales report and product sales growth analysis more easily and flexibly. Excel offers you formulae and functions that will help you to perform complex financial calculations without any manual errors. Excel can provide you with a graphical presentation of your business data by using charts and graphs. Want to know your growth levels for a specific product sales range? Check which parts of your business are performing worse? The pivot table provides more information from your business in depth. Every application in this computer world works with data. The data can be in any form and can belong to different sources. The key question for data management is where to place the data. You manage the data in two ways: data managed outside the program and data managed inside the program. The data managed outside the program includes data managed in a database, a file system, and so on. Data managed inside the program includes data in different worksheets within the workbook, embedded images, and so on. Data manipulation For users who are not satisfied with the default features in Microsoft Office Excel, VSTO programming makes Excel more flexible, and provides a development tool for the creation of custom solutions for data manipulation and data analysis. Custom programming using VSTO 3.0 improves most part of the Microsoft Office Excel solution. Custom programming using VSTO 3.0 provides a wide range of advantages, including saving time by automating most of the frequently-performed tasks, reducing errors due to manual operations, as well as enforcing standards for data processing, and building the capability to seamlessly integrate with other applications seamlessly. Reading worksheet cells There are many ways to manipulate data and write to the cells in an Excel worksheet. Let's see some of these ways. We can read worksheet cells directly through the Cells property of the sheets, rows, and columns, and can set a value directly by using the cell's row and column index. Open Visual Studio 2008 and create a new Excel solution. Refer to the previous example for full instructions of how to do this. Write the following code inside the ThisWorkbook.cs file. In this sample explanation, you are writing data into the worksheet by using the Cells object. // The Startup event of workbook in our Excel solutionprivate void ThisWorkbook_Startup(object sender,System.EventArgs e){// Set value for Cells row and column index// Text data in Sheet1 cellsGlobals.Sheet1.Cells[3, 3] = "Set my data";} We can also read the worksheet and write data to the cells by using the Range object. In this case, you are creating the range and setting the text data for the range in the Excel worksheet. Open Visual Studio 2008 and create a new solution, as before. Write the following code inside the ThisWorkbook.cs file . In this demonstration, you read the worksheet through the range of cells and set the value by reading through cell ranges. private void ThisWorkbook_Startup(object sender,System.EventArgs e){// Setting value in ExcelSheet cells through reading range objectExcel.Range AuthorExcelSheetRange = Globals.Sheet1.Range["A2","B2"];// Text data for the range A2 to B2AuthorExcelSheetRange.Value2 = "Set my data";} Let's see a demonstration of how to read data from an external data file and display this inside our Excel cells. In this demonstration, you will see how the data from the text (.txt) file is displayed in the spreadsheet. Opening a text file as a workbook using VSTO We'll now see how to open the text file as a workbook by using VSTO and C# programming. This saves time and makes the user more comfortable in accessing the text file while processing the data. Open Visual Studio 2008 and create a new solution, as before. Write the following code inside the ThisWorkbook.cs file: // Opening Text file as workbookprivate void ThisWorkbook_Startup(object sender,System.EventArgs e){// In the workbook objects, file path as parameter in Opentextproperty this.Application.Workbooks.OpenText(@"C:TechBooks.txt",// Value 1 is, the row from which it will read data in the textfile missing, 1,// Checks for delimits for text parsingExcel.XlTextParsingType.xlDelimited,// Text Enumeration valueExcel.XlTextQualifier.xlTextQualifierNone,missing, missing, missing, true, missing, missing, missing,missing, missing, missing, missing, missing, missing);} Connecting with Microsoft SQL Server 2008 database Microsoft SQL Server 2008 is a relational database management system developed by Microsoft Corporation. Microsoft SQL Server is used to manage a huge volume of data along with relation and Metadata information for this data. VSTO provides support for manipulating the data from your database inside Excel using ADO.NET classes. The preceding figure demonstrates how an Excel 2007 object is used to interact with the Microsoft SQL Server database. Let's see how to connect with a relational database management system, retrieve data from the database, and finally display it in our Excel spreadsheet. This demonstration shows you how to retrieve data from a Microsoft SQL Server 2008 database and place the retrieved data into the worksheet cells. Open Visual Studio 2008 and create a new solution, as usual. Write the following code inside the ThisWorkbook.cs file. // Namespace for SQL Server connectionusing System.Data.SqlClient;// Startup event of the workbookprivate void ThisWorkbook_Startup(object sender,System.EventArgs e){// Opening SQL connection for Microsoft SQL Server 2008// WINNER the database server contains the databse called ProductsSqlConnection MySQLConnection = new SqlConnection(@"DataSource=WINNER;Initial Catalog=Products;Integrated Security=True");// Passing SQL command textSqlCommand MySQLCommand = new SqlCommand("SELECT * FROMBooks", MySQLConnection);MySQLConnection.Open();// SQL reader to read through data from DatabaseSqlDataReader MySQLReader = MySQLCommand.ExecuteReader();// Get the active sheet of current applicationExcel.Worksheet MyWorkSheet = this.Application.ActiveSheet asExcel.Worksheet;// Header for the columns set in the Value2 properties((Excel.Range)MyWorkSheet.Cells[1, 1]).Value2 = "Book Name";((Excel.Range)MyWorkSheet.Cells[1, 2]).Value2 = "Author Name";// Indexerint i = 2;// Loop to read through the database returned datawhile (MySQLReader.Read()){// Writing the data from the database table column BookName((Excel.Range)MyWorkSheet.Cells[i, 1]).Value2 =MySQLReader["BookName"];// Writing the data from the database table column Author((Excel.Range)MyWorkSheet.Cells[i, 2]).Value2 =MySQLReader["Author"];i++;}// Dispose the SQL commandMySQLCommand.Dispose();// Closing SQL connection after using it.MySQLConnection.Close();} The following screenshot displays data retrieved from Microsoft SQL Server 2008 database and the data being displayed in the worksheet cells. In this demonstration, you learned how to connect with a Microsoft SQL Server 2008 database in order to get data and populate it in a workbook. This is just one of the ways of manipulating data outside of a workbook.
Read more
  • 0
  • 0
  • 10339

article-image-developing-seam-applications
Packt
08 Oct 2009
10 min read
Save for later

Developing Seam Applications

Packt
08 Oct 2009
10 min read
Seam application architecture As most enterprise Java developers are probably familiar with JSF and JSP, we will be using this as the view technology for our sample applications. Facelets is the recommended view technology for Seam-based applications once we have a solid understanding of Seam. In a standard Java EE application, Enterprise Application Resource (EAR) files contain one or more Web Application Resource (WAR) files and one or more sets of Java Archive (JAR) files containing Enterprise JavaBeans (EJB) functionality. Seam applications are generally deployed in exactly the same manner as depicted in the following diagram. It is possible to deploy Seam onto a servlet-only container (for example, Tomcat) and use POJOs as the server-side Seam components. However, in this situation, we don't get any of the benefits that EJBs provide, such as security, transaction handling, management, or pooling. Seam components Within Seam, components are simple POJOs. There is no need to implement any interfaces or derive classes from a Seam-specific base class to make Seam components classes. For example, a Seam component could be: A simple POJO a stateless Session Bean a stateful Session Bean a JPA entity and so on Seam components are defined by adding the @Name annotation to a class definition. The @Name annotation takes a single parameter to define the name of the Seam component. The following example shows how a stateless Session Bean is defined as a Seam component called calcAction. package com.davidsalter.seamcalculator; @Stateless @Name("calcAction") public class CalcAction implements Calc { ... } When a Seam application is deployed to JBoss, the log output at startup lists what Seam components are deployed, and what type they are. This can be useful for diagnostic purposes, to ensure that your components are deployed correctly. Output similar to the following will be shown in the JBoss console log when the CalcAction class is deployed: 21:24:24,097 INFO [Initialization] Installing components...21:24:24,121 INFO [Component] Component: calcAction, scope: STATELESS, type: STATELESS_SESSION_BEAN, class: com.davidsalter.seamcalculator.CalcAction, JNDI: SeamCalculator/CalcAction/local Object Injection and Outjection One of the benefits of using Seam is that it acts as the "glue" between the web technology and the server-side technology. By this we mean that the Seam Framework allows us to use enterprise beans (for example, Session Beans) directly within the Web tier without having to use Data Transfer Object (DTO) patterns and without worrying about exposing server-side functionality on the client. Additionally, if we are using Session Beans for our server-side functionality, we don't really have to develop an additional layer of JSF backing beans, which are essentially acting as another layer between our web page and our application logic. In order to fully understand the benefits of Seam, we need to first describe what we mean by Injection and Outjection. Injection is the process of the framework setting component values before an object is created. With injection, the framework is responsible for setting components (or injecting them) within other components. Typically, Injection can be used to allow component values to be passed from the web page into Seam components. Outjection works in the opposite direction to Injection. With Outjection, components are responsible for setting component values back into the framework. Typically, Outjection is used for setting component values back into the Seam Framework, and these values can then be referenced via JSF Expression Language (EL) within JSF pages. This means that Outjection is typically used to allow data values to be passed from Seam components into web pages. Seam allows components to be injected into different Seam components by using the @In annotation and allows us to outject them by using the @Out annotation. For example, if we have some JSF code that allows us to enter details on a web form, we may use an <h:inputText …/> tag such as this: <h:inputText value="#{calculator.value1}" required="true"/> The Seam component calculator could then be injected into a Seam component using the @In annotation as follows: @In private Calculator calculator; With Seam, all of the default values on annotations are the most likely ones to be used. In the preceding example therefore, Seam will look up a component called calculator and inject that into the calculator variable. If we wanted Seam to inject a variable with a different name to the variable that it is being injected into, we can adorn the @In annotation with the value parameter. @In (value="myCalculator") private Calculator calculator; In this example, Seam will look up a component called myCalculator and inject it into the variable calculator. Similarly, if we want to outject a variable from a Seam component into a JSF page, we would use the @Out annotation. @Out private Calculator calculator; The outjected calculator object could then be used in a JSF page in the following manner: <h:outputText value="#{calculator.answer}"/> Example application To see these concepts in action, and to gain an understanding of how Seam components are used instead of JSF backing beans, let us look at a simple calculator web application. This simple application allows us to enter two numbers on a web page. Clicking the Add button on the web page will cause the sum of the numbers to be displayed. This basic application will give us an understanding of the layout of a Seam application and how we can inject and outject components between the business layer and the view. The application functionality is shown in the following screenshot. The sample code for this application can be downloaded from the Packt web site, at http://www.packtpub.com/support. For this sample application, we have a single JSF page that is responsible for: Reading two numeric values from the user Invoking business logic to add the numbers together Displaying the results of adding the numbers together <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <html> <head> <title>Seam Calculator</title> </head> <body> <f:view> <h:form> <h:panelGrid columns="2"> Value 1: <h:inputText value="#{calculator. value1}" /> Value 2: <h:inputText value="#{calculator. value2}" /> Add them together gives: <h:outputText value=" #{calculator.answer} "/> </h:panelGrid> <h:commandButton value="Add" action= "#{calcAction.calculate}"/> </h:form> </f:view> </body> </html> We can see that there is nothing Seam-specific in this JSF page. However, we are binding two inputText areas, one outputText area, and a button action to Seam components by using standard JSF Expression Language. JSF EL Seam Binding calculator.value1 This is bound to the member variable value1 on the Seam component called calculator. This value will be injected into the Seam component. calculator.value2 This is bound to the member variable value2 on the Seam component called calculator. This value will be injected into the Seam component. calculator.answer This is bound to the member variable answer on the Seam component called calculator. This value will be outjected from the Seam component. calcAction.calculate This will invoke the method calculate() on the Seam component called calcAction. Our business logic for this sample application is performed in a simple POJO class called Calculator.java. package com.davidsalter.seamcalculator; import java.io.Serializable; import org.jboss.seam.annotations.Name;@Name("calculator") public class Calculator { private double value1; private double value2; private double answer; public double getValue1() { return value1; } public void setValue1(double value1) { this.value1 = value1; } public double getValue2() { return value2; } public void setValue2(double value2) { this.value2 = value2; } public double getAnswer() { return answer; } public void add() { this.answer = value1 + value2; } } This class is decorated with the @Name("calculator") annotation, which causes it to be registered to Seam with the name, "calculator". The @Name annotation causes this object to be registered as a Seam component that can subsequently be used within other Seam components via Injection or Outjection by using the @In and @Out annotations. Finally, we need to have a class that is acting as a backing bean for the JSF page that allows us to invoke our business logic. In this example, we are using a Stateless Session Bean. The Session Bean and its local interface are as follows. In the Java EE 5 specification, a Stateless Session Bean is used to represent a single application client's communication with an application server. A Stateless Session Bean, as its name suggests, contains no state information; so they are typically used as transaction façades. A Façade is a popular design pattern, which defines how simplified access to a system can be provided. For more information about the Façade pattern, check out the following link: http://java.sun.com/blueprints/corej2eepatterns/Patterns/SessionFacade.html Defining a Stateless Session Bean using Java EE 5 technologies requires an interface and an implementation class to be defined. The interface defines all of the methods that are available to clients of the Session Bean, whereas the implementation class contains a concrete implementation of the interface. In Java EE 5, a Session Bean interface is annotated with either the @Local or @Remote or both annotations. An @Local interface is used when a Session Bean is to be accessed locally within the same JVM as its client (for example, a web page running within an application server). An @Remote interface is used when a Session Bean's clients are remote to the application server that is running within a different JVM as the application server. There are many books that cover Stateless Session Beans and EJB 3 in depth, such as EJB 3 Developer's Guide by Michael Sikora, published by Packt Publishing. For more information on this book, check out the following link: http://www.packtpub.com/developer-guide-for-ejb3 In the following code, we are registering our CalcAction class with Seam under the name calcAction. We are also Injecting and Outjecting the calculator variable so that we can use it both to retrieve values from our JSF form and pass them back to the form. package com.davidsalter.seamcalculator; import javax.ejb.Stateless; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Name; @Stateless @Name("calcAction") public class CalcAction implements Calc { @In @Out private Calculator calculator; public String calculate() { calculator.add(); return ""; } } package com.davidsalter.seamcalculator; import javax.ejb.Local; @Local public interface Calc { public String calculate(); } That's all the code we need to write for our sample application. If we review this code, we can see several key points where Seam has made our application development easier: All of the code that we have developed has been written as POJOs, which will make unit testing a lot easier. We haven't extended or implemented any special Seam interfaces. We've not had to define any JSF backing beans explicitly in XML. We're using Java EE Session Beans to manage all of the business logic and web-tier/business-tier integration. We've not used any DTO objects to transfer data between the web and the business tiers. We're using a Seam component that contains both state and behavior. If you are familiar with JSF, you can probably see that adding Seam into a fairly standard JSF application has already made our development simpler. Finally, to enable Seam to correctly find our Seam components and deploy them correctly to the application server, we need to create an empty file called seam.properties and place it within the root of the classpath of the EJB JAR file. Because this file is empty, we will not discuss it further here. To deploy the application as a WAR file embedded inside an EAR file, we need to write some deployment descriptors.
Read more
  • 0
  • 0
  • 2126

article-image-troubleshooting-nagios-30
Packt
08 Oct 2009
8 min read
Save for later

Troubleshooting Nagios 3.0

Packt
08 Oct 2009
8 min read
Troubleshooting Web Interface There might be cases where accessing the Nagios URL shows an error instead of the welcome screen. If this happens, it can be due to various reasons, for example, because the web server has not started, or the Nagios related configuration setup is incorrect, or permissions on the Nagios directories are incorrect. The first thing that we should check is whether Apache is working properly. We can manually run the check_http plugin from Nagios. If the web server is up and running, we should see something similar to what is shown here:  # /opt/nagios/plugins/check_http -H 127.0.0.1HTTP OK HTTP/1.1 200 OK - 296 bytes in 0.006 seconds and if Apache is not running currently, the plugin will report an error similar to the following one: # /opt/nagios/plugins/check_http -H 127.0.0.1HTTP CRITICAL - Unable to open TCP socket If it was stopped, start it by running /etc/init.d/apache2 start. The next step is to check whether the http://127.0.0.1/nagios/ URL is working properly. We can also use the same plugin for this. The -u argument can specify the exact link to access, and -a allows you to specify the username and password to be authorized. It is passed in the form of <username>:<password>. # /opt/nagios/plugins/check_http -H 127.0.0.1 u /nagios/ -a nagiosadmin:<yourpassword>HTTP OK HTTP/1.1 200 OK - 979 bytes in 0.019 seconds We can also check the actual CGI scripts by passing a URL to one of the scripts: # /opt/nagios/plugins/check_http -H 127.0.0.1 u /nagios/cgi-bin/tac.cgi -a nagiosadmin:<yourpassword>HTTP OK HTTP/1.1 200 OK - 979 bytes in 0.019 seconds If any of these checks return any HTTP code other than 200, it means that this is the problem. If the code is 500, it means that Apache is not configured correctly. In such cases, the Apache error log contains useful information about any potential problems. On most systems, including Ubuntu Linux, the filename of the log is /var/log/apache2/error.log. An example entry in the error log could be: [error] [client 127.0.0.1] need AuthName: /nagios/cgi-bin/tac.cgi In this particular case, the problem is the missing AuthName directive for CGI scripts. Internal errors can usually be resolved by making sure that the Nagios-related Apache configuration is correct. If this does not help, it is worth checking other parts of the configuration, especially the ones related to virtual hosts and CGI configuration. Commenting out parts of the configuration can help in determining which parts of the configuration are causing problems. Another possibility is that either the check for /nagios/ or the check for the /nagios/cgi-bin/tac.cgi URL returned code 404. This code means that the page was not found. In this case, please make sure that Apache is configured according to the previous steps. If it is, then it's a good idea to enable more verbose debugging to a custom file. The following Apache 2 directives can be added either to /etc/apache2/conf.d/nagios or to any other file in Apache configuration: LogFormat "%h %l %u "%r" %>s %b %{Host}e %f" debuglogCustomLog /var/log/apache2/access-debug.log debuglog The first entry defines a custom logging format that also logs exact paths to files. The second one enables logging with this format to a dedicated file. An example entry in such a log would be: 127.0.0.1 - - "GET /nagios/ HTTP/1.1" 404 481 127.0.0.1 /var/www/nagios This log entry tells us that http://127.0.0.1/nagios/ was incorrectly expanded to the /var/www/nagios directory. In this case, the Alias directive describing the /nagios/ prefix is missing. Making sure that actual configuration matches the one provided in the previous section will also resolve this issue. Another error that you can get is 403, which indicates that Apache was unable to access either CGI scripts in /opt/nagios/sbin, or Nagios static pages in /opt/nagios/share. In this case, you need to make sure that these directories are readable by the user Apache is running as. The error might also be related to the directories above /opt/nagios or /opt. One of these might also be inaccessible to the user Apache is running as, which will also cause the same error to occur. If you run into any other problems, it is best to start with making sure that Nagios related configuration matches the examples from the previous section. It is also a good idea to reduce the number of enabled features and virtual hosts in your Apache configuration. Troubleshooting Passive Checks It' s not always possible to set up passive checks correctly the first time. In such cases, it is a good thing to try to debug the issue one step at a time in order to find any potential problems. Sometimes the problem could be a configuration issue, while in other cases, it could be an issue such as the mistyping of the host or service name. One thing worth checking is whether the Web UI shows changes after you have sent the passive result check. If it doesn't, then at some point, things are not working correctly. The first thing you should start with is enabling the logging of external commands and passive checks. To do this, make sure that the following values are enabled in the main Nagios configuration file: log_external_commands=1log_passive_checks=1 In order for the changes to take effect, a restart of the Nagios process is needed. After this has been done, Nagios will log all commands passed via the command pipe and log all of the passive check results it receives. The first issue, a common problem, is that an application or script cannot write data to the Nagios command pipe. In order to test this, simply change to the user your scripts are running as, and try the following command: user@ubuntuserver:~$ echo "TEST" >/var/nagios/rw/nagios.cmd If the command above runs fine, and no errors are reported, then your permissions are set up correctly. If an error shows up, you should add the user to the nagioscmd group. The next thing to do is to manually send a passive check result to the Nagios command pipe and check whether the Nagios log file was received and parsed correctly. To test this, run the following command: echo "['date +%s'] PROCESS_HOST_CHECK_RESULT;host1;2;test" >/var/nagios/rw/nagios.cmd The name, host1, needs to be replaced with an actual host name from your configuration. A few seconds after running this command, the Nagios log file should reflect the command that we have just sent. You should see the following lines in your log: EXTERNAL COMMAND: PROCESS_HOST_CHECK_RESULT;host1;2;test[1220257561] PASSIVE HOST CHECK: host1;2;test If both of these lines are in your log file, then we can conclude that Nagios has received and parsed the command correctly. If only the first line is present, then it means that either the global option to receive passive host check results is disabled, or it is disabled for this particular object. The first thing you should do is to make sure that your main Nagios configuration file contains the following line: accept_passive_host_checks=1 Next, you should check your configuration to see whether the host definition has passive checks enabled as well. If not, simply add the following directive to the object definition: passive_checks_enabled 1 If you have misspelled the name of the host object, then the following will be logged: Warning: Passive check result was received for host host01',but the host could not be found! In this case, make sure that your host name is correct. Similar checks can also be done for services. You can run the following command to check if a passive service check is being handled correctly by Nagios: echo "['date +%s'] PROCESS_SERVICE_CHECK_RESULT;host1;APT;0;test" >/var/nagios/rw/nagios.cmd Again, host1 should be replaced by the actual host name, and APT needs to be an existing service for that host. After a few seconds, the following entries in Nagios log file would indicate the result has been successfully parsed: EXTERNAL COMMAND: PROCESS_SERVICE_CHECK_RESULT;host1;APT;0;testPASSIVE SERVICE CHECK: host1;APT;0;test If the second line is not in the log file, either the option to accept service passive checks is disabled on a global basis, or this particular service has the option to accept passive check results disabled. You should start by making sure that your main Nagios configuration file contains the following line: accept_passive_service_checks=1 You should also make sure that the service definition has passive checks enabled as well, and if not, add the following directive to the object definition: passive_checks_enabled 1 If you have misspelled the name of the host or service, then the following will be logged: Warning: Passive check result was received for service APT' on host host1', but the service could not be found!
Read more
  • 0
  • 0
  • 2159

article-image-notifications-and-events-nagios-30-part2
Packt
08 Oct 2009
15 min read
Save for later

Notifications and Events in Nagios 3.0- part2

Packt
08 Oct 2009
15 min read
External Commands Nagios offers a very powerful mechanism for receiving events and commands from external applications—the external commands pipe. This is a pipe file created on a file system that Nagios uses to receive incoming messages. The name of the file is rw/nagios.cmd and it is located in the directory passed as the localstatedir option during compilation. Following the compilation and installation instructions and the given guidelines, the file name will be /var/nagios/rw/ nagios.cmd. The communication does not use any authentication or authorization—the only requirement is to have write access to the pipe file. An external command file is usually writable by the owner and the group; the usual group used is nagioscmd. If you want a user to be able to send commands to the Nagios daemon, simply add that user to this group. A small limitation of the command pipe is that there is no way to get any results back and so it is not possible to send any query commands to Nagios. Therefore, by just using the command pipe, you have no verification that the command you have just passed to Nagios has actually been processed, or will be processed soon. It is, however, possible to read the Nagios log file and check if it indicates that the command has been parsed correctly, if necessary. An external command pipe is used by the web interface to control how Nagios works. The web interface does not use any other means to send commands or apply changes to Nagios. This gives a good understanding of what can be done with the external command pipe interface. From the Nagios daemon perspective, there is no clear distinction as to who can perform what operations. Therefore, if you plan to use the external command pipe to allow users to submit commands remotely, you need to make sure that the authorization is in place as well so that it is not possible for unauthorized users to send potentially dangerous commands to Nagios. The syntax for formatting commands is easy. Each command must be placed on a single line and end with a newline character. The syntax is as follows: [TIMESTAMP] COMMAND_NAME;argument1;argument2;...;argumentN TIMESTAMP is written as UNIX time—that is the number of seconds since 1970-01-01 00:00:00. This can be created by using the date +%s system command. Most programming languages also offer the means to get the current UNIX time. Commands are written in upper case. This can be one of the commands that Nagios should execute, and the arguments depend on the actual command. For example, to add a comment to a host stating that it has passed a security audit, one can use the following shell command: echo "['date +%s'] ADD_HOST_COMMENT;somehost;1;Security Audit;This host has passed security audit on 'date +%Y-%m-%d'">/var/nagios/rw/nagios.cmd This will send an ADD_HOST_COMMENT command (visit http://www.nagios.org/developerinfo/externalcommands/commandinfo.php? command_id=1) to Nagios over the external command pipe. Nagios will then add a comment to the host, somehost, stating that the comment originated from Security Audit. The first argument specifies the host name to add the comment to; the second tells Nagios if this comment should be persistent. The next argument describes the author of the comment, and the last argument specifies the actual comment text. Similarly, adding a comment to a service requires the use of the ADD_SVC_COMMENT command (visit http://www.nagios.org/developerinfo/externalcommands/ commandinfo.php? command_id=1) . The command's syntax is very similar to the ADD_HOST_COMMENT command except that the command requires the specification of the host name and service name. For example, to add a comment to a service stating that it has been restarted, you should use the following echo "['date +%s'] ADD_SVC_COMMENT;router;OpenVPN;1;nagiosadmin;Restarting the OpenVPN service" >/var/nagios/rw/nagios.cmd The first argument specifies the host name to add the comment to; the second is the description of the service to which Nagios should add the comment. The next argument tells Nagios if this comment should be persistent. The fourth argument describes the author of the comment, and the last argument specifies actual comment text. You can also delete a single comment or all comments using the DEL_HOST_ COMMENT (visit http://www.nagios.org/developerinfo/externalcommands/ commandinfo.php? command_id=3), DEL_ALL_HOST_COMMENTS (visit http://www. nagios.org/developerinfo/externalcommands/commandinfo.php? command_ id=13), and DEL_SVC_COMMENT (visit http://www.nagios.org/developerinfo/externalcommands/commandinfo.php? command_id=4) or DEL_ALL_SVC_COMMENTS commands (visit http://www.nagios.org/developerinfo/externalcommands/ commandinfo.php? command_id=14). Other commands worth mentioning are related to scheduling checks on demand. Very often, it is necessary to request that a check be carried out as soon as possible; for example, when testing a solution. This time, let's create a script that schedules a check of a host, all services on that host, and a service on a different host, as follows: #!/bin/shNOW='date +%s'echo "[$NOW] SCHEDULE_HOST_CHECK;somehost;$NOW" >/var/nagios/rw/nagios.cmdecho "[$NOW] SCHEDULE_HOST_SVC_CHECKS;somehost;$NOW" >/var/nagios/rw/nagios.cmdecho "[$NOW] SCHEDULE_SVC_CHECK;otherhost;Service Name;$NOW" >/var/nagios/rw/nagios.cmdexit 0 The commands SCHEDULE_HOST_CHECK (visit http://www.nagios.org/ developerinfo/externalcommands/commandinfo.php? command_id=127) and SCHEDULE_HOST_SVC_CHECKS (http://www.nagios.org/developerinfo/externalcommands/commandinfo.php?command_id=30) accept a host name and the time at which the check should be scheduled. The SCHEDULE_SVC_CHECK command (visit http://www.nagios.org/developerinfo/externalcommands/ commandinfo.php? command_id=29) requires the specification of a service description as well as the name of the host to schedule the check on. Normal scheduled checks, such as the ones scheduled above, might not actually take place at the time that you scheduled them. Nagios also needs to take allowed time periods into account as well as checking whether checks were disabled for a particular object or globally for the entire Nagios. There are cases when you'll need to force Nagios to do a check—in such cases, you should use SCHEDULE_FORCED_HOST_CHECK (visit http://www.nagios. org/developerinfo/externalcommands/commandinfo.php? command_id=128), SCHEDULE_FORCED_HOST_SVC_CHECKS (visit http://www.nagios.org/developerinfo/externalcommands/commandinfo.php? command_id=130) and SCHEDULE_FORCED_SVC_CHECK (visit http://www.nagios.org/developerinfo/ externalcommands/commandinfo.php? command_id=129) commands. They work in exactly the same way as described above, but make Nagios skip the checking of time periods, and ensure that the checks are disabled for this particular object. This way, a check will always be performed, regardless of other Nagios parameters Other commands worth using are related to custom variables, introduced in Nagios 3. When you define a custom variable for a host, service, or contact, you can change its value on the fly with the external command pipe. As these variables can then be directly used by check or notification commands and event handlers, it is possible to make other applications or event handlers change these attributes directly without modifications to the configuration files. A good example would be that the IT staff registers its presence via an application without any GUI. This application periodically sends information about the latest known IP address, and that information is then passed to Nagios assuming that the person is in the office. This would later be sent to a notification command to use that specific IP address while sending a message to the user. Assuming that the user name is jdoe and the custom variable name is DESKTOPIP, the message that would be sent to the Nagios external command pipe would be as follows: [1206096000] CHANGE_CUSTOM_CONTACT_VAR;jdoe;DESKTOPIP;12.34.56.78 This would cause a later use of $_CONTACTDESKTOPIP$ to return a value of 12.34.56.78. Nagios offers the CHANGE_CUSTOM_CONTACT_VAR (visit http://www.nagios.org/developerinfo/externalcommands/commandinfo.php? command_id=141), CHANGE_CUSTOM_HOST_VAR (visit http://www.nagios.org/developerinfo/ externalcommands/commandinfo.php?command_id=139), and CHANGE_CUSTOM_ SVC_VAR (visit http://www.nagios.org/developerinfo/externalcommands/commandinfo.php?command_id=140) commands for modifying custom variables in contacts, hosts and, services accordingly. The commands explained above are just a very small subset of the full capabilities of the Nagios external command pipe. For a complete list of commands, visit http:// www.nagios.org/developerinfo/externalcommands/commandlist.php, where the External Command List can be seen. External commands are usually sent from event handlers or from the Nagios web interface. You will find external commands most useful when writing event handlers for your system, or when writing an external application that interacts with Nagios. Event Handlers Event handlers are commands that are triggered whenever the state of a host or  service changes. They offer functionality similar to notifications. The main difference is that the event handlers are called for each type of change and even for each soft state change. This provides the ability to react to a problem before Nagios notifies it as a hard state and sends out notifications about it. Another difference is what the event handlers should do. Instead of notifying users that there is a problem, event handlers are meant to carry out actions automatically. For example, if a service defined with max_check_attempts set to 4, the retry_ interval set to 1, and the check_interval is set to 5, then the following example illustrates when event handlers would be triggered, and with what values, for $SERVICESTATE$, $SERVICESTATETYPE$, and $SERVICEATTEMP$ macro definitions: Event handlers are triggered for each state change—for example, in minutes, 10, 23, 28, and 29. When writing an event handler, it is necessary to check whether an event handler should perform an action at that particular time or not. See the following example for more details. A typical example might be that your web server process tends to crash once a month. Because this is rare enough, it is very difficult to debug and resolve it. Therefore, the best way to proceed is to restart the server automatically until a solution to the problem is found. If your configuration has max_check_attempts set to 4, as in the example above, then a good place to try to restart the web server is after the third soft failure check—in the previous example, this would be minute 12. Assuming that the restart has been successful, the diagram shown above would look like this: Please note that no hard critical state has occurred since the event handler resolved the problem. If a restart cannot resolve the issue, Nagios will only try it once, as the attempt is done only in the third soft check. Event handlers are defined as commands, similar to check commands. The main difference is that the event handlers only use macro definitions to pass information to the actual event handling script. This implies that the $ARGn$ macro definitions cannot be used and arguments cannot be passed in the host or service definition by using the ! separator. In the previous example, we would define the following command: define command{command_name restart-apache2command_line $USER1$/events/restart_apache2$SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$} The command would need to be added to the service. For both hosts and services, this requires adding an event_handler directive that specifies the command to be run for each event that is fired. In addition, it is good to set event_handler_enabled set to 1 to make sure that event handlers are enabled for this object. The following is an example of a service definition: define service{host_name localhostservice_description Webserveruse apacheevent_handler restart-apache2event_handler_enabled 1} Finally, a short version of the script is as follows: #!/bin/sh# use variables for argumentsSERVICESTATE=$1SERVICESTATETYPE=$2SERVICEATTEMPT=$3# we don't want to restart if current status is OKif [ "$SERVICESTATE" != "OK" ] ; then# proceed only if we're in soft transition stateif [ "$SERVICESTATETYPE" == "SOFT" ] ; then# proceed only if this is 3rd attempt, restartif [ "$SERVICESTATEATTEMPT" == "3" ] ; then# restarts Apache as system administratorsudo /etc/init.d/apache2 restartfififiexit 0 As we're using sudo here, obviously the script needs an entry in the sudoers file to allow the nagios user to run the command without a password prompt. An example entry for the sudoers file would be as follows: nagios ALL=NOPASSWD: /etc/init.d/apache2 This will tell sudo that the command /etc/init.d/apache2 can be run by the user nagios and that asking for passwords before running the command will not be done. According to our script, the restart is only done after the third check fails. Assuming that the restart went correctly, the next Nagios check will notify that Apache is running again. As this is considered a soft state, Nagios has not yet sent out any notifications about the problem If the service would not restart correctly, the next check will cause Nagios to set this failure as a hard state. At this point, notifications will be sent out to the object owners. You can also try performing a restart in the second check. If that did not help, then during the third attempt, the script can forcefully terminate all Apache2 processes using the killall or pkill command. After this has been done, it can try to start the service again. For example: # proceed only ifthis is 3rd attempt, restartif [ "$SERVICESTATEATTEMPT" == "2" ] ; then# restart Apache as system administratorsudo /etc/init.d/apache2 restartfi# proceed only ifthis is 3rd attempt, restartif [ "$SERVICESTATEATTEMPT" == "3" ] ; then# try to terminate apache2 process as system administratorsudo pkill apache2# starts Apache as system administratorsudo /etc/init.d/apache2 startfi Another common scenario is to restart one service if another one has just recovered—for example, you might want to restart email servers that use a database for authentication if the database has just recovered from a failure state. The reason for doing this is that some applications may not handle disconnected database handles correctly—this can lead to the service working correctly from the Nagios perspective, but not allowing some of the users in due to internal problems. If you have set this up for hosts or services, it is recommended that you keep flapping enabled for these services. It often happens that due to incorrectly planned scripts and the relations between them, some services might end up being stopped and started again. In such cases, Nagios will detect these problems and stop running event handlers for these services, which will cause fewer malfunctions to occur. It is also recommended that you keep notifications set up so that people also get information on when flapping starts and stops. Modifying Notifications An interesting new feature in Nagios 3 is the ability to change various parameters related to notifications. These parameters are modified via an external command pipe, similar to a few of the commands shown in the previous section. A good example would be when Nagios contact persons have their workstations connected to the local network only when they are actually at work (which is usually the case if they are using notebooks), and turn their computers off when they leave work. In such a case, a ping check for a person's computer could trigger an event handler to toggle that person's attributes. Let's assume that our user jdoe has two actual contacts—jdoe-email and jdoejabber, each for different types of notifications. We can set up a host corresponding to the jdoe workstation. We will also set it up to be monitored every five minutes and create an event handler. The handler will change the jdoe-jabber's host and service notification time period to none on a hard host down state. On a host up state change, the time period for jdoe-jabber will be set to 24x7. This way, the user will only get Jabber notifications if he or she is at work. Nagios offers commands to change the time periods during which a user wants to receive notifications. The commands for this purpose are: CHANGE_CONTACT_HOST_ NOTIFICATION_TIMEPERIOD ( http://www.nagios.org/developerinfo/ externalcommands/commandinfo.php? command_id=153 ) and CHANGE_CONTACT_ SVC_NOTIFICATION_TIMEPERIOD ( http://www.nagios.org/developerinfo/externalcommands/commandinfo.php?command_id=152 ). Both commands take the contact and the time period name as their arguments. An event handler script that modifies the user's contact time period based on state is as follows #!/bin/shNOW='date +%s'CONTACTNAME=$1-jabberif [ "$2,$3" = "DOWN,HARD" ] ; thenTP=noneelseTP=24x7fiecho "[$NOW] CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD;$CONTACT;$TP" >/var/nagios/rw/nagios.cmdecho "[$NOW] CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD;$CONTACT;$TP" >/var/nagios/rw/nagios.cmdexit 0 The command should pass $CONTACTNAME$, $SERVICESTATE$, and $SERVICESTATETYPE$ as parameters to the script. In case you need a notification about a problem sent again, you should use the SEND_CUSTOM_HOST_NOTIFICATION or SEND_CUSTOM_SVC_NOTIFICATION command. These commands take host or host and service names, additional options, author name, and comments that should be put in the notification. Options allow specifying if the notification should also include all escalation levels (a value of 1), if Nagios should skip time periods for specific users (a value of 2) as well as if Nagios should increment notifications counters (a value of 4). Options are stored bitwise so a value of 7 (1+2+4) would enable all of these options. The notification would be sent to all people including escalations; it will be forced, and the escalation counters will be increased. Option value 3 means it should be broadcast to all escalations as well, and the time periods should be skipped. To send a custom notification about the main router to all users including escalations, you should send the following command to Nagios [1206096000] SEND_CUSTOM_HOST_NOTIFICATION;router1;3;jdoe;RESPOND ASAP
Read more
  • 0
  • 0
  • 4284
article-image-jquery-embedded-dojo-accordion-panes
Packt
08 Oct 2009
4 min read
Save for later

jQuery Embedded in Dojo Accordion Panes

Packt
08 Oct 2009
4 min read
Basic DOJO 123 accordion In my earlier article I had used the version of the Toolkit which had the accordion in the Widgets. In the latest version which I am using, the accordion is found in digit/layout. The code is similar to that in the earlier article. Basically you create a accordion container and then place the accordion panes inside the container. In referencing the Dojo library I am using part of the references from the Dojo Toolkit 123 installed on my local IIS and part of the reference from the AOL site (uses the 1.0.0 script). Listing 1: AccordionOrig.htm: A basic accordion with three panes [DOJO 123] <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Accordion Pane with jQueries</title> <style type="text/css"> @import "http://localhost/Dojo123/dojo123/dijit/themes/tundra/tundra.css"; @import "http://localhost/Dojo123/dojo123/dojo/resources/dojo.css" </style> <script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js" djConfig="parseOnLoad: true"></script> <script type="text/javascript"> dojo.require("dojo.parser"); dojo.require("dijit.layout.AccordionContainer"); </script> </head> <body class="tundra"> <div dojoType="dijit.layout.AccordionContainer" duration="200" style="margin-right: 30px; width: 400px; height: 400px; overflow: scroll"> <!--Pane 1 --> <div dojoType="dijit.layout.AccordionPane" selected="true" title="Page 1" style="color:red;overflow: scroll; background-color:#FFFF80;"> <!--Pane 1 content--> <p >Test 1</a></p > </div> <!--Pane 2 --> <div dojoType="dijit.layout.AccordionPane" title="Page 2" style="overflow: scroll;background-color:#FFFF80;"> <!--Pane 2 content--> <p >Test 2</p > </div> <!-- Pane 3--> <div dojoType="dijit.layout.AccordionPane" title="Page 3" style="color:magenta;overflow: scroll;background-color:#FFFF80;"> <!--Pane 3 content--> <p >Test 3</a></p > </div> </div> </body> </html> This page when browsed to, will display the accordion as shown in Figure 1. This was cross-browser compatible in the following browsers: IE 6.0, Opera 9.1, Firefox 3.0.5, and Safari 3.2.1. The page did not render correctly (all panes completely open) in Google Chrome 1.0.154.43. Figure 1 jQuery API Components used in the article jQuery 1.3 downloaded from this site is used as a source for the script. From the API reference only two simple components were chosen to be embedded in the panes - the Selector and the Effects. The slideUp() effect where in, when you click on the code sensitive area the region of the area on the web page slides up. H1 Selector styled using jQuery Using jQuery you can selectively apply style to tags, ids, etc. In the example shown in the code that follows the H1 tag is styled using jQuery. Listing 2: H1SelectorJQry.htm: Tag styling with jQuery <html> <head></head> <body> <script language="JavaScript" src="http://localhost/JayQuery/jquery-1.3.min.js"> </script> <h1>Jquery inside a DOJO Accordion Pane</h1> <script type="text/JavaScript"> $(document).ready(function(){ $("h1").css("color", "magenta");}); </script> </body> <html> In the above, the jQuery code (inside the script tags) renders the h1 tag in the color shown as in Figure 2. Figure 2 jQuery Effect: slideUp() The htm page with the listing 3 when browsed to, displays a pale green 300 x 300 square corresponding to the styling of the p tag as shown in Figure 4. When clicked anywhere inside this square, the square slides up and disappears. This is the slideUp() effect. Listing 3: p_slideUp.htm: Jquery Effect <html> <head></head> <body> <script language="JavaScript" src="http://localhost/JayQuery/jquery-1.3.min.js"> </script> <div><p style="width:300; height:300; background-color:palegreen; color:darkgreen;">Test</p></div> <script type="text/JavaScript"> $("p").click(function () { $(this).slideUp(); }); </script> </body> <html> This page gets displayed as shown in Figure 3. When you click anywhere in the pale green area the "P" region slides up. Figure 3
Read more
  • 0
  • 0
  • 2636

Packt
08 Oct 2009
8 min read
Save for later

jQuery UI—The Dialog: Part 2

Packt
08 Oct 2009
8 min read
Using dialog animations The dialog provides us with built-in effect abilities and also allows us to specify effects to use when the dialog is opened or closed. Using these effects is extremely easy and gives a great visual flair. Let's look at how these effects can be enabled. Create the following new page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.dialog.css"> <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.resizable.css"> <link rel="stylesheet" type="text/css" href="styles/dialogTheme.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Dialog Example 6</title> </head> <body> <div id="myDialog" class="flora" title="This is the title">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpat ligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti. Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.dialog.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.resizable.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.draggable.js"></script> <script type="text/javascript"> //define function to be executed on document ready $(function(){ //define config object var dialogOpts = { hide: true }; //create the dialog $("#myDialog").dialog(dialogOpts); }); </script> </body></html> Save this as dialog6.html. In this example, our configuration object contains just one property—the hide property. The hide property accepts the boolean true as its value. This enables the built-in hide effect, which gradually reduces the dialog's size and opacity until it gracefully disappears. We can also enable the show effect, which is the opposite of the hide animation. However, at this stage in the component's development, this causes a slight issue with its display. The following screenshot shows the hide effect in progress: Controlling a dialog programmatically The dialog requires few methods in order to function. As implementers, we can easily open, close, or destroy the dialog at will. The full list of methods we can call on a dialog instance are as follows: Method Used to close Closes or hides the dialog destroy Permanently disables the dialog isOpen Determines whether a dialog is open or not moveToTop Moves the specified dialog to the top of the stack open Opens the dialog Let's look at opening and closing the widget, which can be achieved with the simple use of the open and close methods. Create the following new page in your text editor: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.dialog.css"> <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.resizable.css"> <link rel="stylesheet" type="text/css" href="styles/dialogTheme.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Dialog Example 7</title> </head> <body> <div id="myDialog" class="flora" title="This is the title"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpat ligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti. Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div> <button id="openDialog">Open the Dialog!</button> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.dialog.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.resizable.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.draggable.js"></script> <script type="text/javascript"> //define function to be executed on document ready $(function(){ //define doOk function var doOk = function() { //close the dialog $("#myDialog").dialog("close"); } //define config object var dialogOpts = { modal: true, overlay: { background: "url(img/modal.png) repeat" }, buttons: { "Ok!": doOk }, height: "400px", autoOpen: false }; //create the dialog $("#myDialog").dialog(dialogOpts); //define click handler for the button $("#openDialog").click(function() { //open the dialog $("#myDialog").dialog("open"); }); }); </script> </body></html> The open and close methods require no additional arguments and do exactly as they say, pure and simple. Save the file as dialog7.html. The destroy method for a dialog works in a slightly different way than it does for the other widgets we've seen so far. Instead of returning the underlying HTML to its original state, the dialog's destroy method completely disables the widget, hiding its content in the process. Change dialog7.html to make use of the destroy method: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.dialog.css"> <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.resizable.css"> <link rel="stylesheet" type="text/css" href="styles/dialogTheme.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Dialog Example 8</title> </head> <body> <div id="myDialog" class="flora" title="This is the title"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpat ligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti. Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div> <button id="openDialog">Open the Dialog!</button> <button id="destroy">Destroy the dialog!</button> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.dialog.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.resizable.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.draggable.js"></script> <script type="text/javascript"> //define function to be executed on document ready $(function(){ //define doOk function var doOk = function() { //close the dialog $("#myDialog").dialog("close"); } //define config object var dialogOpts = { modal: true, overlay: { background:"url(img/modal.png) repeat" }, buttons: { "Ok!": doOk }, height: "400px", autoOpen: false }; //create the dialog $("#myDialog").dialog(dialogOpts); //define click handler for the button $("#openDialog").click(function() { //open the dialog $("#myDialog").dialog("open"); }); //define click handler for destroy $("#destroy").click(function() { //destroy dialog $("#myDialog").dialog("destroy"); }); }); </script> </body></html> Save the changes as dialog8.html and try out the new file. You'll find that you can open and close the dialog as many times as you want until the Destroy the dialog! button is clicked. After this, the dialog will no longer appear (although it will still exist in the DOM). To fully remove the dialog mark-up from the page, we can simply chain the remove jQuery method onto the end of the destroy method call.
Read more
  • 0
  • 0
  • 1703

article-image-development-ajax-web-widget
Packt
08 Oct 2009
10 min read
Save for later

Development of Ajax Web Widget

Packt
08 Oct 2009
10 min read
We’ve seen this kind of thing done by the popular bookmark sharing website, digg.com. We don’t need to visit digg.com to digg the URL. We can do it using a small object called Widget, provided by digg.com. This is just one simple example of providing remote functionality; you can find lots of widgets providing different functionality across various websites. What is a web widget? A web widget is a small piece of code provided by a third party website, which can be installed and executed in any kind of web page which is created using HTML (or XHTML). The common technologies used in web widgets are JavaScript, Ajax and Adobe flash but in some places other technologies such as HTML combined with CSS, and Java Applets are also used. A web widget can be used for: Serving useful information from a website. Providing some functionality (like: voting, polling). Endorsing the products and services of a website. Web widgets are also known as badges, modules, and snippets. And, these are commonly used by bloggers, social network users and advertisers. Popular Web Widgets You can find many examples of the web widgets on the World Wide Web. These include: Google Adsense – It is probably the most popular web widget you can see on the World Wide Web. All you’ve to do, is get a few lines of code from Google and place it in your website. Different kinds of contextual advertisements get displayed on your website according to the content displayed on your website. Digg this widget – If You want to display news or articles then you’re most probably going to do so with this widget. Provided by the social book marking website digg.com, it is one of the popular bookmark sharing websites. Your website will lots of visitors if your article gets more and more digs, and gets featured on the first page. Del.icio.us widget – You might have seen the widget previously, or text showing “Save to del.icio.us”, “Add to del.icio.us” and “saved by XXX users”. This is another popular social bookmarking website. Snap preview –Provided by snap.com, this widget shows the thumbnail preview of a web page. Survey widget from Polldaddy.com – If you need to run some kind of poll then you can use this widget to create and manage the poll on your website. Google Maps – A rather well known widget, which adds different map functionality in Google maps. you must get an api key from Google to use this widget. Benefits of Providing Web Widgets I came to know about dzone.com, a social bookmarking website for web and software developers, from a widget I found in a blog. Let’s look at the benefits of web widgets: A widget can be an excellent publicity tool. Most of the people who come to know about digg.com, del.icio.us or reddit.com do so from their web widgets in various news portal and blogs. Providing web services- This is useful since the user doesn’t have to visit that particular website to get its services. For example, a visitor to a website which has a Polldaddy web widgets can participate on a survey without visiting to polldaddy.com. Web widgets can be one of the ways of bringing income for your website, by utilizing advertising widgets such as Google adsense (discussed above). Widgets can generate more traffic to your website. For example, you can make a widget that evaluates the price of a product on a website. Widgets across multiple websites means visitors from multiple sources, hence more traffic to you website. How do Web Widgets work As can be seen in the above figure, the web widget is used by a widget client, which is a web page. The web pages just use a chunk of code provided by the functionality providing website. Furthermore, all the services and functionality are provided by the code residing on the remote server which the widget client doesn’t have to care about. In a web widget system, there is optional system called Widget Management System which can manage the output of the widget. Widget Management System A Widget Management System is used for controlling the various operations of the widget, including things like height or width or color. Most widget providing websites allows you to customize the way widget looks in blogs or website. For example, you can customize the size and color of Google adsense by logging into the Google adsense account system. Some widget Management Systems also allow you to manage the content of the widget as well. In the survey widget from vizu.com, you can manage parameters like the topic of poll and number of answers of the poll. Concept of Technologies Used To make the most out of Ajax web widgets, let’s get familiar with some technologies. HTML and XHTML Hypertext Markup language(HTML) is one of the most known markup language for constructing web pages. As the name implies, we use it to markup the text document so that web browsers know how to display them. XHTML on the other hand, is the way to standardize the HTML by making HTML a dialect of XML. XHTML comes in different flavors like transitional, strict or frameset, with each flavor offering either different capabilities or different degrees of conformance to the XML standard. Difference between HTML and XHTML The single biggest difference between HTML and XHTML is that XHML must be well-formed according to XML conventions. Because an XHTML document is essentially XML in nature, simply following the traditional HTML practices is not enough. An XHML document must be well formed. For example, let’s take the examples of “img” and “input” elements of HTML. <img src="logo.gif" alt="My Site" border="0" > <input type="text" name="only_html" id="user_name" value="Not XHTML" > Both of the above statements are perfect HTML statements but they are not well graded constructions in XHTML as they are not well formed according to compliance of XML (those tags are not enclosed properly). To figure out the difference, first look at the above tags in the XHML valid syntax. <img src="logo.gif" alt="My Site" border="0" /><input type="text" name="only_html" id="user_name" value="Not XHTML" /> Did you find the difference? The latter tags are well formed and the previous one is not. If you look closely, you can find that the HTML tags in the second example are closed like XML. The point is you should have well formed document in order to allow JavaScript to access the DOM. You can also add comments in the HTML document. Any information beginning with the character string <!-- and ending with the string --> will be ignored: <!-- This is a comment within HTML--> You can add the comment in the same fashion in an XML document as well. Concept of IFRAME IFrame (Inline Frame ) is a useful HTML element for creating web widgets. Using IFrame, we can embed the HTML document from the remote server into our document. This feature is most commonly used in the web widgets. We can define the width and height of IFrame using the height and width property of the IFrame element. IFrame can be defined in any part of the web pages. IFrame behaves like an inline object and the user can scroll through the Iframe to view the content which is out of view. We can also remove the scroll bar from the IFrame by setting scrolling property to no. The embedded document can be reloaded asynchronously using IFrame and can be an alternative option to an XMLHttpRequest object. For this reason, IFrames are widely used by Ajax applications. You can use the IFrame in the HTML document in the following way: <html> <body> <iframe src="http://wwww.example.com" width="200"> If your browser doesn’t support IFrame, this text will be displayed in the browser </iframe> </body></html> CSS(Cascading Style Sheet) A Cascading Style Sheet is a style sheet language which is used to define the presentation of document written in HTML or XHTML pages. CSS is mainly used for defining the layout, colors and fonts of the elements of a web page along with other perspectives of the document. While the mark up language can be used to define the content of the web page, the primary goal of providing a CSS is to separate the document’s content from the document’s presentation. The Internet Media type “text/css” is reserved for CSS. Using Cascading Style Sheet CSS can be used in different ways in a web page. It can be written with the <style></style> tag of the web-page. It can be defined in the style attribute of the element. Also, CSS can be defined in a different page with extension .css that links with the web page to define the presentation. What is the benefit of using CSS then? You can define the values for a set of attributes for all HTML elements (of a similar type), then change the presentation with one change in the CSS property <style type="text/css">all the css declaration goes here</style> But what about defining the CSS property for different web pages? The above method can be cumbersome and you would need to replicate the same code to different web pages. To overcome such a situation, you can define all the property in a single page let’s say call it style.css and link that CSS to the web pages. <link href="style.css" type="text/css" rel="stylesheet" /> Furthermore, you can define the styles within the elements using the style property of the HTML elements, which is commonly known as inline styles. <p style="text-align:justify">This is content inside paragraph</p> As you’ve seen, we’ve quickly defined the text-align attribute to justify Defining Style Sheet rules A style sheet allows you to change the different attributes of the HTML elements by defining a styling rule for them. A rule has two components: selectors, which defines which HTML elements to apply the styling rule and declaration, which contains the styling rule for the selectors. p { background-color:#999999 } In the above css rule, p is the selector and background-color:#999999, is the declaration of the rule. The above style defines the rule for the paragraph element <p></p>. .box { width:300px } In the above rule, selectors is defined as a class and it can be used in any element with the class property of the element. <p class="box">..content..</p> <div class="box">content</div> Class can be used with any HTML element. #container { width:1000px } “#” is known as an id selector in CSS. The above rule applies to an element which has the id “container” such as below: <div id="container">..content..</div> We can also define a set of rules for multiple elements using comma (,) among the selectors: h1, h2, h3 {font-size:12px; color:#FF0000 } There are many more styles of defining selectors and CSS properties.
Read more
  • 0
  • 0
  • 4320
article-image-debugging-scheduler-oracle-11g-databases
Packt
08 Oct 2009
5 min read
Save for later

Debugging the Scheduler in Oracle 11g Databases

Packt
08 Oct 2009
5 min read
Unix—all releases Something that has not been made very clear in the Oracle Scheduler documentation is that redirection cannot be used in jobs (<, >, >>, |, &&, ||). Therefore, many developers have tried to use it. So, let's keep in mind that we cannot use redirection, not in 11g as well as older releases of the database. The scripts must be executable, so don't forget to set the execution bits. This might seem like knocking down an open door, but it's easily forgotten. The user (who is the process owner of the external job and is nobody:nobody by default) should be able to execute the $ORACLE_HOME/bin/extjob file. In Unix, this means that the user should have execution permissions on all the parent directories of this file. This is not something specific to Oracle; it's just the way a Unix file system works. Really! Check it out. Since 10gR1, Oracle does not give execution privileges to others. A simple test for this is to try starting SQL*Plus as a user who is neither the Oracle installation user, nor a member of the DBA group—but a regular user. If you get all kinds of errors, then it implies that the permissions are not correct, assuming that the environment variables (ORACLE_HOME and PATH) are set up correctly. The $ORACLE_HOME/install/changePerm.sh script can fix the permissions within ORACLE_HOME (for 10g). In Oracle 11g, this again changed and is no longer needed. The Scheduler interprets the return code of external jobs and records it in the *_scheduler_job_run_details view. This interpretation can be very misleading, especially when using your own exit codes. For example, when you code your script to check the number of arguments, and code an exit 1 when you find the incorrect number of arguments, the error number is translated to ORA-27301: OS failure message:No such file or directory by Oracle using the code in errno.h. In 11g, the Scheduler also records the return code in the error# column. This lets us recognize the error code better and find where it is raised in the script that ran, when the error codes are unique within the script. When Oracle started with Scheduler, there were some quick changes. Here are the most important changes listed that could cause us problems when the definitions of the mentioned files are not exactly as listed: 10.2.0.1: $ORACLE_HOME/bin/extjob should be owned by the user who runs the jobs (process owner) and have 6550 permissions (setuid process owner). In a regular notation, that is what ls –l shows, and the privileges should be -r-sr-s---. 10.2.0.2: $ORACLE_HOME/rdbms/admin/externaljob.ora should be owned by root. This file is owned by the Oracle user (the user who installed Oracle) and the Oracle install group with 644 permissions or -rw-r—-r--, as shown by ls –l. This file controls which operating system user is going to be the process owner, or which user is going to run the job. The default contents of this file are as shown in the following screenshot: $ORACLE_HOME/bin/extjob must be the setuid root (permissions 4750 or -rwsr-x---) and executable for the Oracle install group, where the setuid root means that the root should be the owner of the file. This also means that while executing this binary, we temporarily get root privileges on the system. $ ORACLE_HOME/bin/extjobo should have normal 755 or -rwxr-xr-x permissions,and be owned by the normal Oracle software owner and group. If this file is missing, just copy it from $ORACLE_HOME/bin/extjob. On AIX, this is the first release that has external job support. 11g release: I n 11g, the same files as in 10.2.0.2 exist with the same permissions. But $ORACLE_HOME/bin/jssu is owned by root and the Oracle install group with the setuid root (permissions 4750 or -rwsr-x---). It is undoubtedly best to stop using the old 10g external jobs and migrate to the 11g external jobs with credentials as soon as possible. The security of the remote external jobs is better because of the use of credentials instead of falling back to the contents of a single file in $ORACLE_HOME/, and the flexibility is much better. In 11g, the process owner of the remote external jobs is controlled by the credential and not by a file. Windows usage On Windows, this is a little easier with regard to file system security. The OracleJobscheduler service must exist in a running state, and the user who runs this service should have the Logon as batch job privilege. A .batfile cannot be run directly, but should be called as an argument of cmd.exe, for example: --/BEGINDBMS_SCHEDULER.create_job(job_name => 'env_windows',job_type => 'EXECUTABLE',number_of_arguments => 2,job_action => 'C:windowssystem32cmd.exe',auto_drop => FALSE,enabled => FALSE);DBMS_SCHEDULER.set_job_argument_value('env_windows',1,'/c');DBMS_SCHEDULER.set_job_argument_value('env_windows',2,'d:temptest.bat');end;/ This job named env_windows calls cmd.exe, which eventually runs the script named test.bat that we created in d:temp. When the script we want to call needs arguments, they should be listed from argument number 3 onwards.
Read more
  • 0
  • 0
  • 4590

article-image-safely-manage-different-versions-content-plone
Packt
08 Oct 2009
2 min read
Save for later

Safely Manage Different Versions of Content with Plone

Packt
08 Oct 2009
2 min read
(For more resources on Plone, see here.) Introducing versioning Now that you have learned how to add various types of content, from pages to events to news items, we're ready to introduce a feature of Plone called versioning, which is an important part of content management. The content items you work with in your Plone site may go through many changes over time. Plone provides versioning information to help you manage your content from the time it was initially created through to the current version. By default, Plone provides versioning for the following content types: Pages News Items Events Links Other content types can be configured to provide versioning through the Plone Control Panel under Types. Although you may enable the File type to use versioning, the only changes that are tracked are those items actually describing the File (for example, Title, Description, and so on). The changes to the contents of the File are not tracked. Creating a new version Versions are created each time you save your content. Note that there is a Change note field at the bottom of the Edit page for content items with versioning enabled: The information entered in the Change note field will be stored along with other versioning information, which you are able to view through the History tab. Viewing the version history You can view the list of all of the versions of a content item by clicking on the History tab for that content item. In the History view that you can see in the following screenshot, the most recent version is listed fi rst. Clicking on any of the column headers will re-sort the listing based on that column heading. The most current version is always labeled Working Copy in the History view. Previewing previous versions To preview a specific version, simply click the preview link of the desired revision. In the following example, revision 3 has been identified, and will be displayed if this link is clicked: On the subsequent page, you may either click on the jump down link to the point of the content preview: or you may scroll down the page in order to see the actual preview:
Read more
  • 0
  • 0
  • 2602
Modal Close icon
Modal Close icon