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-managing-and-enhancing-multi-author-blogs-wordpress-27part-1
Packt
16 Oct 2009
18 min read
Save for later

Managing and Enhancing Multi-Author Blogs with WordPress 2.7(Part 1)

Packt
16 Oct 2009
18 min read
Creating an author page template If you have different authors on your blog, then my suggestion to you would be to display the biographical and contact information of each author on his own dedicated page. Luckily, WordPress allow us to do just that. Getting ready In this recipe, we're going to create an author page template for the purpose of displaying author related information. Make sure that you have understood the creation and usage of a page template. How to do it Create a new file named authors.php on your WordPress theme directory. Insert the following code into your file named authors.php: <?php/*Template Name: Authors Page*/?><?php get_header(); ?><div id="content" class="narrowcolumn"><?phpif(isset($_GET['author_name'])) :$curauth = get_userdatabylogin($author_name);else :$curauth = get_userdata(intval($author));endif;?><h2>About <?php echo $curauth->nickname; ?></h2><div class="excerpt"><?php echo $curauth->nickname; ?> personal website:<a href="<?php echo $curauth->user_url; ?>"><?php echo $curauth->user_url; ?></a></div><?php echo $curauth->user_description; ?><h2>Latest posts by <?php echo $curauth->nickname; ?>:</h2>Chapter 6133<ul><?php if ( have_posts() ) : while ( have_posts() ) :the_post(); ?><li><a href="<?php the_permalink() ?>"><?php the_title();?></a> on <?php the_time('d M Y'); ?></li><?php endwhile; else: ?><p><?php _e('No posts by this author.'); ?></p><?php endif; ?></ul></div><!--/content--><?php get_sidebar(); ?><?php get_footer(); ?> Save the file and upload it to the wp-content/themes/yourtheme folder of your WordPress install. Log in to your WordPress dashboard, create a new page, and select the Authors Page as a page template. Give it the title of your choice, such as, About the Author and publish the page. Open the single.php file from your theme. Depending on the theme that you're using, you may need to add the following code in order to display the author's name and a link to the author's page: Posted by <?php the_author_posts_link(); ?> Once you have saved the modifications made in your single.php file, visit one of your blog posts and click on the author name. The author page is displayed showing the author name, description, and web site. How it works The first thing that we need to know is the name of the author whose information is to be displayed. To do so, we have to get the author_name parameter sent via the GET method. With this value, we can initialize a $curauth php object that will allow us to get some personal information about the author, such as his web site, email, biography, and so on, with the help of the classic php syntax, that is, $curauth->nickname;. Once the author data, that is to be displayed, has been retrieved, we shall add a WordPress loop in order to be able to view the recent posts by this author. The following screenshot shows a well-prepared author page: There's more... In the preceding example we retrieved the author name, description, and web site URL. However, as you may know, users can provide much more information (in Administration, Profile, Your Profile options) such as their email address, AIM and Yahoo! messenger nickname, and login information. A few more template tags can be used to retrieve another kind of information from the author data. These tags are listed under the There's more! section of Displaying author-related information on posts, which we will see later in this article. Displaying a custom login form in your blog's sidebar It doesn't matter whether you're running a multi-author blog, or a blog where readers can register. Having a login form embedded in your sidebar will make your blog look a lot more professional and user friendly. Here is what you can expect from this recipe. In the following screenshot, a login form has been added to the K2 theme sidebar. Getting ready To achieve this recipe, you'll have to edit the sidebar.php file from your theme. The following hack works with WordPress 2.0 to 2.8. How to do it Open the sidebar.php file for editing. Find the opening <ul> tag and paste the following code under it: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2><?php echo $user_identity ?></h2><ul><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echo urlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li></ul><?php elseif ( get_option('users_can_register') ) : ?>Managing and Enhancing Multi-Author Blogs136<h2>Identification</h2><ul><li><form action="<?php bloginfo('url')?>/wp-login.php" method="post"><p><label for="log"><input type="text" name="log"id="log" value="<?php echo wp_specialchars (stripslashes($user_login), 1) ?>" size="22" /> User</label><br /><label for="pwd"><input type="password"name="pwd" id="pwd" size="22" /> Password</label><br /><input type="submit" name="submit" value="Login"class="button" /><label for="rememberme"><input name="rememberme"id="rememberme" type="checkbox" checked="checked"value="forever" /> Remember me</label><br /></p><input type="hidden" name="redirect_to" value="<?php echo$_SERVER['REQUEST_URI']; ?>"/></form></li><li><a href="<?php bloginfo('url')?>/wp-register.php">Register</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=lostpassword">Recover password</a></li></ul><?php endif ?></li> Save the file. Your users can now login directly from your blog's sidebar. How it works The working of this code is quite simple. First, you initialize the global variables to get the user ID, name, and level. Then, you check the value of the $user_ID variable. If the value is not null, which means that the current user is logged in, you then display a quick hello user text and a link to log out. If the user isn't logged in, you check whether registering is allowed on the blog. If the user is logged in, then you simply display an HTML form that allows the user to log in directly from the blog. A link has also been included for registration if the current user doesn't have an account yet. This code was inspired from a tutorial available at www.wpdesigner.com. Adding a control panel to your blog's sidebar Now that you have learned how to check whether a user is logged in or not, why not learn how to add a small control panel to your blog's sidebar that is only visible to the logged in users. In this recipe, you'll learn how to achieve this task. Getting ready The upcoming piece of code works in exactly the same way as the code from the previous recipe does. It is all about checking if the user is logged in and whether he or she has the right to do a certain kind of thing. The following screenshot shows a simple, but useful, control panel which is similar to the one we're about to create: How to do it Open sidebar.php for editing. Find the first opening <ul> HTML tag, and paste the following code under the <ul> tag: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2>Control panel</h2><ul><li>Identified as <strong><?php echo $user_identity ?></strong>.<ul><li><a href="<?php bloginfo('url') ?>/wp-admin/">Dashboard</a></li><?php if ( $user_level >= 1 ) : ?><li><a href="<?php bloginfo('url') ?>/wp-admin/post-new.php">Write an article</a></li><?php endif; ?><li><a href="<?php bloginfo('url') ?>/wp-admin/profile.php">Profile and personal options</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echourlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li><?phpif (is_single()) {?><li><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a></li><?php } ?></ul></li></ul><?php endif; ?></li> Once you are done, save the file. The allowed users can now go to their dashboard, edit their profile, or write a new post directly from the blog. How it works As mentioned earlier, this code works in the same way as the code that was used to create a login form in the sidebar. After you've made sure that the $user_ID variable isn't null, you work towards displaying the options available to the user. It is possible to define what a user can perform according to his role (administrator, author, contributor, subscriber, and so on). We're going to have a look at this in the next recipe. There's more... Now that you have learned how to add a control panel to the blog's sidebar, let's go ahead and try out something new. Adding a login form and a control panel Now that you know how to add a login form and a mini control panel to your blog's sidebar, why not try mixing the two codes? If the user isn't logged in, we'll display the login form. Otherwise, the custom panel will be shown to the user. The code below works in the same way as the two that we studied previously. Add the following code to the sidebar.php file of your theme: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2>Control panel</h2><ul><li>Identified as <strong><?php echo $user_identity ?></strong>.<ul><li><a href="<?php bloginfo('url') ?>/wp-admin/">Dashboard</a></li><?php if ( $user_level >= 1 ) : ?><li><a href="<?php bloginfo('url') ?>/wp-admin/post-new.php">Write an article</a></li><?php endif; ?><li><a href="<?php bloginfo('url') ?>/wp-admin/profile.php">Profile and personal options</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echo urlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li><?phpif (is_single()) {?><li><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a></li><?php } ?></ul></li></ul><?php elseif ( get_option('users_can_register') ) : ?><h2>Identification</h2><ul><li><form action="<?php bloginfo('url') ?>/wp-login.php"method="post"><p><label for="log"><input type="text" name="log" id="log" value="<?php echo wp_specialchars(stripslashes($user_login), 1)?>" size="22" /> User</label><br /><label for="pwd"><input type="password" name="pwd" id="pwd"size="22" /> Password</label><br /><input type="submit" name="submit" value="Login"class="button" /><label for="rememberme"><input name="rememberme" id="rememberme" type="checkbox" checked="checked"value="forever" /> Remember me</label><br /></p><input type="hidden" name="redirect_to" value="<?php echo$_SERVER['REQUEST_URI']; ?>"/></form></li><li><a href="<?php bloginfo('url') ?>/wp-register.php">Register</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=lostpassword">Recover password</a></li></ul><?php endif; ?></li> The custom logging form for unregistered users will look similar to the following screenshot: And the control panel for logged in users will look similar to the following screenshot: Configuring author roles Now that you have learned about the different aspects of the user's roles and capabilities, there's probably something that you're finding a little frustrating. By default, you can't configure author roles to fit your blog's needs. For example, a contributor can't upload images. Moreover, by default, you can't change it. Luckily, there's a plugin called Role Manager which allows you to configure author roles in the way that you want. Getting ready The Role Manager plugin can be found at the following link: http://www.im-web-gefunden.de/wordpress-plugins/role-manager/ Download it, unzip it onto your hard drive, and install it as any other WordPress plugin. How to do it Once the Role Manager plugin is installed, log in to your WordPress dashboard and go to Users | Roles. A list of all of the available user roles will be displayed. For each role you can define what the user can do. For example, you can choose to let a contributor upload images. What is even better is that you're not limited to the 5 default user roles that are provided by WordPress. The Role Manager plugin allows you to create new roles, as well as the ability to rename, copy, or delete existing ones. How it works The job of the Role Manager plugin is pretty easy. It simply creates custom roles with the options that you have defined and save it on the WordPress database. There's more... Now that we have configured the author roles, let's learn how to control the author's actions. Controlling what authors can do Even if your blog is powered by multiples authors, it is still your blog. Therefore, you shouldn't allow every author to have the right to edit posts or delete comments. Since version 2.0, WordPress features user roles. User roles are defined as a group of actions that can be accomplished by a specific range of users. For example, the administrator can edit theme files, but the subscribers can't. User roles and their capabilities Here are the 5 predefined roles for WordPress users: Administrator: The administrator is the blog owner. He has unlimited access to all of the administration features such as writing posts, editing his own posts along with the posts from other authors, installing plugins, selecting a new theme, editing themes, and editing plugin files. Editor: The editor can write or publish posts, upload images, edit his own posts, and manage other's posts. Author: The author can write, publish, and edit his own his own posts. He's also allowed to upload images for use in his posts. Contributor: A contributor can write posts but can't publish them himself. Once he has written a post, the post is pending approval from the administrator. The contributor can't upload images either. This role is very good for guest authors on your own blog. Subscriber: A subscriber is a registered user of your blog, but can't write posts. For an exhaustive description of user roles and capabilities, you should read the related page in WordPress Codex: http://codex.wordpress.org/Roles_and_Capabilities. Controlling what users can see in your theme In the previous example, we built a sidebar control panel that allows the user to edit the current post. However, the code doesn't let you control which kind of author is allowed to edit the current post. For now, even if only the users with a sufficient role level will be capable of editing the post, every logged in user can see the related link. The solution to that problem is a built-in WordPress function, called current_user_can(). As an argument, this function takes a string describing the action or the required role level to perform a specific task. For example, the following code will provide a link to edit the current post to the administrators only: <?phpif (current_user_can('level_10')){ ?><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a><?php } ?> The current_user_can() function accepts user_0 to user_10 as a parameter. Here is the conversion table between the role levels and the roles: Suscriber: level_0 Contributor: level_1 Author: level_2 to level_4 Editor: level_5 to level_7 Administrator: level_8 to level_10 The current_user_can() function can also be used with a specific action as a parameter. This is the recommended use, as the level parameter is becoming obsolete. The following example checks if the current user can edit a post he previously published. If yes, then a link to edit the post will be displayed. <?phpif (current_user_can('edit_published_posts')){ ?><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a><?php } ?> Here are all of the arguments that are accepted by the current_user_can() function:      switch_themes      edit_themes      activate_plugins      edit_plugins      edit_users      edit_files      manage_options      moderate_comments      manage_categories      manage_links      upload_files      import      unfiltered_html      edit_posts      edit_others_posts      edit_published_posts      edit_pages      edit_others_pages      edit_published_pages      edit_published_pages      delete_pages      delete_others_pages      delete_published_pages      delete_posts      delete_others_posts      delete_published_posts      delete_private_posts      edit_private_posts      read_private_posts      delete_private_pages      edit_private_pages      read_private_pages      delete_users      create_users      unfiltered_upload      edit_dashboard      update_plugins      delete_plugins Displaying author-related information on posts In a multi-author blog, it's always good for the reader to know the author of the article that they're currently reading. It's even better if they can grab some extra information about the author, such as his website, a short bio, and so on. In this recipe, you'll learn how to edit your single.php theme file to automatically retrieve the author-related information, and display it at the top of the page. Getting ready As we're going to display author information on posts, the first thing to do is to make sure that your contributing authors have entered their biography and other information into the WordPress database. Any author can enter his information by logging in to the WordPress dashboard, and then going to Profile. The blog administrator can edit all of the profiles. The following screenshot shows the WordPress 2.7 profile editor for the authors. How to do it Once you have made sure that your authors have successfully filled their information, you can start coding by carrying out the following steps: Open the file single.php for addition. Paste the following code within the loop: <div id="author-info"><h2>About the author: <?php the_author();?></h2><?php the_author_description(); ?><?php the_author();?>'s website: <a href="<?php the_author_url();?>"><?php the_author_url(); ?></a><br />Other posts by <?php the_author_posts_link(); ?></div><!--/author-info--> Save the file and visit your blog. You will notice that your posts now automatically display the author-related information, as shown in the following screenshot: How it works WordPress provides a dozen of author-related template tags, which are an easy way to retrieve information that is entered by authors in their profile. Note that all of these tags must be used within the loop for them to work. There's more... Here are all the available template tags related to authors:
Read more
  • 0
  • 1
  • 2846

article-image-ajaxdynamic-content-and-interactive-forms-joomla
Packt
16 Oct 2009
13 min read
Save for later

AJAX/Dynamic Content and Interactive Forms in Joomla!

Packt
16 Oct 2009
13 min read
AJAX: an acronym that Jesse James Garret of AdaptivePath.com came up with in 2005. Just a few short years later, it seems like every site has a "taste" of AJAX in it. If you're totally new to AJAX, I'll just point out that, at its core, AJAX is nothing very scary or horrendous. AJAX isn't even a new technology or language. Essentially, AJAX stands for: Asynchronous JavaScript and XML, and it is the technique of using JavaScript and XML to send and receive data between a web browser and a web server. The biggest advantage this technique has is that you can dynamically update a piece of content on your web page or web form with data from the server (preferably formatted in XML), without forcing the entire page to reload. The implementation of this technique has made it obvious to many web developers that they can start making advanced web applications (sometimes called RIAs—Rich Interface Applications) that work and feel more like software applications than web pages. Keep in mind that the word AJAX is starting to have its own meaning (as you'll also note its occasional use here as well as all over the Web as a proper noun rather than an all-cap acronym). For example, a Microsoft web developer may use VBScript instead of JavaScript to serve up Microsoft Access database data that is transformed into JSON (not XML) using a .NET server-side script. Today, that guy's site would still be considered an AJAX site rather than an "AVAJ" site (yep, AJAX just sounds cooler). In fact, it's getting to the point where just about anything on a web site (that isn't in Flash) that slides, moves, fades, or pops up without rendering a new browser window is considered an "Ajaxy" site. In truth, a large portion of these sites don't truly qualify as using AJAX, they're just using straight-up JavaScripting. Generally, if you use cool JavaScripts in your Joomla! site, it will probably be considered Ajaxy, despite not being asynchronous or using any XML. Want more info on this AJAX business? The w3schools site has an excellent introduction to AJAX, explaining it in straightforward simple terms. They even have a couple of great tutorials that are fun and easy to accomplish even if you only have a little HTML, JavaScript and server-side script (PHP or ASP) experience (no XML experience required): http://w3schools.com/ajax/. Preparing for dynamic content and interactive forms Gone are the days of clicking, submitting, and waiting for the next page to load, or manually compiling your own content from all your various online identities to post in your site. A web page using AJAX techniques (if applied properly) will give the user a smoother and leaner experience. Click on a drop-down option and check-box menus underneath are immediately updated with the relevant choices—no submitting, no waiting. Complicated forms that, in the past, took two or three screens to process can be reduced into one convenient screen by implementing the form with AJAX. As wonderful as this all sounds, I must again offer a quick disclaimer: I understand that, like with drop-down menus and Flash, you may want AJAX to be in your site, or your clients are demanding that AJAX be in their sites. Just keep in mind, AJAX techniques are best used in situations where they truly benefit a user's experience of a page; for example, being able to painlessly add relevant content via an extension or cutting a lengthy web process form down from three pages to one. In a nutshell, using an AJAX technique simply to say your site is an AJAX site is probably not a good idea. You should be aware that, if not implemented properly, some uses of AJAX can compromise the security of your site. You may inadvertently end up disabling key web browser features (such as back buttons or the history manager). Then there's all the basic usability and accessibility issues that JavaScript in general can bring to a site. Some screen readers may not be able to read a new screen area that's been generated by JavaScript. If you cater to users who rely on tabbing through content, navigation may be compromised once new content is updated. There are also interface design problems that AJAX brings to the table (and Flash developers can commiserate). Many times, in trying to limit screen real estate and simplify a process, developers actually end up creating a form or interface that is unnecessarily complex and confusing, especially when your user is expecting a web page to, well, act like a normal web page. Remember to check in with Don't Make Me Think: This is the Steve Krug book I recommend for help with any interface usability questions you may run into.Really interested in taking on AJAX? For you programmers, I highly recommend "AJAX and PHP: Building Responsive Web Applications", Cristian Darie, Bogdan Brinzarea, Filip Chereches-Tosa, and Mihai Bucica, Packt Publishing. In it, you'll learn the ins and outs of AJAX development, including handling security issues. You'll also do some very cool stuff, such as make your own Google-style auto-suggest form and a drag-and-drop sortable list (and that's just two of the many fun things to learn in the book). So, that said, you're now all equally warned and armed with all the knowledgeable resources I can think to throw at you. Let's get to it: how exactly do you go about getting something Ajaxy into your Joomla! site? Joomla! extensions Keep in mind, extensions are not part of your template. They are additional files with Joomla!-compatible PHP code, which are installed separately into their own directories in your Joomla! 1.5 installation. Once installed, they are available to be used with any template that is also installed in your Joomla! installation. Even though these are not part of your template, you might have to prepare your template to be fully compatible with them. Some extensions may have their own stylesheets, which are installed in their extension directory. Once you've installed an extension, you may want to go into your own template's stylesheet so that it nicely displays XHTML objects and content that the extension may output into your site. Extensions are any component, module or plugin that you install into your Joomla! 1.5 installation. Components control content that displays in the main type="component" jdoc tag in your template. Note that components may also have module settings and the ability to display content in assigned module positions. The poll component is a good example of a component that also has module settings. Modules are usually smaller and lighter and only display in module positions. Plugins generally help you out more on the backend of your site, say to switch WYSIWYG editors or with enabling OpenID logins, but as we'll see, some plugins can affect the display of your site to users as well. Deciding where AJAX is best used On the whole, we're going to look at the most popular places where AJAX can really aid and enrich your site's user experience. We'll start with users adding comments to articles and pages and streamlining that process. We'll then take a look at a nice plugin that can enhance pagination for people reading long articles on your site. We'll then move on to the RSS Reader module, which can enhance the content in your modules (and even makes your users have fun arranging them). Finally, we'll realize that AJAX isn't just for impressing your site users. You, as an administrator, can (and do) take advantage of AJAX as well. Please note: These extensions were chosen by me based on the following criteria: 1. They provided some useful enhancement to a basic site.2. They, at the time of this writing, were free and received very good feedback on Joomla!.org's extensions site: http://extensions.Joomla.org. In the next few pages, I'll walk you through installing these extensions and discuss any interesting insights for doing so, and benefits of their enhancements (and some drawbacks). But you must use the extension links provided to make sure you download the latest stable versions of these extensions and follow the extension author's installation guides when installing these into your Joomla! site. If you run into any problems installing these extensions, please contact the extension's author for support. Always be sure to take the normal precaution of backing up your site before installation, at least for any non-stable extensions you may decide to try. Installing the Joomla! comment component Chances are, if you've invested in Joomla! 1.5 as your CMS, you need some powerful capabilities. Easy commenting with "captcha" images to reduce spam is always helpful: http://extensions.Joomla.org/extensions/contacts-&-feedback/comments/4389/details To install this extension (and the other few coming up), you have to basically go to Extensions | Install/Uninstall and upload the extension's ZIP file. You'll then proceed to the plugin, component, and/or modules panel and activate the extension so that it is ready to be implemented on your site. Upon installing this comment component, to my surprise, it told me that it was for an older version of Joomla! Everything on the download page seemed to indicate it worked with 1.5. The installation error did mention that I just needed to activate the System Legacy plugin and it would work. So I did, and the comment form appeared on all my article pages. This may seem like a step backward, but for extensions like this, which are very useful, if they work well and stay stable in Legacy Mode, a developer may have made the decision to leave well enough alone. The developer will most likely eventually upgrade the extension (especially if Legacy Mode goes away in future versions of Joomla!). Just be sure to sign up for updates or check back on any extensions you use if you do upgrade your site. You should do this regardless of whether your extensions run natively or in Legacy Mode. The advantage of AJAX in a comment form is that a user isn't distracted and comments post smoothly and right away (a bit of instant gratification for the user, even if you never "confirm" the post and it never gets actually published for other viewers). This extension outputs tables, but for the ease of handling robust comments and having a great admin area to manage them, I'll make do. The following screenshot shows the Joomla! comment component appearing in an article page: As you can see in my previous image, I have some strong styles that are trying to override the component's styles. A closer look at the output HTML will give me some class names and objects that I can target with CSS. The administration panel's Component | Joomla! Comment | Other Component settings page also allows quite a few customization options. The Layout tab also offers several included style sheets to select from as well as the option to copy the CSS sheet out to my template's directory (the component will do this automatically). This way, I can amend it with my own specific CSS, giving my comment form a better fit with my template's design. Installing the core design Ajax Pagebreak plugin If your site has long articles that get broken down regularly in to three or more pages, Pagebreak is a nice plugin that uses Ajax to smoothly load the next page. It's a useful feature that will also leave your site users with a little "oh wow" expression. http://www.greatJoomla.com/news/plugins/demo-core-design-ajaxpagebreak-plugin.html After successfully installing this plugin, I headed over to the Extensions | Plugin Manager and activated it. I then beefed out an article (with Lorem Ipsum) and added page breaks to it on the Home Page. It's hard to see in a screenshot, but it appears below the Prev and Next links without a full browser redraw. I've set my site up with SEO-friendly URLs, and this plugin does amend the URLs with a string; that is, http://yoururl.com/1.5dev/menu-item-4?start=1. I'm not sure how this will really affect the SEO "friendliness" value of my URL, but it does give me a specific URL to give to people if I want to send them to a targeted page, which is very good for accessibility. One thing to note, the first page of the article is the original URL; that is, http://yoururl.com/1.5dev/menu-item-4. The second page then appends ?start=1, the third page becomes ?start=2, and so on. Just be aware that when sending links out to people, it is always best to pull the URL directly from the site so that you know it's correct! Installing the AJAX RSS Reader Version 3 with Draggable Divs module RSS feeds are a great way to bring together a wide variety of content as well as bring all your or your organization's "social network happenings" to one place in your own site. I like to use RSS feeds to get people interested in knowing what an organization is doing (or tweeting), or reading, and so on. Having links and lists of what's currently going on can compel users to link to you, join your group, follow you, and become a friend, a fan, or whatever. This AJAX powered module has the extra feature of being draggable and somewhat editable. This is a nice way to draw a user in to the feeds and let them play with them and arrange the information to their taste. Sometimes, sorting and reorganizing makes you see connections and possibilities that you didn't see before. The next image may seem confusing, but it's a screenshot of the top div box being dragged and dropped: http://extensions.Joomla!.org/extensions/394/details AJAX: It's not just for your site's users I've already mentioned, when applied properly, how AJAX can aid in interface usability. Joomla! attempts to take advantage of this within its Administration panel by enhancing it with relevant information and compressing multiple page forms into one single screen area. Here's a quick look at how Joomla! already uses AJAX to enhance its Administration panel forms: The following image shows how the image uploader uses a "lightbox" div layer effect so that you can keep track of where you are in the content editor. In the next image, you can see how Joomla! helps keep the administration area cleared up by using smooth-sliding accordion panels. This helps you see everything on one page and have access to just what you need, when you need it.
Read more
  • 0
  • 0
  • 3125

article-image-maintaining-optimizing-and-upgrading-your-site-drupal-6-part-1
Packt
16 Oct 2009
7 min read
Save for later

Maintaining, Optimizing and Upgrading Your Site in Drupal 6: Part 1

Packt
16 Oct 2009
7 min read
We will consider the example of an imaginary web site created for a restaurant called Good Eatin' Bistro. Chef Wanyama is the owner of the Good Eatin' Bistro, a popular upscale restaurant. You can check this web site at http://goodeatin.drupalbyexample.com/. Web site backups A strong backup plan is critical for any successful web site. A good backup plan will protect against hardware failure, allow you to transfer your web site to another host, and allow you to recover from malicious hacking into your web site. When you create a backup plan, you should also test the restoration from this backup to make sure that the backup works correctly. In this section, we will explore ways of performing backups regardless of the host that you are using. Your hosting provider may also offer a solution that will back up files and databases either one time, or on a recurring basis. If your host does provide backup capabilities, you should review them to see if they suit your needs completely, or if you want to augment them or replace them with the techniques in this section. Manually backing up a site Good Eatin' Goal: Back up the web site without using a custom backup module. Additional modules needed: None. Basic steps If you do not want to use a dedicated module to perform your backups, you can manually download the files and the database information that make up the site. However, this can be more time-intensive and error-prone than using a custom backup module. A manual backup has two steps, in which you must first back up the files that make up the site and then back up the database information. To back up the files for the web site, use the following procedure: Begin by opening the utility that you use to transfer files to the web site. This could be an FTP client, or an online file manager. My favorite FTP client is FileZilla, which is a freely-available open source client. The FileZilla client can be downloaded from http://filezilla-project.org/. Select the backup location on your local computer to which you want to copy the files, and select the root directory of your web server as the remote directory. You may want to date the backup folder so that you can maintain a history of the site. Next, download the files to your local directory. If you want, you can compress the files into a ZIP file or a compressed archive. To reduce the amount of data that you need to download, you should be able to download just the sites directory, because that folder contains all of the custom files, pictures, themes, and modules that you have added to the site. To back up the database information, you can use your web site provider's database management utility. Many hosts provide phpMyAdmin for this purpose. If you are unsure whether or not your host gives you access to phpMyAdmin, you can contact their customer support group to check. Begin by opening phpMyAdmin and selecting the database that has your site information within it. The screen should be similar to the following: If you have multiple databases available on the host, you may need to select the database that you want to work with in the drop-down list at the upper left corner of the screen. Next, select the Export tab at the top of the screen. phpMyAdmin will prompt you to select the tables that you want to download and the format that you want to download in, as shown in the following screenshot: If you want to be able to rebuild the database at a later time, you should export all the tables in SQL format. Next, you will need to specify the name of the file to download to. You can use __DB__ as the database name. You may want to zip the file to reduce storage space. Then click Go to begin the download process. You will be prompted for the location to which you want to save the exported data. When you are ready to restore the web site from backup, you simply reverse the process. You should always import into a blank database, to avoid conflicts with existing data. You can either drop or delete all of the titles in the existing database, or you can create a new database to import the data into. After you have cleaned out your database, select the Import tab in phpMyAdmin. Now navigate to the file that you exported earlier, and click Go to begin the import. You may need to delete all of the tables in the database before you import the data, depending on the options you chose when you exported the data. To reload the files, simply open your FTP client, select the same directories that you used when creating the backup and then upload the files, rather than downloading them. Automatic site backups Good Eatin' Goal: Back up a web site so that it can be stored for easy recovery. Additional modules needed: Backup and Migrate (http://drupal.org/project/backup_migrate). Basic steps Although you can manually back up your files and database, this process can be time-consuming and error prone. Luckily, the Backup and Migrate module makes this process easier, and optimizes the backups to exclude unnecessary data. Begin by downloading and installing the Back up and Migrate module. You can now back up your data by selecting Content management and then Backup and migrate, from the Administer menu. The Backup and Migrate module allows you to fully customize the backup files that are created. You can control which tables are included in the backup, and whether or not the data in the table is backed up. By default, the Backup and Migrate module does not back up cache information, session information, or watchdog information, because data in these tables is temporary and can easily be re-created. There are a variety of other options that you can choose from, which control how the resulting file is named, how it is compressed, and where it is compressed to. Once you have set the options as desired, click Backup Database to begin the backup process. If you have selected the Download option, the file will be sent to your computer so that you can store it. If you select the Save to Files Directory option, the backup file will be saved onto the server so that you can download it later, either directly from the server or using the Saved Backups tab. If you would like the Backup and Migrate module to back up your database automatically on a regular basis, you can schedule the back up to occur at specified intervals by clicking on the Backup Schedule tab, as shown here: Please note that the backups created by the Backup and Migrate module do not include the files from the site, so you will still need to back up these files independently. You can minimize the backup file size by only backing up the files that the users can upload. These files are typically stored in the files directory. The process for backing up files is identical to the process used in the section on manual backups. Restoring a site from a backup Good Eatin' Goal: Restore information from a backup file created by the Backup and Migrate module. Additional modules needed: Backup and Migrate (http://drupal.org/project/backup_migrate). Basic steps Restoring a backup created by the Backup and Migrate module is a simple process. Navigate to the Backup and Migrate manager by selecting Content management and then Backup and Migrate, from the Administer menu. Next, click on the Restore/Import DB tab. Navigate to the location of your backup file. After you have selected the backup file, click on Restore Database to begin the restore process. Please read all displayed warnings carefully, and make sure that you test the import on a test installation for your site before running it on your production site. If you are sure that you want to proceed with the import, agree to the confirmation and click restore. You may also need to import any saved files, if the server file system is not fully up-to-date. We discussed this previously in the section on manual backups.
Read more
  • 0
  • 0
  • 1367

article-image-asterisk-gateway-interface-scripting-php
Packt
16 Oct 2009
4 min read
Save for later

Asterisk Gateway Interface Scripting with PHP

Packt
16 Oct 2009
4 min read
PHP-CLI vs PHP-CGI Most Linux distributions include both versions of PHP when installed, especially if you are using a modern distribution such as CentOS or Mandriva. When writing AGI scripts with PHP, it is imperative that you use PHP-CLI, and not PHP-CGI. Why is this so important? The main issue is that PHP-CLI and PHP-CGI handle their STDIN (standard input) slightly differently, which makes the reading of channel variables via PHP-CGI slightly more problematic. The php.ini configuration file The PHP interpreter includes a configuration file that defines a set of defaults for the interpreter. For your scripts to work in an efficient manner, the following must be set—either via the php.ini file, or by your PHP script: ob_implicit_flush(false); set_time_limit(5); error_log = filename;error_reporting(0); The above code snippet performs the following: Directive Description ob_implicit_flush(false); Sets your PHP output buffering to false, in order to make sure that output from your AGI script to Asterisk is not buffered, and takes longer to execute set_time_limit(5); Sets a time limit on your AGI scripts to verify that they don't extend beyond a reasonable time of execution; there is no rule of thumb relating to the actual value; it is highly dependant on your implementation Depending on your system and applications, your maximum time limit may be set to any value; however, we suggest that you verify your scripts, and are able to work with a maximum limit of 30 seconds. error_log=filename; Excellent for debugging purposes; always creates a log file error_reporting(E_NONE); Does not report errors to the error_log; changes the value to enable different logging parameters; check the PHP website for additional information about this AGI script permissions All AGI scripts must be located in the directory /var/lib/asterisk/agi-bin, which is Asterisk's default directory for AGI scripts. All AGI scripts should have the execute permission, and should be owned by the user running Asterisk. If you are unfamiliar with these, consult with your system administrator for additional information. The structure of a PHP based AGI script Every PHP based AGI script takes the following form: #!/usr/bin/php -q <? $stdin = fopen(‘php://stdin’, ‘r’); $stdout = fopen(‘php://stdout’, ‘w’); $stdlog = fopen(‘my_agi.log’, ‘w’); /* Operational Code starts here */ .. .. ..?> Upon execution, Asterisk transmits a set of information to our AGI script via STDIN. Handling of that input is best performed in the following manner: #!/usr/bin/php -q <? $stdin = fopen(‘php://stdin’, ‘r’); $stdout = fopen(‘php://stdout’, ‘w’); $stdlog = fopen(‘my_agi.log’, ‘w’); /* Handling execution input from Asterisk */ while (!feof($stdin)) { $temp = fgets($stdin); $temp = str_replace("n","",$temp); $s = explode(":",$temp); $agivar[$s[0]] = trim($s[1]); if $temp == "") { break; } } /* Operational Code starts here */ .. .. ..?> Once we have handled our inbound information from the Asterisk server, we can start our actual operational flow. Communication between Asterisk and AGI The communication between Asterisk and an AGI script is performed via STDIN and STDOUT (standard output). Let's examine the following diagram: In the above diagram, ASC refers to our AGI script, while AST refers to Asterisk itself. As you can see from the diagram above, the entire flow is fairly simple. It is just a set of simple I/O queries and responses that are carried through the STDIN/STDOUT data streams. Let's now examine a slightly more complicated example: The above figure shows an example that includes two new elements in our AGI logic—access to a database, and to information provided via a web service. For example, the above image illustrates something that may be used as a connection between the telephony world and a dating service. This leads to an immediate conclusion that just as AGI is capable of connecting to almost any type of information source, depending solely on the implementation of the AGI script and not on Asterisk, Asterisk is capable of interfacing with almost any type of information source via out-of-band facilities. Enough of talking! Let's write our first AGI script.
Read more
  • 0
  • 0
  • 6738

article-image-jboss-portals-and-ajax-part-1
Packt
16 Oct 2009
7 min read
Save for later

JBoss Portals and AJAX - Part 1

Packt
16 Oct 2009
7 min read
Rich user interfaces and AJAX Rich user interfaces can be achieved by using a combination of dynamic HTML elements such as HTML and JavaScript. However, the scope of such an interface is limited to client-side behavior and has minimal functional implications due to the lack of server-side interactions. The power of AJAX is in its capability to provide even richer interface by supplementing its dynamic user interface with powerful functionality through seamless server-side invocation power. AJAX allows individual user interface components to communicate with the server and exchange data without the need for refreshing the whole screen. This is achieved using a process called Web Remoting. Web remoting, or the process of communicating between a browser and a server, can be performed in multiple ways. The popular approaches that are supported by today's browsers are IFrames and XMLHttpRequest. Dynamic HTML can be complemented with either of these methods to generate AJAX functionality. Asynchronous JavaScript and XML or AJAX Asynchronous communication between the client and the server forms the backbone of AJAX. Although an asynchronous request-response method can provide significant value in the development of rich functionality by itself, the results are lot more pronounced when used in conjunction with other functional standards such as CSS, DOM, JavaScript, and so on. The predominant popularity of AJAX stems from such usage. Client-server communication can be achieved either by using IFrames, or by using the supported JavaScript function called XMLHttpRequest(). Due to certain limitations of IFrames, XMLHttpRequest has gained a lot more acceptance. While IFrame can also be an effective option for implementing AJAX-based solutions, in this article, we will focus largely on an XMLHttpRequest-based implementation. The primary advantage of using AJAX-based interfaces is that the update of content occurs without page refreshes. A typical AJAX implementation using XMLHttpRequest happens as described in the following steps: An action on the client side, whether this is a mouse click or a timed refresh, triggers a client event An XMLHttpRequest object is created and configured The XMLHttpRequest object makes a call The request is processed by a server-side component The component returns an XML (or an equivalent) document containing the result The XMLHttpRequest object calls the callback() function and processes the result The HTML DOM is updated with any resulting values The following simplified image illustrates the high-level steps involved in an AJAX request flow. The portal client page gets served to the client browser, where the execution of JavaScript functions takes place. The following example illustrates the initialization of the request object and its basic use: if (window.XMLHttpRequest) // Object of the current window { // for non-IE browsers request = new XMLHttpRequest();}else if (window.ActiveXObject){ // For IE request = new ActiveXObject("Microsoft.XMLHTTP");}request.onreadystatechange = function(){ // do something to process response};if (request.readyState == 4){ // everything received, OK. Do something now..} else { // wait for the response to come to ready state} In subsequent sections, we will modify our sample portal application by adding AJAX functionality to one of the portlets. AJAX in JBoss portal AJAX has gained tremendous popularity in the traditional web application development world due to the richness and agility that it brings to user interfaces. Portals, such as JBoss portal, can also gain significantly from AJAX, in terms of implementation of both behavior and functionality. Refreshing the page content tends to be a time-consuming and resource-intensive process. Every request that a user makes to the server, either by clicking on submissions or links, results in the portal calling doView() and a series of methods for each portlet on the page, one at a time, before aggregating the results and sending the response back to the browser. Using AJAX allows for simultaneous submissions of request in their own independent threads of execution, resulting in an asynchronous and parallel execution. The portal page refresh overhead is now only as long as the time consumed by the slowest portlet. The response times observed by the user improve dramatically, while at the same time allowing more functionality on pages. Architecturally, vertical independent stacks of execution facilitate cleaner and more modular designs and implementations. AJAX can be implemented in JBoss portal in the following two ways: Using in-built support for asynchronous portal behavior by using configurations Writing custom behavior in portlets and page content by using AJAX libraries The in-built support for asynchronous behavior comprises of support for both markup and content. The markup support is in layouts and renderers, while the content is supported through configurable drag-drop and partial page refresh behavior. Almost all of the AJAX behavior supported by JBoss portal relates to asynchronous communication between the client and the portal servers. The only exception is the drag-drop behavior, which is largely view functionality. As far as the custom development within a portlet is concerned, the options are innumerable. A portlet can be developed using many advanced frameworks that are available as either commercial or open source products. For example, user interface features such as drag-and-drops, grids, accordion selects, pull-down menus, content refresh, and so on can be implemented by using third-party libraries including Scriptaculous, JQuery, and DOJO, which have gained a strong following among developers, even on traditional applications and non-portal platforms. In the next few sections, we will walk through an example of AJAX-enabled portlets using one of these libraries, developed on the JBoss portal platform. However, before we go into the implementation, let's step back and understand the limitations that the current portlet specification– JSR-286–addresses, facilitating easy development of AJAX portlets. JSR-168 AJAX limitations Before we look at the features and options provided by the new specification, let's look at how traditional JSR-168 portlets functioned. As shown in the following figure, the "Action" request invoked the processAction method on the server, which implemented controller logic to route it to the correct view. The "Render" request then invokes the render method to serve the content page to the browser. However, when the portlet uses AJAX and needs to makes an asynchronous call, it has to use ActionURL. This in turn follows the standard processing when processAction processes the request and the render method creates the user interface. However, now when the user interface is sent back, the portal injects some other markup and recreates the entire portal page. Hence, instead of refreshing a snippet of user interface, we end up refreshing the whole page. The issues with JSR-168 and AJAX can be broadly summarized as follows: ActionURL and RenderURL point to a portal, and not to a portlet. When we point to a portal, the result is a complete portal page, even if the portlet generates only a snippet. As per the specification, the user interface rendered by the portlet is supposed to be aggregated with some other markup and served back to the browser. When more than only the necessary data and markup is sent back, the JavaScript code on the client side that makes the asynchronous call cannot process the request. Asynchronous calls are made through XMLHttpRequest, which is designed to consume and process the complete response from the portlet. With the portal processing the request in between, XMLHttpRequest cannot consume the original response for processing. This defeats the purpose and value of using asynchronous calls to the server, and we end up with traditional full page refreshes. There were obviously a few workarounds to this. The most common practice was to serve the request from outside of the portal container into the web container. The idea is that the AJAX call can still be made to ActionURL, but the render function copies or shares its context with a traditional Java servlet in the web container of the application server. The AJAX call can now make a direct request to the servlet and get an asynchronous response from the servlet with no interference from the portal. There was a need for a better solution, and one that was incorporated as part of the specification. JSR-286, the latest portlet specification, addresses these problems.
Read more
  • 0
  • 0
  • 2399

article-image-storing-planning-data-ibm-cognos-d-cube-part-1
Packt
16 Oct 2009
10 min read
Save for later

Storing Planning Data in IBM Cognos: D-Cube (Part 1)

Packt
16 Oct 2009
10 min read
Overview of the D-Cube In Analyst, data is stored in a D-Cube. The D-Cube is a multi-dimensional data structure similar to an OLAP or Excel pivot table. Each of the dimensions contains a list of related data. For example, in a four dimensional cube, the first dimension may contain the items in  P&L statement, the second may list the departments, the third show the timescale, and the fourth may show the version (Budget or Actual). In this example, you have the  P&L statement by month, by department, and by version. The D-Cube must have at least two dimensions. If more than two dimensions exist, the other dimensions appear as pages. The following screenshot depicts a four dimensional D-Cube. The first two dimensions form the rows and columns. The third and fourth dimensions are displayed as pages, in the upper-left corner of the D-Cube. You can switch to different pages in the cube by clicking the page drop-down list and selecting another page. Creating a D-Cube Creating a D-Cube takes a few simple steps but it requires a great deal of forethought. Before creating the D-Cube, you must think through the dimensions that will form the cube. You must know what data will populate the D-Cube. You must know what category of D-Lists your selection falls under so that you can prioritize the calculations appropriately. You must know what function the D-Cube performs. Is it an input cube, a calculation cube, a summary or reporting cube, or a staging cube? You must also know in which library the D-Cube will be stored, and whether the D-Cube will be shared or will be exclusive to a model. Finally, you must consider size and performance, especially if you plan to deploy the D-Cube in Contributor. To create a D-Cube: Click on File | New | D-Cube. In the Create new D-Cube box, select the D-List that makes up the D-Cube. Drop the D-List onto the lower pane. Order the D-List. Click on OK. Enter the D-Cube name, and then click on OK. By default, the D-Cube opens with the longest D-List as the rows and the timescale as the columns. You can transpose the cube or swap the dimensions by dragging and dropping them. When you close and reopen the D-Cube, it will revert to the default view. Order of dimensions It is important to have the proper order of dimensions in the D-Cube. The order of dimensions is important because it determines which calculation takes precedence when calculations from two separate D-Lists intersect. The order also determines the priority of formats when the cell has opposing formats. As a rule, the dimensions must follow this order: Calculation: Calculation D-Lists contain mathematical operations over and above simple addition. Any use of operators, such as multiplication, subtraction, division, or the use of a BiF, make the D-List a calculation D-List. Aggregation: Aggregation D-Lists usually contain a hierarchy of items, such as an organizational hierarchy, a list of products, customers, or cost centers, or a list of items with a simple subtotal. Non-Calculating: Non-Calculating D-Lists contain no calculations. Timescale: Timescale D-Lists contains items that span a period of time, such as months, weeks, or days. Versions: Version D-Lists contain iterations of the data, such as Actual, Budget, Forecast, and Revised Budget. It is critical to set the proper order of dimensions before building the Contributor application. If you reorder the dimensions after the application is created, all of the data in the D-Cube will be deleted. In addition, reordering dimensions changes the structure of the import tables and, therefore, the way that you import data into Contributor. Size considerations The size of the D-Cube is measured by the number of cells in it. The number of cells you can have in a D-Cube is limited only by your computer's memory. When you build a D-Cube, you should keep in mind the amount of memory available on the computer on which the model will be used. You will not be able to open a large cube if your PC does not have enough memory to handle the data. If the model is deployed in Contributor, size is an even more important consideration. Even with a powerful computer, you will experience performance lag because a large model must pass through the organization's network. In a wide area network, the problem associated with a large model becomes more apparent. To determine the number of cells, find the product of the number of items in all of the D-lists in the D-Cube. For instance, if a D-Cube has five D-Lists, which have the following number of items: 8, 1, 10, 5, and 12, the number of cells in the D-Cube will be 4,800. This is 8*1*10*5*12. You can find the number of cells in the dimension selection box, as illustrated in the following screenshot: The number of items in a dimension has an inverse impact on the magnitude of size increases for additions to the cube. The fewer the items, the bigger the impact that an addition will have to the size of the cube. In the example of the cube above, if you add one item to a dimension that has only one item, you will double the size of the cube. However, if you add one item to a dimension that has 10 items, you will increase the size of the cube by only ten percent. One clue that your D-Cube may have a problem with size is the number of dimensions. While there is no limitation on the number of dimensions that a cube can have, having too many of them can become a problem. With a D-Cube that has too many dimensions, any additional item in one of the D-Lists increases the size in an order of magnitude depending on the number of items in the D-List. If possible, keep the number of dimensions to not more than five. If you need to have a D-Cube that provides views of data beyond five dimensions, consider splitting the D-Cube. You are more likely to require less memory if you have several smaller cubes than with one super cube. With Analyst, you can open a D-Cube that has several million cells on a PC that has 512MB of RAM. However, if you plan to deploy the model in Contributor, the threshold for the number of cells is much lower. An acceptable benchmark is roughly 500,000 cells per e.List. This benchmark is subject to many other factors, such as network latency, client PC memory, and CPU, all of which can contribute to model performance. Working with the D-Cube When working with the D-Cube, you have several functionalities that help you to hone in on the information that you want. By default, the D-Cube opens in full view, but you can open only a slice of the cube and save the slice for later viewing. Opening a full view of the D-Cube The most straightforward way to view the D-Cube is to open all dimensions. To open a full D-Cube: Click on File | Open | D-Cube. Select the D-Cube. Click on OK. Select the Full option. Click on OK. Opening a selection of the D-Cube A selection is a subset of a D-Cube. You can only open the specific items of the dimensions that you want to view. Because the data in a selection is fewer than the full view, less memory is required and the D-Cube opens and recalculates faster. To open a selection of the D-Cube: Click on File | Open | D-Cube. Select the D-Cube. Click on OK. Select the Edit Selection option. This option opens the dimension selection box, where you can select the items that you want to view in the D-Cube slice. As shown in the following illustration, the item selection box lets you select the items from a dimension that you want to include in your view. In the item selection box, each tab represents a D-List. To select the items, move the items from the Items available pane (on the left) to the Items included pane (on the right). Click on OK. Viewing different slices of the D-Cube You can view the D-Cube in a variety of ways. You can open a selection of the D-Cube, or several selections at the same time. If you have a selection open, you can change it to another selection. The ability to switch views makes it easier to work with the D-Cube. For instance, suppose you have a D-Cube that has two versions: Budget and Actual. If you want to enter only budget data, you may want to open only the Budget dimension and keep the Actual dimension closed. You can have multiple selections of the D-Cube open at the same time in the same way that you open the D-Cube. This allows you to arrange the selections next to each other on the same screen. To modify the views of the D-Cube: With the D-Cube open, click on D-CubeSelections: New Slice: This option allows you to create a new view of the same D-Cube, with the same selection. Reselect: Modify the current selection. Selecting this option allows you to add or remove dimensions in the current view. Save: Save the current selection as a saved selection. This option allows you to save the current view so that you can open it again later. If you select Reselect, move the items that you want to add to or remove from the current view from the Items included to the Items available pane, or vice versa, respectively. Click on OK. Saving a selection You can select a view of a D-Cube and then save this selection so that you do not have to reselect the same view the next time that you open the cube. When you save a selection, you create a "saved selection"—an object that is derived from the cube. To save a selection: Click File | Open | D-Cube. Select the D-Cube. Under Mode, select Edit Selection. Select the D-List items that you want to view in the D-Cube, and move them from the Items available pane to the Items included pane. If you do not select anything in the Items available pane, then all of the items will be included in the selection, including any future additions to the D-List. Under the Save Selections option on the lower-right corner of the dialog box, click on the Save button. Enter the name of the saved selection. Click on OK. If you have a saved selection, you can load it into the item selection box. The dimension item selection box is used in many functions, including export, D-List imports, and D-Cube allocations (to be discussed later). Opening the saved selection Once saved, the selection becomes a separate object that can be copied and shared. However, because it is a subset of the cube, you have to go through the cube to access the saved selection. To open the saved selection: Click on File | Open | D-Cube. Select the D-Cube. Under Mode, select Saved Selection. Select the Saved Selection. Click on OK    
Read more
  • 0
  • 0
  • 2375
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 ₹800/month. Cancel anytime
article-image-jbi-binding-components-netbeans-ide-6
Packt
16 Oct 2009
4 min read
Save for later

JBI Binding Components in NetBeans IDE 6

Packt
16 Oct 2009
4 min read
Binding Components Service Engines are pluggable components which connect to the Normalized Message Router (NMR) to perform business logic for clients. Binding components are also standard JSR 208 components that plug in to NMR and provide transport independence to NMR and Service Engines. The role of binding components is to isolate communication protocols from JBI container so that Service Engines are completely decoupled from the communication infrastructure. For example, BPEL Service Engine can receive requests to initiate BPEL process while reading files on the local file system. It can receive these requests from SOAP messages, from a JMS message, or from any of the other binding components installed into JBI container. Binding Component is a JSR 208 component that provides protocol independent transport services to other JBI components. The following figure shows how binding components fit into the JBI Container architecture: In this figure, we can see that the role of BC is to send and receive messages both internally and externally from Normalized Message Router using protocols, specific to the binding component. We can also see that any number of binding components can be installed into the JBI container. This figure shows that like Service Engines (SE), binding components do not communicate directly with other binding components or with Service Engines. All communication between individual binding components and between binding components and Service Engines is performed via sending standard messages through the Normalized Message Router. NetBeans Support for Binding Components The following table lists which binding components are installed into the JBI container with NetBeans 5.5 and NetBeans 6.0:   As is the case with Service Engines, binding components can be managed within the NetBeans IDE. The list of Binding Components installed into the JBI container can be displayed by expanding the Servers | Sun Java System Application Server 9 | JBI | Binding Components node within the Services explorer. The lifecycle of binding components can be managed by right-clicking on a binding component and selecting a lifecycle process—Start, Stop, Shutdown, or Uninstall. The properties of an individual binding component can also be obtained by selecting the Properties menu option from the context menu as shown in the following figure. Now that we've discussed what binding components are, and how they communicate both internally and externally to the Normalized Message Router, let's take a closer look at some of the more common binding components and how they are accessed and managed from within the NetBeans IDE. File Binding Component The file binding component provides a communications mechanism for JBI components to interact with the file system. It can act as both a Provider by checking for new files to process, or as a Consumer by outputting files for other processes or components. The figure above shows the file binding component acting as a Provider of messages. In this scenario, a message has been sent to the JBI container, and picked up by a protocol-specific binding component (for example, a SOAP message has been received). A JBI Process then occurs within the JBI container which may include routing the message between many different binding components and Service Engines depending upon the process. Finally, after the JBI Process has completed, the results of the process are sent to File Binding Component which writes out the result to a file. The figure above shows the file binding component acting as a Consumer of messages. In this situation, the File Binding Component is periodically polling the file system looking for files with a specified filename pattern in a specified directory. When the binding component finds a file that matches its criteria, it reads in the file and starts the JBI Process, which may again cause the input message to be routed between many different binding components and Service Engines. Finally, in this example, the results of the JBI Process are output via a Binding Component. Of course, it is possible that a binding component can act as both a provider and a consumer within the same JBI process. In this case, the file binding component would be initially responsible for reading an input message from the file system. After any JBI processing has occurred, the file binding component would then write out the results of the process to a file. Within the NetBeans Enterprise Pack, the entire set of properties for the file binding component can be edited within the Properties window. The properties for the binding component are displayed when either the input or output messages are selected from the WSDL in a composite application as shown in the following figure.
Read more
  • 0
  • 0
  • 1826

article-image-soa-java-business-integration-part-1
Packt
16 Oct 2009
5 min read
Save for later

SOA with Java Business Integration (part 1)

Packt
16 Oct 2009
5 min read
SOA—The Motto We have been doing integration for many decades in proprietary or ad-hoc manner. Today, the buzz word is SOA and in the integration space, we are talking about Service Oriented Integration (SOI). Let us look into the essentials of SOA and see whether the existing standards and APIs are sufficient in the integration space. Why We Need SOA We have been using multiple technologies for developing application components, and a few of them are listed as follows: Remote Procedure Call (RPC) Common Object Request Broker Architecture (CORBA) Distributed Component Object Model (DCOM) .NET remoting Enterprise Java Beans (EJBs) Java Remote Method Invocation (RMI) One drawback, which can be seen in almost all these technologies, is their inability to interoperate. In other words, if a .NET remoting component has to send bytes to a Java RMI component, there are workarounds that may not work all the times. Next, all the above listed technologies follow the best Object Oriented Principles (OOP), especially hiding the implementation details behind interfaces. This will provide loose coupling between the provider and the consumer, which is very important especially in distributed computing environments. Now the question is, are these interfaces abstract enough? To rephrase the question, can a Java RMI runtime make sense out of a .NET interface? Along these lines, we can point out a full list of doubts or deficiencies which exist in today's computing environment. This is where SOA brings new promises. What is SOA SOA is all about a set of architectural patterns, principles, and best practices to implement software components in such a way that we overcome much of the deficiencies identified in traditional programming paradigms. SOA speaks about services implemented based on abstract interfaces where only the abstract interface is exposed to the outside world. Hence the consumers are unaware of any implementation details. Moreover, the abstract model is neutral of any platform or technology. This means, components or services implemented in any platform or technology can interoperate. We will list out few more features of SOA here: Standards-based (WS-* Specifications) Services are autonomous and coarse grained Providers and consumers are loosely coupled The list is not exhaustive, but we have many number of literature available speaking on SOA, so let us not repeat it here. Instead we will see the importance of SOA in the integration context. SOA and Web Services SOA doesn't mandate any specific platform, technology, or even a specific method of software engineering, but time has proven that web service is a viable technology to implement SOA. However, we need to be cautious in that using web services doesn't lead to SOA by itself, or implement it. Rather, since web services are based on industry accepted standards like WSDL, SOAP, and XML; it is one of the best available means to attain SOA. Providers and consumers agree to a common interface called Web Services Description Language (WSDL) in SOA using web services. Data is exchanged normally through HTTP protocol, in Simple Object Access Protocol (SOAP) format. WSDL WSDL is the language of web services, used to specify the service contract to be agreed upon by the provider and consumer. It is a XML formatted information, mainly intended to be machine processable (but human readable too, since it is XML). When we host a web service, it is normal to retrieve the WSDL from the web service endpoint. Also, there are mainly two approaches in working with WSDL, which are listed as follows: Start from WSDL, create and host the web service and open the service for clients; tools like wsdl2java help us to do this. Start from the types already available, generate the WSDL and then continue; tools like java2wsdl help us here. Let us now quickly run through the main sections within a WSDL. A WSDL structure is as shown here: <?xml version="1.0" encoding="UTF-8"?><wsdl:definitions targetNamespace= "http://versionXYZ.ws.servicemix.esb.binildas.com" …> <wsdl:types> <schema elementFormDefault="qualified" targetNamespace="http://version20061231.ws. servicemix.esb.binildas.com" > </schema> </wsdl:types> <wsdl:message name="helloResponse"> <!-- other code goes here --> </wsdl:message> <wsdl:portType name="IHelloWeb"> <!-- other code goes here --> </wsdl:portType> <wsdl:binding name="HelloWebService20061231SoapBinding" type="impl:IHelloWeb"> <!-- other code goes here --> </wsdl:binding> <wsdl:service name="IHelloWebService"> <wsdl:port binding="impl:HelloWebService20061231SoapBinding" name="HelloWebService20061231"> <wsdlsoap:address location="http://localhost:8080/AxisEndToEnd20061231/ services/HelloWebService20061231"/> </wsdl:port> </wsdl:service></wsdl:definitions> We will now run through the main sections of a typical WSDL: types: The data types exchanged are expressed here as an XML schema. message: This section details about the message formats (or the documents) exchanged. portType: The PortType can be looked at as the abstract interface definition for the exposed service. binding: The PortType has to be mapped to specific data formats and protocols, which will be detailed out in the binding section. port: The port gives the URL representation of the service endpoint. service: Service can contain a collection of port elements. Since JBI is based on WSDL, we can deal with many WSDL instances.    
Read more
  • 0
  • 0
  • 1711

article-image-creating-matrix-report-using-analysis-services-cube
Packt
16 Oct 2009
4 min read
Save for later

Creating a matrix report using the Analysis Services Cube

Packt
16 Oct 2009
4 min read
Reviewing Jayaram's other OLAP related articles may greatly help in understanding this article. Creating the CUBE will be essential to work with this hands-on. If you are already experienced and have an appropriate CUBE to work with you may directly go to the section on deriving a dataset. The CUBE used in this hands-on is a simple one. It does not even have a "Time" dimension although Microsoft in Visual Studio gives a warning that you should have one. However for the purposes of demonstration and doing the hands-on a CUBE without the "Time" dimension should be adequate. The two previous articles on creating a CUBE provide the necessary background for this article. Create a data source with a CUBE Create an Analysis Services Cube (herein called MyNwind.cube) using the TestNorthwind as the database. The Measures and Dimensions for this cube are as shown in the next figure. Start your Report Builder 2.0. Make sure you have started the reporting services using the Reporting Services Configuration Manager. In Report Builder 2.0 click on New | Data source... under Report Data. Provide the following information: Name: SrcCubeSelect connection type: Microsoft SQL Server Analysis ServicesConnection String: Data Source=Hodentek2SANGAM; Initial Catalog=NwindRTM Herein NwindRTM is the name of the Datasource in the Analysis Server. (Alternately you may build this source as shown). Click OK on the Data Source Properties window. Add a dataset to the report Right click on SrcCube and choose Add DataSet... In the Dataset Properties window make the following changes: Name: QryCubeData source: SrcCubeQuery Type: text Click on Query Designer... button. At first you will see only the Metadata of the cube displayed as in the left side of the next figure. Expand Customers, Orders, and Products in the dimensions and drop them on the list header in the bottom pane on the right hand side of the next figure. Drag and drop Freight from Orders under Measures as shown. For each of the dimensions using an operator create a filter expression as shown. For example, the Products included in the query range from Product IDs 3 to 9; the Customer ID (some specific ones are chosen), similarly theCategory ID (only those with ID's 2, 3, 4, and 5 are included in the query). The design of the query with these filtering choices is as shown in the previous figure. The filtering tool is very flexible and all the items namely Dimension, Hierarchy, Operator and Filter Expression can be designed in this interface using either drop-down pick lists choices or drop-downs with checkboxes as shown here. Run the query by clicking on the toolbar item (!) and review the results. Click OK on the Query Designer. The Dataset Properties window shows up with this query designed according to your choices in the query item window as shown. Close the Dataset Properties window. Report Design In Report Builder 2.0 click on New Table or Matrix wizard. In the Choose a dataset window accept the default and click Next. Drag and drop Customer_ID in the Row Groups drop area. Drag and drop Order_ID below Customer_ID in the Row Groups drop area. Drag and drop Product_ID in the Column Groups drop area. Drag and drop Freight into the Values drop area and click on Next. In the Choose the layout window accept Expand/collapse groups and choose the option Stepped, subtotal above. Click Next and choose some style (herein Ocean) and click Finish. The final report design is as shown here. Click Home | Run. The report gets displayed after processing as shown here. The orders from a particular customer have been expended in this view. Summary Report Builder 2.0 can used to author reports based on Analysis Services Cubes. The interface is very flexible and the Query Designer is very easy to use as shown in this article. If you have read this article you may be interested to view : Creating an Analysis Services Cube with Visual Studio 2008 - Part 1 Creating an Analysis Services Cube with Visual Studio 2008 - Part 2
Read more
  • 0
  • 0
  • 3698

article-image-windows-development-using-visual-studio-2008
Packt
16 Oct 2009
11 min read
Save for later

Windows Development Using Visual Studio 2008

Packt
16 Oct 2009
11 min read
Visual Studio Visual Studio is an environment for developing applications in Windows. It has a number of tools, such as an editor, compilers, linkers, a debugger, and a project manager. It also has several Wizards—tools designed for rapid development. The Wizard you will first encounter is the Application Wizard. It generates code for an Application Framework. The idea is that we use the Application Wizard to design a skeleton application that is later completed with more application-specific code. There is no real magic about wizards, all they do is generate the skeleton code. We could write the code ourselves, but it is a rather tedious job. Moreover, an application can be run in either debug or release mode. In debug mode, additional information is added in order to allow debugging; in release mode, all such information is omitted in order to make the execution as fast as possible. The code of this article is developed with Visual Studio 2008. The Windows 32 bits Application Programming Interface (Win32 API) is a huge C function library. It contains a couple of thousand functions for managing the Windows system. With the help of Win32 API it is possible to totally control the Windows operating system. However, as the library is written in C, it could be a rather tedious job to develop a large application, even though it is quite possible. That is the main reason for the existence of the Microsoft Foundation Classes (MFC). It is a large C++ class library containing many classes encapsulating the functionality of Win32 API. It does also hold some generic classes to handle lists, maps, and arrays. MFC combines the power of Win32 API with the advantages of C++. However, on some occasions MFC is not enough. When that happens, we can simply call an appropriable Win32 API function, even though the application is written in C++ and uses MFC. Most of the classes of MFC belong to a class hierarchy with CObject at the top. On some occasions, we have to let our classes inherit CObject in order to achieve some special functionality. The baseclass Figure in the Draw and Tetris applications inherits CObject in order to read or write objects of unknown classes. The methods UpdateAllViews and OnUpdate communicate by sending pointers to CObject objects. The Windows main class is CWnd. In this environment, there is no function main. Actually, there is a main, but it is embedded in the framework. We do not write our own main function, and there is not one generated by the Application Wizard. Instead, there is the object theApp, which is an instance of the application class. The application is launched by its constructor. When the first version of MFC was released, there was no standard logical type in C++. Therefore, the type BOOL with the values TRUE and FALSE was introduced. After that, the type bool was introduced to C++. We must use BOOL when dealing with MFC method calls, and we could use bool otherwise. However, in order to keep things simple, let us use BOOL everywhere. In the same way, there is a MFC class CString that we must use when calling MFC methods. We could use the C++ built-in class string otherwise. However, let us use CString everywhere. The two classes are more or less equivalent. There are two types for storing a character, char and wchar_t. In earlier version of Windows, you were supposed to use char for handling text, and in more modern versions you use wchar_t. In order to make our application independent of which version it is run on, there are two macros TCHAR and TEXT. TCHAR is the character type that replaces char and wchar_t. TEXT is intended to encapsulate character and string constants. TCHAR *pBuffer;stScore.Format(TEXT("Score: %d."), iScore); There is also the MFC type BYTE which holds a value of the size of one byte, and UINT which is shorthand for unsigned integer. Finally, all generated framework classes have a capital C at the beginning of the name. The classes we write ourselves do not. The Document/View model The applications in this article are based on the Document/View model. Its main idea is to have two classes with different responsibilities. Let us say we name the application Demo, the Application Wizard will name the document class CDemoDoc and the view class will be named CDemoView. The view class has two responsibilities: to accept input from the user by the keyboard or the mouse, and to repaint the client area (partly or completely) at the request of the document class or the system. The document's responsibility is mainly to manage and modify the application data. The model comes in two forms: Single Document Interface (SDI) and Multiple Document Interface (MDI). When the application starts, a document object and a view object are created, and connected to each other. In the SDI, it will continue that way. In the MDI form, the users can then add or remove as many views they want to. There is always exactly one document object, but there may be one or more view objects, or no one at all. The objects are connected to each other by pointers. The document object has a list of pointers to the associated view objects. Each view object has a fieldm_pDocument that points at the document object. When a change in the document's data has occurred, the document instructs all of its views to repaint their client area by calling the method UpdateAllViews in order to reflect the change. The message system Windows is built on messages. When the users press one of the mouse buttons or a key, when they resize a window, or when they select a menu item, a message is generated and sent to the current appropriate class. The messages are routed by a message map. The map is generated by the Application Wizard. It can be modified manually or with the Properties Window View (the Messages or Events button). The message map is declared in the file class' header file as follows: DECLARE_MESSAGE_MAP() The message map is implemented in the class' implementation file as follows: BEGIN_MESSAGE_MAP(this_class, base_class)// Message handlers.END_MESSAGE_MAP() Each message has it own handle, and is connected to a method of a specific form that catches the message. There are different handlers for different types of messages. There are around 200 messages in Windows. Here follows a table with the most common ones. Note that we do not have to catch every message. We just catch those we are interested in, the rest will be handled by the framework. Message Handler/Method Sent WM_CREATE ON_WM_CREATE/OnCreate When the window is created, but not yet showed. WM_SIZE ON_WM_SIZE/OnSize When the window has been resized. WM_MOVE ON_WM_MOVE/OnMove When the window has been moved. WM_SETFOCUS ON_WM_SETFOCUS/ OnSetFocus When the window receives input focus. WM_KILLFOCUS ON_WM_KILLFOCUS/ OnKillFocus When the window loses input focus. WM_VSCROLL ON_WM_VSCROLL/ OnVScroll When the user scrolls the vertical bar. WM_HSCROLL ON_WM_HSCROLL/ OnHScroll When the user scrolls the horizontal bar. WM_LBUTTONDOWN   WM_MBUTTONDOWN   WM_RBUTTONDOWN ON_WM_LBUTTONDOWN/ OnLButtonDown ON_WM_MBUTTONDOWN/ OnMButtonDown ON_WM_RBUTTONDOWN/ OnRButtonDown When the user presses the left, middle, or right mouse button. WM_MOUSEMOVE ON_WM_MOUSEMOVE/ OnMouseMove When the user moves the mouse, there are flags available to decide whether the buttons are pressed. WM_LBUTTONUP   WM_MBUTTONUP   WM_RBUTTONUP ON_WM_LBUTTONUP/ OnLButtonUp ON_WM_MUTTONUP/ OnMButtonUp ON_WM_RUTTONUP/ OnRButtonUp When the user releases the left, middle, or right button. WM_CHAR ON_WM_CHAR/OnChar When the user inputs a writable character of the keyboard. WM_KEYDOWN ON_WM_KEYDOWN/ OnKeyDown When the user presses a key of the keyboard. WM_KEYUP ON_WM_KEYUP/ OnKeyUp When the user releases a key of the keyboard. WM_PAINT ON_WM_PAINT/OnPaint When the client area of the window needs to be repainted, partly or completely. WM_CLOSE ON_WM_CLOSE/OnClose When the user clicks at the close button in the upper right corner of the window. WM_DESTROY ON_WM_DESTROY/ OnDestroy When the window is to be closed. WM_COMMAND ON_COMMAND(Identifier, Name)/OnName   When the user selects a menu item, a toolbar button, or a accelerator key connected to the identifier. WM_COMMAND_ UPDATE ON_COMMAND_ UPDATE_UI(Identifier, Name)/OnUpdateName On idle time, when the system is not busy with any other task, this message is sent in order to enable/disable or to check menu items and toolbar buttons. When a user selects a menu item, a command message is sent to the application. Thanks to MFC, the message can be routed to virtually any class in the application. However, in the applications of this article, all menu messages are routed to the document class. It is possible to connect an accelerator key or a toolbar button to the same message, simply by giving it the same identity number. Moreover, when the system is in idle mode (not busy with any other task) thecommand update message is sent to the application. This gives us an opportunity to check or disable some of the menu items. For instance, the Save item in the File menu should be grayed (disabled) when the document has not been modified and does not have to be saved. Say that we have a program where the users can paint in one of three colors. The current color should be marked by a radio box. The message map and its methods can be written manually or be generated with the Resource View (the View menu in Visual Studio) which can help us generate the method prototype, its skeleton definition, and its entry in the message map. The Resource is a system of graphical objects that are linked to the application. When the framework is created by the Application Wizard, the standard menu bar and toolbar are included. We can add our own menus and buttons in Resource Editor, a graphical tool of Visual Studio. The coordinate system In Windows, there are device (physical) and logical coordinates. There are several logical coordinate mapping systems in Windows. The simplest one is the text system; it simply maps one physical unit to the size of a pixel, which means that graphical figures will have different size monitors with different sizes or resolutions. This system is used in the Ring and Tetris applications. The metric system maps one physical unit to a tenth of a millimeter (low metric) or a hundredth of a millimeter (high metric). There is also the British system that maps one physical unit to a hundredth of an inch (low English) or a thousandth of an inch (high English). The British system is not used in this article. The position of a mouse click is always given in device units. When a part of the client area is invalidated (marked for repainting), the coordinates are also given in device units, and when we create or locate the caret, we use device coordinates. Except for these events, we translate the positions into logical units of our choice. We do not have to write translation routines ourselves, there are device context methods LPtoDP (Logical Point to Device Point) and DPtoLP (Device Point to Logical Point) in the next section that do the job for us. The setting of the logical unit system is done in OnInitialUpdate and OnPrepareDC in the view classes. In the Ring and Tetris Applications, we just ignore the coordinates system and use pixels. In the Draw application, the view class is a subclass of the MFC class CScrollView. It has a method SetScrollSizes that takes the logical coordinate system and the total size of the client area (in logical units). Then the mapping between the device and logical system is done automatically and the scroll bars are set to appropriate values when the view is created and each time its size is changed. void SetScrollSizes(int nMapMode, CSize sizeTotal, const CSize& sizePage = sizeDefault, const CSize& sizeLine = sizeDefault); In the Calc and Word Applications, however, we set the mapping between the device and logical system manually by overriding the OnPrepareDC method. It calls the method SetMapMode which sets the logical horizontal and vertical units to be equal. This ensures that circles will be kept round. The MFC device context method GetDeviceCaps returns the size of the screen in pixels and millimeters. Those values are used in the call to SetWindowExt and SetViewportExt, so that the logical unit is one hundredth of a millimeter also in those applications. The SetWindowOrg method sets the origin of the view's client area in relation to the current positions of the scroll bars, which implies that we can draw figures and text without regarding the current positions of the scroll bars. int SetMapMode(int iMapMode);int GetDeviceCaps(int iIndex) const;CSize SetWindowExt(CSize szScreen);CSize SetViewportExt(CSize szScreen);CPoint SetWindowOrg(CPoint ptorigin);
Read more
  • 0
  • 0
  • 1876
article-image-jquery-ui-accordion-widget-part-1
Packt
16 Oct 2009
9 min read
Save for later

jQuery UI Accordion Widget - Part 1

Packt
16 Oct 2009
9 min read
Accordion's structure Let's take a moment to familiarize ourselves with what an accordion is made of. Within the outer container is a series of links. These links are the headings within the accordion and each heading will have a corresponding content panel, or drawer as they are sometimes referred to, which opens when the heading is clicked. The following screenshot shows these elements as they may appear in an accordion: It's worth remembering that when using the accordion widget, only one content panel can be open at any one time. Let's implement a basic accordion now. In a blank page in your text editor, create the following page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Accordion Widget Example 1</title> </head> <body> <ul id="myAccordion"> <li> <a href="#">Header 1</a> <div>Wow, look at all this content that can be shown or hidden with a simple click!</div> </li> <li> <a href="#">Header 2</a> <div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpatligula. 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. </div> </li> <li> <a href="#">Header 3</a> <div>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> </li> </ul> <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.accordion.js"></script> <script type="text/javascript"> //function to execute when doc ready $(function() { //turn specified element into an accordion $("#myAccordion").accordion(); }); </script> </body></html> Save the file as accordion1.html in your jqueryui folder and try it out in a browser. We haven't specified any styling at all at this stage, but as you can see from the following screenshot, it still functions exactly as intended: Little code is required for a basic working version of the accordion widget. A simple unordered list element is the mark-up foundation which is transformed by the library into the accordion object. The following three separate external script files are required for an accordion: The jQuery library itself (jquery-1.2.6.js) The UI base file (ui.core.js) The accordion source file (ui.accordion.js) The first two files are mandatory requirements of all components of the UI library. They should be linked to in the order shown here. Each widget also has its own source file, and may depend on other components as well. The order in which these files appear is important. The jQuery library must always appear first, followed by the UI base file. After these files, any other files that the widget depends upon should appear before the widget's own script file. The library components will not function as expected if files are not loaded in the correct order. Finally, we use a custom <script> block to turn our <ul> element into the accordion. We can use the jQuery object shortcut $ to specify an anonymous function which will be executed as soon as the document is ready. This is analogous to using $(document).ready(function(){}) and helps to cut down on the amount of code we have to type. Following this, we use the simple ID selector $("#myAccordion") to specify the element on the page we want to transform. We then use the accordion() constructor method to create the accordion Other elements can be turned into accordions as well. All list element variants are supported including ordered lists and definition lists. You don't even need to base the accordion on a list element at all. You can build a perfectly functional accordion using just nested <div> and <a> elements, although additional configuration will be required In the above example, we used an empty fragment (#) as the value of the href attribute. You should note that any URLs supplied for accordion headers will not be followed when the header is clicked within the accordion when using the default implementation. Styling the accordion With no styling, the accordion will take up 100% of the width of its container. Like with other widgets, we have several options for styling the accordion. We can create our own custom stylesheet to control the appearance of the accordion and its content, we can use the default or flora themes that come with the library, or we can use Theme Roller to create an extensive skin for the whole library. Let's see how using the flora theme for the accordion will cause it to render. In accordion1.html, add the following <link> tag to the <head> of the page: <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.accordion.css"> Save the new file as accordion2.html, also in the jqueryui folder, and view it again in a browser. It should appear something like this: The accordion theme file assumes that an unordered list is being used as the basis of the widget and specifically targets <li> elements with certain style rules. We can easily create our own custom theme to style the accordion for situations where we want to use a non-list-based accordion widget, or if we simply want different colors or font styles. You can use the excellent Firebug plugin for Firefox, or another DOM viewer, to see the class names that are automatically added to certain elements when the accordion is generated. You can also read through an un-minified version of the source file if you really feel like it. These will be the class names that we'll be targeting with our custom CSS. The following screenshot shows Firebug in action: Change accordion2.html so that it appears as follows (new code is shown in bold): <!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="styles/accordionTheme.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Accordion Widget Example 3</title> </head> <body> <div id="myAccordion"> <span class="corner topLeft"></span><span class="corner topRight"></span><span class="corner bottomLeft"></span><span class="corner bottomRight"></span> <div><a href="#">Header 1</a><div>Wow, look at all this content that can be shown or hidden with a simple click!</div></div> <div><a href="#">Header 2</a><div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpatligula. 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.</div></div> <div><a href="#">Header 3</a><div>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></div> </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.accordion.js"></script> <script type="text/javascript"> //function to execute when doc ready $(function() { //turn specified element into an accordion $("#myAccordion").accordion(); }); </script> </body></html> Save this version as accordion3.html in the jqueryui folder. The class name ui-accordion is automatically added to the accordion's container element. Therefore, we can use this as a starting point for most of our CSS selectors. The links that form our drawer headers are given the class ui-accordion-header so we can also target this class name. In a new file, create the following stylesheet: #myAccordion { width:200px; border:2px solid #000000; position:relative; list-style-type:none; padding-left:0;}.ui-accordion-header { text-decoration:none; font-weight:bold; color:#000000; display:block; width:100%; text-align:center;}.ui-accordion div div { font-size:90%;}.ui-accordion a { color:#ffffff; background:url(../img/accordion/header-sprite.gif) repeat-x 0px 0px;}.ui-accordion a.selected { background:url(../img/accordion/header-sprite.gif) repeat-x 0px -22px;}.ui-accordion a:hover { background:url(../img/accordion/header-sprite.gif) repeat-x 0px -44px;}/* container rounded corners */.corner { position:absolute; width:12px; height:13px; background:url(../img/accordion/corner-sprite.gif) no-repeat;}.topLeft { top:-2px; left:-2px; background-position:0px 0px;}.topRight { top:-2px; right:-2px; background-position:0px -13px;}.bottomRight { bottom:-2px; right:-2px; background-position:0px -26px;}.bottomLeft { bottom:-2px; left:-2px; background-position:0px -39px;} Save this file as accordionTheme.css in your styles folder and preview accordion3.html in a browser. We will need a new folder for the images we use in this and subsequent examples. Create a new folder inside the img folder and name it accordion. With just two images, and a few simple style rules, we can drastically change the default appearance of the accordion with our own custom skin as shown in the following screenshot: Configuring accordion The accordion has a range of configurable properties which allow us to easily change the default behaviour of the widget. The following table lists the available properties, their default value, and gives a brief description of their usage:
Read more
  • 0
  • 0
  • 4496

article-image-java-data-objects-and-service-data-objects-soa
Packt
16 Oct 2009
11 min read
Save for later

Java Data Objects and Service Data Objects in SOA

Packt
16 Oct 2009
11 min read
JDO Java Data Objects (JDO) is a complementing standard of accessing data from your data store using a standard interface-based abstraction model of persistence in java. The original JDO (JDO 1.0) specification is quite old and is based on Java Specification Request 12 (JSR 12). The current major version of JDO (JDO 2.0) is based on JSR 243. The original specifications were done under the supervision of Sun and starting from 2.0, the development of the API and the reference implementation happens as an Apache open-source project. Why JDO? We have been happily programming to retrieve data from relational stores using JDBC, and now the big question is do we need yet another standard, JDO? If you think that as software programmers you need to provide solutions to your business problems, it makes sense for you to start with the business use cases and then do a business analysis at the end of which you will come out with a Business Domain Object Model (BDOM). The BDOM will drive the design of your entity classes, which are to be persisted to a suitable data store. Once you design your entity classes and their relationship, the next question is should you be writing code to create tables, and persist or query data from these tables (or data stores, if there are no tables). I would like to answer 'No' for this question, since the more code you write, the more are the chances of making errors, and further, developer time is costly. Moreover, today you may write JDBC for doing the above mentioned "technical functionalities", and tomorrow you may want to change all your JDBC to some other standard since you want to port your data from a relational store to a different persistence mechanism. To sum up, let us list down a few of the features of JDO which distinguishes itself from other similar frameworks. Separation of Concerns: Application developers can focus on the BDOM and leave the persistence details (storage and retrieval) to the JDO implementation. API-based: JDO is based on a java interface-based programming model. Hence all persistence behavior including most commonly used features of OR mapping is available as metadata, external to your BDOM source code. We can also Plug and Play (PnP) multiple JDO implementations, which know how to interact well with the underlying data store. Data store portability: Irrespective of whether the persistent store is a relational or object-based file, or just an XML DB or a flat file, JDO implementations can still support the code. Hence, JDO applications are independent of the underlying database. Performance: A specific JDO implementation knows how to interact better with its specific data store, which will improve performance as compared to developer written code. J2EE integration: JDO applications can take advantage of J2EE features like EJB and thus the enterprise features such as remote message processing, automatic distributed transaction coordination, security, and so on. JPOX—Java Persistent Objects JPOX is an Apache open-source project, which aims at a heterogeneous persistence solution for Java using JDO. By heterogeneous we mean, JPOX JDO will support any combination of the following four main aspects of persistence: Persistence Definition: The mechanism of defining how your BDOM classes are to be persisted to the data store. Persistence API: The programming API used to persist your BDOM objects. Query Language: The language used to find objects due to certain criteria. Data store: The underlying persistent store you are persisting your objects to. JDO Sample Using JPOX In this sample, we will take the familiar Order and LineItems scenario, and expand it to have a JDO implementation. It is assumed that you have already downloaded and extracted the JPOX libraries to your local hard drive. BDOM for the Sample We will limit our BDOM for the sample discussion to just two entity classes, that is, OrderList and LineItem. The class attributes and relationships are shown in the following screenshot: The BDOM illustrates that an Order can contain multiple line items. Conversely, each line item is related to one and only one Order. Code BDOM Entities for JDO The BDOM classes are simple entity classes with getter and setter methods for each attribute. These classes are then required to be wired for JDO persistence capability in a JDO specific configuration file, which is completely external to the core entity classes. OrderList.java OrderList is the class representing the Order, and is having a primary key attribute that is number. public class OrderList{ private int number; private Date orderDate; private Set lineItems; // other getter & setter methods go here // Inner class for composite PK public static class Oid implements Serializable{ public int number; public Oid(){ } public Oid(int param){ this.number = param; } public String toString(){ return String.valueOf(number); } public int hashCode(){ return number; } public boolean equals(Object other){ if (other != null && (other instanceof Oid)){ Oid k = (Oid)other; return k.number == this.number; } return false; } } } LineItem.java LineItem represents each item container in the Order. We don't explicitly define a primary key for LineItem even though JDO will have its own mechanism to do that. public class LineItem{ private String productId; private int numberOfItems; private OrderList orderList; // other getter & setter methods go here } package.jdo JDO requires an XML configuration file, which defines the fields that are to be persisted and to what JDBC or JDO wrapper constructs should be mapped to. For this, we can create an XML file called package.jdo with the following content and put it in the same directory where we have the entities. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jdo SYSTEM "file:/javax/jdo/jdo.dtd"> <jdo> <package name="com.binildas.jdo.jpox.order"> <class name="OrderList" identity-type="application" objectid-class="OrderList$Oid" table="ORDERLIST"> <field name="number" primary-key="true"> <column name="ORDERLIST_ID"/> </field> <field name="orderDate"> <column name="ORDER_DATE"/> </field> <field name="lineItems" persistence-modifier="persistent" mapped-by="orderList"> <collection element-type="LineItem"> </collection> </field> </class> <class name="LineItem" table="LINEITEM"> <field name="productId"> <column name="PRODUCT_ID"/> </field> <field name="numberOfItems"> <column name="NUMBER_OF_ITEMS"/> </field> <field name="orderList" persistence-modifier="persistent"> <column name="LINEITEM_ORDERLIST_ID"/> </field> </class> </package> </jdo> jpox.PROPERTIES In this sample, we will persist our entities to a relational database, Oracle. We specify the main connection parameters in jpox.PROPERTIES file. javax.jdo.PersistenceManagerFactoryClass=org.jpox.jdo.JDOPersistenceManagerFactory javax.jdo.option.ConnectionDriverName=oracle.jdbc.driver.OracleDriver javax.jdo.option.ConnectionURL=jdbc:oracle:thin:@127.0.0.1:1521:orcl javax.jdo.option.ConnectionUserName=scott javax.jdo.option.ConnectionPassword=tiger org.jpox.autoCreateSchema=true org.jpox.validateTables=false org.jpox.validateConstraints=false Main.java This class contains the code to test the JDO functionalities. As shown here, it creates two Orders and adds few line items to each order. First it persists these entities and then queries back these entities using the id. public class Main{ static public void main(String[] args){ Properties props = new Properties(); try{ props.load(new FileInputStream("jpox.properties")); } catch (Exception e){ e.printStackTrace(); } PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props); PersistenceManager pm = pmf.getPersistenceManager(); Transaction tx = pm.currentTransaction(); Object id = null; try{ tx.begin(); LineItem lineItem1 = new LineItem("CD011", 1); LineItem lineItem2 = new LineItem("CD022", 2); OrderList orderList = new OrderList(1, new Date()); orderList.getLineItems().add(lineItem1); orderList.getLineItems().add(lineItem2); LineItem lineItem3 = new LineItem("CD033", 3); LineItem lineItem4 = new LineItem("CD044", 4); OrderList orderList2 = new OrderList(2, new Date()); orderList2.getLineItems().add(lineItem3); orderList2.getLineItems().add(lineItem4); pm.makePersistent(orderList); id = pm.getObjectId(orderList); System.out.println("Persisted id : "+ id); pm.makePersistent(orderList2); id = pm.getObjectId(orderList2); System.out.println("Persisted id : "+ id); orderList = (OrderList) pm.getObjectById(id); System.out.println("Retreived orderList : " + orderList); tx.commit(); } catch (Exception e){ e.printStackTrace(); if (tx.isActive()){ tx.rollback(); } } finally{ pm.close(); } } } Build and Run the JDO Sample You can download the required code for this article from http://www.packtpub.com/files//code/3216_Code.zip. Unzip the file and the code of our interest is in the folder 3216_04_Code. There is also a README.txt file, which gives detailed steps to build and run the samples. Since we use Oracle to persist entities, we need the following two libraries in the classpath: jpox-rdbms*.jar classes12.jar We require a couple of other libraries too which are specified in the build.xml file. Download these libraries and change the path in examples.PROPERTIES accordingly. To build the sample, first bring up your database server. Then to build the sample in a single command, it is easy for you to go to ch04jdo folder and execute the following command. cd ch04jdo ant The above command will execute the following steps: First it compiles the java source files Then for every class you persist, use JPOX libraries to enhance the byte code. As the last step, we create the required schema in the data store. To run the sample, execute: ant run You can now cross check whether the entities are persisted to your data store. This is as shown in the following screenshot where you can see that each line item is related to the parent order by the foreign key.   Data Services Good that you now know how to manage the basic data operations in a generic way using JDO and other techniques. By now, you also have good hands-on experience in defining and deploying web services. We all appreciate that web services are functionalities exposed in standard, platform, and technology neutral way. When we say functionality we mean the business use cases translated in the form of useful information. Information is always processed out of data. So, once we retrieve data, we need to process it to translate them into information. When we define SOA strategies at an enterprise level, we deal with multiple Line of Business (LOB) systems; some of them will be dealing with the same kind of business entity. For example, a customer entity is required for a CRM system as well as for a sales or marketing system. This necessitates a Common Data Model (CDM), which is often referred to as the Canonical Data Model or Information Model. In such a model, you will often have entities that represent "domain" concepts, for example, customer, account, address, order, and so on. So, multiple LOB systems will make use of these domain entities in different ways, seeking different information-based on the business context. OK, now we are in a position to introduce the next concept in SOA, which is "Data Services". Data Services are specialization of web services which are data and information oriented. They need to manage the traditional CRUD (Create, Read, Update, and Delete) operations as well as a few other data functionalities such as search and information modeling. The Create operation will give you back a unique ID whereas Read, Update, and Delete operations are performed on a specific unique ID. Search will usually be done with some form of search criteria and information modeling, or retrieval happens when we pull useful information out of the CDM, for example, retrieving the address for a customer. The next important thing is that no assumptions should be made that the data will be in a java resultset form or in a collection of transfer object form. Instead, you are now dealing with data in SOA context and it makes sense to visualize data in XML format. Hence, XML Schema Definition (XSDs) can be used to define the format of your requests and responses for each of these canonical data definitions. You may also want to use ad hoc queries using XQuery or XPath expressions, similar to SQL capabilities on relational data. In other words, your data retrieval and data recreation for information processing at your middle tier should support XML tools and mechanisms, and should also support the above six basic data operations. If so, higher level of abstractions in the processing tier can make use of the above data services to provide Application Specialization capabilities, specialized for the LOB systems. To make the concept clear, let us assume that we need to get the order status for a particular customer (getCustomerOrderStatus()) which will take the customer ID argument. The data services layer will have a retrieve operation passing the customer ID and the XQuery or the XPath statement will obtain the requested order information from the retrieved customer data. High level processing layers (such as LOB service tiers) can use high-level interface (for example, our getCustomerOrderStatus operation) of the Application Specialization using a web services (data services) interface and need not know or use XQuery or XPath directly. The underlying XQuery or XPath can be encapsulated, reused, and optimized.
Read more
  • 0
  • 0
  • 10035

article-image-find-closest-mashup-plugin-ruby-rails
Packt
16 Oct 2009
10 min read
Save for later

Find closest mashup plugin with Ruby on Rails

Packt
16 Oct 2009
10 min read
Building a kiosk locator feature for your site Your company has just deployed 500 multi-purpose payment kiosks around the country, cash cows for the milking. Another 500 more are on the way, promising to bring in the big bucks for all the hardworking employees in the company. Naturally your boss wants as many people as possible to know about them and use them. The problem is that while the marketing machine churns away on the marvels and benefits of the kiosks, the customers need to know where they are located to use them. He commands you: "Find a way to show our users where the nearest kiosks to him are, and directions to reach them!" What you have is a database of all the 500 locations where the kiosks are located, by their full address. What can you do? Requirements overview Quickly gathering your wits, you penned down the following quick requirements: Each customer who comes to your site needs to be able to find the closest kiosk to his or her current location. He or she might also want to know the closest kiosk to any location. You want to let the users determine the radius of the search. Finding the locations of the closest kiosks, you need to show him how to reach them. You have 500 kiosks now, (and you need to show where they are) but another 500 will be coming, in 10s and 20s, so the location of the kiosks need to be specified during the entry of the kiosks. You want to put all of these on some kind of map. Sounds difficult? Only if you didn't know about web mashups! Design The design for this first project is rather simple. We will build a simple database application using Rails and create a main Kiosk class in which to store the kiosk information including its address, longitude, and latitude information. After populating the database with the kiosk information and address, we will use a geolocation service to discover its longitude and latitude. We store the information in the same table. Next, we will take the kiosk information and mash it up with Google Maps and display the kiosks as pushpins on the online map and place its information inside an info box attached to each pushpin. Mashup APIs on the menu In this article we will be using the following services to create a 'find closest' mashup plugin: Google Maps APIs including geocoding services Yahoo geocoding services (part of Yahoo Maps APIs) Geocoder.us geocoding services Geocoder.ca geocoding services Hostip.info Google Maps Google Maps is a free web-based mapping service provided by Google. It provides a map that can be navigated by dragging the mouse across it and zoomed in and out using the mouse wheel or a zoom bar. It has three forms of views—map, satellite and a hybrid of map and satellite. Google Maps is coded almost entirely in JavaScript and XML and Google provides a free JavaScript API library that allows developers to integrate Google Maps into their own applications. Google Maps APIs also provide geocoding capabilities, that is, they able to convert addresses to longitude and latitude coordinates. We will be using two parts of Google Maps: Firstly to geocode addresses as part of GeoKit's APIs Secondly to display the found kiosk on a customized Google Maps map Yahoo Maps Yahoo Maps is a free mapping service provided by Yahoo. Much like Google Maps it also provides a map that is navigable in a similar way and also provides an extensive set of APIs. Yahoo's mapping APIs range from simply including the map directly from the Yahoo Maps website, to Flash APIs and JavaScript APIs. Yahoo Maps also provides geocoding services. We will be using Yahoo Maps geocoding services as part of GeoKit's API to geocode addresses. Geocoder.us Geocoder.us is a website that provides free geocoding of addresses and intersections in the United States. It relies on Geo::Coder::US, a Perl module available for download from the CPAN and derives its data from the TIGER/Line data set, public-domain data from the US Census Bureau. Its reliability is higher in urban areas but lower in the other parts of the country. We will be using Geocoder.us as part of GeoKit's API to geocode addresses. Geocoder.ca Geocoder.ca is a website that provides free geocoding of addresses in the United States and Canada. Like Geocoder.us. it uses data from TIGER/Line but in addition, draws data from GeoBase, the Canadian government-related initiative that provides geospatial information on Canadian territories. We will be using Geocoder.ca as part of GeoKit's API to geocode addresses. Hostip.info Hostip.info is a website that provides free geocoding of IP addresses. Hostip.info offers an HTTP-based API as well as its entire database for integration at no cost. We will be using Hostip.info as part of GeoKit's API to geocode IP addresses. GeoKit GeoKit is a Rails plugin that enables you to build location-based applications. For this article we will be using GeoKit for its geocoding capabilities in two ways: To determine the longitude and latitude coordinates of the kiosk from its given address To determine the longitude and latitude coordinates of the user from his or her IP address GeoKit is a plugin to your Rails application so installing it means more or less copying the source files from the GeoKit Subversion repository and running through an installation script that adds certain default parameters in your environment.rb file. To install the GeoKit, go to your Rails application folder and execute this at the command line: $./script/plugin install svn://rubyforge.org/var/svn/geokit/trunk This will copy the necessary files to your RAILS_ROOT/vendor/plugins folder and run the install.rb script. Configuring GeoKit After installing GeoKit you will need to configure it properly to allow it to work. GeoKit allows you to use a few sets of geocoding APIs, including Yahoo, Google, Geocoder.us, and Geocoder.ca. These geocoding providers can be used directly or through a cascading failover sequence. Using Yahoo or Google requires you to register for an API key but they are free. Geocoder.us is also free under certain terms and conditions but both Geocoder.us and Geocoder.ca have commercial accounts. In this article I will briefly go through how to get an application ID from Yahoo and a Google Maps API key from Google. Getting an application ID from Yahoo Yahoo's application ID is needed for any Yahoo web service API calls. You can use the same application ID for all services in the same application or multiple applications or one application ID per service. To get the Yahoo application ID, go to https://developer.yahoo.com/wsregapp/index.php and provide the necessary information. Note that for this application you don't need user authentication. Once you click on submit, you will be provided an application ID. Getting a Google Maps API key from Google To use Google Maps you will need to have a Google Maps API key. Go to http://www.google.com/apis/maps/signup.html. After reading the terms and conditions you will be asked to give a website URL that will use the Google Maps API. For geocoding purposes, this is not important (anything will do) but to display Google Maps on a website, this is important because Google Maps will not display if the URL doesn't match. However all is not lost if you have provided the wrong URL at first; you can create any number of API keys from Google. Configuring evironment.rb Now that you have a Yahoo application ID and a Google Maps API key, go to environment.rb under the RAILS_ROOT/config folder. Installing GeoKit should have added the following to your environment.rb file: # Include your application configuration below # These defaults are used in GeoKit::Mappable.distance_to and in acts_as_mappable GeoKit::default_units = :miles GeoKit::default_formula = :sphere # This is the timeout value in seconds to be used for calls to the geocoder web # services. For no timeout at all, comment out the setting. The timeout unit is in seconds. # GeoKit::Geocoders::timeout = 3 # These settings are used if web service calls must be routed through a proxy. # These setting can be nil if not needed, otherwise, addr and port must be filled in at a minimum. If the proxy requires authentication, the username and password can be provided as well. GeoKit::Geocoders::proxy_addr = nil GeoKit::Geocoders::proxy_port = nil GeoKit::Geocoders::proxy_user = nil GeoKit::Geocoders::proxy_pass = nil # This is your yahoo application key for the Yahoo Geocoder # See http://developer.yahoo.com/faq/index.html#appid and http://developer.yahoo.com/maps/rest/V1/geocode.html GeoKit::Geocoders::yahoo = <YOUR YAHOO APP ID> # This is your Google Maps geocoder key. # See http://www.google.com/apis/maps/signup.html and http://www.google.com/apis/maps/documentation/#Geocoding_Examples GeoKit::Geocoders::google = <YOUR GOOGLE MAPS KEY> # This is your username and password for geocoder.us # To use the free service, the value can be set to nil or false. For usage tied to an account, the value should be set to username:password. # See http://geocoder.us and http://geocoder.us/user/signup GeoKit::Geocoders::geocoder_us = false # This is your authorization key for geocoder.ca. # To use the free service, the value can be set to nil or false. For usage tied to an account, set the value to the key obtained from Geocoder.ca # See http://geocoder.ca and http://geocoder.ca/?register=1 GeoKit::Geocoders::geocoder_ca = false # This is the order in which the geocoders are called in a failover scenario # If you only want to use a single geocoder, put a single symbol in the array. # Valid symbols are :google, :yahoo, :us, and :ca # Be aware that there are Terms of Use restrictions on how you can use the various geocoders. Make sure you read up on relevant Terms of Use for each geocoder you are going to use. GeoKit::Geocoders::provider_order = [:google,:yahoo] Go to the lines where you are asked to put in the Yahoo and Google keys and change the values accordingly. Make sure the keys are within apostrophes. Then go to the provider order and put in the order you want (the first will be tried; if that fails it will go to the next until all are exhausted): GeoKit::Geocoders::provider_order = [:google,:yahoo] This completes the configuration of GeoKit. YM4R/GM YM4R/GM is another Rails plugin, one that facilitates the use of Google Maps APIs. We will be using YM4R/GM to display the kiosk locations on a customized Google Map. This API essentially wraps around the Google Maps APIs but also provides additional features to make it easier to use from Ruby. To install it, go to your Rails application folder and execute this at the command line: $./script/plugin install svn://rubyforge.org/var/svn/ym4r/Plugins/GM/trunk/ym4r_gm During the installation, the JavaScript files found in the RAILS_ROOT/vendors/plugin/javascript folder will be copied to the RAILS_ROOT/public/javascripts folder. A gmaps_api_key.yml file is also created in the RAILS_ROOT/config folder. This file is a YAML representation of a hash, like the database.yml file in which you can set up a test, development, and production environment. This is where you will put in your Google Maps API key (in addition to the environment.rb you have changed earlier). For your local testing you will not need to change the values but once you deploy this in production on an Internet site you will need to put in a real value according to your domain.
Read more
  • 0
  • 0
  • 2386
article-image-maintaining-optimizing-and-upgrading-your-site-drupal-6-part-2
Packt
16 Oct 2009
9 min read
Save for later

Maintaining, Optimizing and Upgrading Your Site in Drupal 6: Part 2

Packt
16 Oct 2009
9 min read
Maintaining content As you continue to add content to your web site, you will need to ensure that your content is properly moderated, that old content is removed, and that changes to web site content are tracked. Creating content revisions Good Eatin' Goal: Create revisions of content to ensure that you have a complete record of changes to your web site's content. Additional modules needed: None. Basic steps We have simply updated our pages as necessary to add new functionality and content. However, if you have many editors, content that changes frequently, a need to view the history of a page, or need the ability to easily return to an old version of a page, you will want to store multiple revisions of your pages. To do this, carry out the following steps: Edit the content for which you want to create a new revision. Make the changes as needed and, before saving, expand the Revision information section. Select the Create new revision option and enter a message describing the changes that you have made to the node. When you save the content, you will see a new tab called Revisions. Clicking on this tab will show you a list of all of the revisions that have been created for the page. If you would like to return to an older version of the page, you can click the revert link. Or, if you want to remove an older revision, you can click the delete link to get rid of it permanently. You can control which users have access to the revision system by using the Permissions Manager. Drupal allows you to control which users can: view revisions, revert revisions, and delete revisions. If you want to force users to always create new revisions when editing content, edit the content type and then expand the Workflow settings. Change the default options to select the Create new revision option. When editors change content, the Create new revision option will be selected by default, and they will not be able to change the option unless they have the administer nodes permission. If you want to approve all revisions before publication, you can deselect the Published checkbox. Comparing content revisions Good Eatin' Goal: Compare the text of two different revisions of a page. Additional modules needed: Diff (http://drupal.org/project/diff). Basic steps Although the built-in functionality for creating revisions in Drupal works perfectly well, it can be difficult to review the changes that were made in each revision. The Diff module makes comparing revisions very easy. Begin by installing and activating the Diff module. To use the Diff module, simply view the revisions for any page. You will notice that the Revisions list has changed to allow you to select the revisions to be compared. Select the revisions to compare and then click on the Show diff button. Drupal will then display information about the text that has been changed, added, or deleted. Moderate content Good Eatin' Goal: Find questionable or offensive content, and remove it from your site, easily. Additional modules needed: Modr8 (http://drupal.org/project/modr8). Basic steps An unfortunate side effect of having a web site on the Internet is that, at some point, a malicious user will attempt to post inappropriate content on your site. If your site is extremely busy, you may find yourself with a large amount of content to review and approve. The Modr8 module can help you manage the workload and can send emails to users letting them know when their content has been approved or rejected. Begin by installing and activating the Modr8 module. The settings for the Modr8 module can be accessed by selecting Site configuration and then Modr8, from the Administer menu. The basic settings control how often logs are removed. Alternatively, you can choose to keep the logs forever. You can also change the number of items in the moderation queue to be displayed at a time, as well as the default action for the content that requires moderation. You can also configure the email settings for the moderation queue, including the text of the emails, and whether or not emails should be sent to the user who posted the content when their content is approved and/or when their content is rejected. You can also choose to send an email if the moderator does not take action for the item and wants to send a note to the author. If you would like new content to be added to the moderation queue automatically, you can edit the content type and select the In moderation queue setting in the workflow section. To view the moderation queue, select Content management and then Moderated content, from the Administer menu. The moderation queue appears as follows: From this page, you can approve, delete, or defer action on any content that needs moderation. After you make your changes, click Save to complete your selections. You can also display a log of all the moderation actions, by clicking on Reports and then Content moderation log. The moderation log appears as follows: Allowing users to report questionable or offensive content. Good Eatin' Goal: Get feedback from users to learn what they find offensive so the objectionable content can be removed. Additional modules needed: Abuse (http://drupal.org/project/abuse). Basic steps In the last task, we reviewed methods that allowed you to moderate every piece of content that is added to the site. However, this can be a time-intensive task if the proportion of content that you receive that is questionable is low. If this is the case, you can allow your users to help you to moderate the content by using the Abuse module, to let them report items that they find offensive. This strategy has a couple of advantages. Firstly, you are freed from the maintenance of pre-approving all content before it is published. Secondly, it ensures that the content meets community standards, rather than placing you or your editors in charge of defining community standards. The Abuse module also has a Watchlist component that allows you to flag content as suspicious or banned, and automatically move them into a queue for review by an administrator. Begin by downloading and installing the Abuse and Watchlist modules, both of which are included in the Abuse installation. We will begin by editing the Watchlist settings, which can be accessed by selecting Site configuration and then Watchlist settings, from the Administer menu. You can include any words that you want to, in the Watch list and Filtered/banned word list, depending on your target audience and your site's needs; just make sure that you enter one word per line. Items on the Watch list can be viewed while they are in the review queue, and items on the Filtered/banned word list will be hidden until they are reviewed. You can also control which items are automatically added to the Watch list or banned list, based on the Watchlist word settings configured above. You can also force moderation for specific types if they are more prone to abuse. We can now modify the Abuse Moderation settings by selecting Site configuration and then Abuse Moderation settings, from the Administer menu. The first setting controls what content types are subject to abuse reports. The next section of controls how abuse tickets are to be handled by your moderators. If you have multiple moderators for your site, you can select the Abuse Assigned Moderators option. If you use this, you will also need to store the maximum number of items that have been flagged for abuse that are added to the moderator's queue. If moderators live in different time zones, you can set an hour of the day at which all moderation queues are cleared, so that items do not remain in the moderation queue for an overly-long period of time. Finally, you can configure the settings related to all of the items that have been flagged as abusive by a user. The Abuse threshold controls how many complaints must be registered for an item before it is moved into the moderation queue. 3 is a good number to start with, but you may want to increase or decrease the threshold depending on the needs of your site. You can edit the reasons for flagging an item for abuse by selecting Site configuration, then Abuse Moderation settings, and finally Abuse Moderation reasons, from the Administer menu. All available reasons will be listed on the page using a format similar to the example above. You can add new reasons, remove reasons, or change the text for reasons from this page. Before the abuse module is activated, you need to assign permissions to users, so that they can flag content for review. Content that has the abuse module activated will have a new Flag as offensive link added to it, as shown in the following screenshot: When the user clicks on the Flag as offensive link, he or she will be presented with a form where he or she can specify their contact information, and a reason why he or she believes that the content is offensive. Administrators can review content that has been flagged as offensive by clicking on Content management and then Moderate. The administrators can click on the Get More Tickets link to have additional items assigned to them. Once a ticket has been assigned to them, the administrator can view information about the user who submitted the content as well as the user who flagged the content, and choose what action to take for the content. The administrator can either allow the content, or remove the content from the web site. The administrator can also optionally send a warning to the user without further action.
Read more
  • 0
  • 0
  • 1795

article-image-adding-interactive-course-material-moodle-19-part-1
Packt
16 Oct 2009
2 min read
Save for later

Adding Interactive Course Material in Moodle 1.9: Part 1

Packt
16 Oct 2009
2 min read
The following table gives you a brief description of each kind of activity. The sections that follow the table describe how and when to use these activities. Activity Description Assignment   An assignment is an activity completed offline, outside of Moodle. When the student completes the assignment, he or she either uploads a file for the instructor's review, or reports to the instructor in some other way. Regardless of whether the assignment requires uploading a file, the student receives a grade for the assignment. Choice   A choice is essentially a single, multiple-choice question that the instructor asks the class. The result can either be displayed to the class, or kept between the individual student and the instructor. Choices are a good way to get feedback from the students about the class. You can plant these choices in your course ahead of time, and keep them hidden until you need the students' feedback. You can also add them as needed. Journal   You can create an online journal, which will be unique for each student. A journal can be seen only by the student who writes it, and the instructor. Remember that a journal is attached to the course in which it appears. If you want to move a student's journal to another course, you'll need to make creative usage of the backup and restore functions.
Read more
  • 0
  • 0
  • 1303
Modal Close icon
Modal Close icon