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

How-To Tutorials - CMS & E-Commerce

830 Articles
article-image-enhancing-user-experience-wordpress-27part-2
Packt
12 Oct 2009
7 min read
Save for later

Enhancing User Experience with WordPress 2.7(Part 2)

Packt
12 Oct 2009
7 min read
Creating a drop-down menu for your categories Do you use a lot of categories along with their sub-categories? If so, using a drop-down menu is a nice way to categorize content, especially on larger sites. However, giving a quick access to the categories or sub-categories to readers can become a pain. Over the years, the drop-down menu has become very popular on the Internet. In this recipe, I'm going to show you how to create your own drop-down menu for your WordPress blog categories. Getting ready The menu you are going to create will first list your pages, and then at last a tab called Categories will obviously list your categories. This menu is achieved only with XHTML and CSS. No JavaScript is needed (unless you want to maintain compatibility with it commonly referred to as IE6) to ensure the best SEO possible for your WordPress blog. How to do it In order to make this recipe more readable, I have divided it in 3 steps—the PHP and the HTML, the CSS, and the JavaScript for IE6 compatibility. Step 1: PHP and HTML Open the header.php file from your theme and paste the following code where you'd like your drop-down menu to be displayed: <ul id="nav" class="clearfloat"><li><a href="<?php echo get_option('home'); ?>/"class="on">Home</a></li><?php wp_list_pages('title_li='); ?><li class="cat-item"><a href="#">Categories</a><ul class="children"><?php wp_list_categories('orderby=name&title_li=');$this_category = get_category($cat);if (get_category_children($this_category->cat_ID) != "") {echo "<ul>";wp_list_categories('orderby=id&show_count=0&title_li=&use_desc_for_title=1&child_of='.$this_category->cat_ID);echo "</ul>";}?></ul></li></ul> The purpose of this code is to make a list of all our pages and subpages, as well as a last list element named Categories. When a reader hovers on one of the top-level menu, the subpages (or categories) are displayed. Step 2: The CSS Open the style.css file from your theme and paste the following styles: #nav{background:#222;font-size:1.1em;}#nav, #nav ul {list-style: none;line-height: 1;}#nav a, #nav a:hover {display: block;text-decoration: none;border:none;}#nav li {float: left;list-style:none;border-right:1px solid #a9a9a9;}#nav a, #nav a:visited {display:block;font-weight:bold;color: #f5f5f4;padding:6px 12px;}#nav a:hover, #nav a:active, .current_page_item a, #home .on {background:#000;text-decoration:none}#nav li ul {position: absolute;left: -999em;height: auto;width: 174px;border-bottom: 1px solid #a9a9a9;}#nav li li {width: 172px;border-top: 1px solid #a9a9a9;border-right: 1px solid #a9a9a9;border-left: 1px solid #a9a9a9;background: #777;}#nav li li a, #nav li li a:visited {font-weight:normal;font-size:0.9em;color:#FFF;}#nav li li a:hover, #nav li li a:active {background:#000;}#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li.sfhover ul, #nav li li.sfhover ul, #nav li li li.sfhover ul {left: auto;}a.main:hover {background:none;} You may have to tweak this code a bit to match up to your blog's look and feel, for example, by adjusting colors. Once you are finished, simply save the file. Step 3: Optional JavaScript I'm not going to teach you something new here since, Internet Explorer 6 is a totally obsolete, crappy, and buggy browser. Sadly, many peoples are still using it and you may want to make sure that your blog is IE6 compliant. Modern browsers as such as Safari, Firefox, Opera, and even Internet Explorer 7 will not have any problem with the :hover pseudo-class on li elements. But you guessed it, it is asking too much from the IE6. To ensure backward compatibility on your WordPress blog, create a new file and call it dropdown.js. Put this code in the dropdown.js file: <![CDATA[//><!--sfHover = function() {var sfEls = document.getElementById("nav").getElementsByTagName("LI");for (var i=0; i<sfEls.length; i++) {sfEls[i].onmouseover=function() {this.className+=" sfhover";}sfEls[i].onmouseout=function() {this.className=this.className.replace(newRegExp(" sfhoverb"), "");}}}if (window.attachEvent) window.attachEvent("onload", sfHover);//–><!]]> Save the dropdown.js file and upload it to your wp-content/themes/yourtheme directory. Open header.php and add the following line within the <head> and </head> HTML tags: <!--[if lte IE 6]><script type="text/javascript" src="<?php bloginfo('template_url');?>/dropdown.js"></script><![endif]--> That's all! Your blog now has a very professional looking drop-down menu. How it works As IE6 cannot deal with :hover pseudo-classes on <li> elements, this small piece of code automatically ads a new CSS class, named sfhover to <li> elements when they are hovered over. When the mouse goes out of the top level element, a new function is executed, using a regular expression to remove the sfhover class. There's more... Now that I have shown you're the principle of creating a drop-down menu, you can use what you have just learned to create various kinds of menus. As an example, let's see how to re-use the previous code and create a very nice horizontal drop-down menu. Creating a horizontal drop-down menu As you'll notice by observing the code, there's a lot of similar things between this code and the one that you saw earlier. Part 1: PHP and HTML Simply copy this code where you want the menu to be displayed, for example, in your header.php file: <ul id="nav2" class="clearfloat"><li><a href="<?php echo get_option('home'); ?>/"class="on">Home</a></li><?php wp_list_categories('orderby=name&exlude=181&title_li=');$this_category = get_category($cat);if (get_category_children($this_category->cat_ID) != "") {echo "<ul>";wp_list_categories('orderby=id&show_count=0&title_li=&use_desc_for_title=1&child_of='.$this_category->cat_ID);echo "</ul>";}?></ul> Part 2: The CSS In modern drop-down menus, CSS are a very important part. Indeed, in this example it is CSS that display our menus horizontally. Paste the following code in your style.css file: #nav2{background-color: #202020;display: block;font-size:1.1em;height:50px;width:100%;}#nav2, #nav2 ul {line-height: 1;list-style: none;}#nav2 a ,#nav2 a:hover{border:none;display: block;text-decoration: none;}#nav2 li {float: left;list-style:none;}#nav2 a,#nav2 a:visited {color:#109dd0;display:block;font-weight:bold;padding:6px 12px;}#nav2 a:hover, #nav2 a:active {color:#fff;text-decoration:none}#nav2 li ul {border-bottom: 1px solid #a9a9a9;height: auto;left: -999em;position: absolute;width: 900px;z-index:999;}#nav2 li li {width: auto;}#nav2 li li a,#nav2 li li a:visited {color:#109dd0;font-weight:normal;font-size:0.9em;}#nav2 li li a:hover,#nav2 li li a:active {color:#fff;}#nav2 li:hover ul, #nav2 li li:hover ul, #nav2 li li li:hover ul,#nav2 li.sfhover ul, #nav2 li li.sfhover ul, #nav2 li li li.sfhover ul {left: 30px;} Once you have added theses lines to your style.css file and saved it, your WordPress blog will feature a very cool horizontal menu for displaying your categories. Part 3: (Optional) JavaScript As usual, if you want to maintain backward compatibility with Internet Explorer 6, you'll have to use the Javascript code that you have already seen in the previous example.
Read more
  • 0
  • 0
  • 989

article-image-creating-our-first-module-using-drupal-6-part2
Packt
12 Oct 2009
11 min read
Save for later

Creating Our First Module using Drupal 6 (Part2)

Packt
12 Oct 2009
11 min read
Using Goodreads Data So far, we have created a basic module that uses hook_block() to add block content and installed this basic module. As it stands, however, this module does no more than simply displaying a few lines of static text. In this article, we are going to extend the module's functionality. We will add a few new functions that retrieve and format data from Goodreads. Goodreads makes data available in an XML format based on RSS 2.0. The XML content is retrieved over HTTP (HyperText Transport Protocol), the protocol that web browsers use to retrieve web pages. To enable this module to get Goodreads content, we will have to write some code to retrieve data over HTTP and then parse the retrieved XML. Our first change will be to make a few modifications to goodreads_block(). Modifying the Block Hook We could cram all of our new code into the existing goodreads_block() hook; however, this would make the function cumbersome to read and difficult to maintain. Rather than adding significant code here, we will just call another function that will perform another part of the work. /** * Implementation of hook_block */function goodreads_block($op='list' , $delta=0, $edit=array()) { switch ($op) { case 'list': $blocks[0]['info'] = t('Goodreads Bookshelf'); return $blocks; case 'view': $url = 'http://www.goodreads.com/review/list_rss/' .'398385' .'?shelf=' .'history-of-philosophy'; $blocks['subject'] = t('On the Bookshelf'); $blocks['content'] = _goodreads_fetch_bookshelf($url); return $blocks; }} The preceding code should look familiar. This is our hook implementation as seen in the previous article. However, we have made a few modifications, indicated by the highlighted lines. First, we have added a variable, $url, whose value is the URL of the Goodreads XML feed we will be using (http://www.goodreads.com/review/list_rss/398385?shelf=history-of-philosophy). In a completely finished module, we would want this to be a configurable parameter, but for now we will leave it hard-coded. The second change has to do with where the module is getting its content. Previously, the function was setting the content to t('Temporary content'). Now it is calling another function: _goodreads_fetch_bookshelf($url). The leading underscore here indicates that this function is a private function of our module—it is a function not intended to be called by any piece of code outside of the module. Demarcating a function as private by using the initial underscore is another Drupal convention that you should employ in your own code. Let's take a look at the _goodreads_fetch_bookshelf() function. Retrieving XML Content over HTTP The job of the _goodreads_fetch_bookshelf() function is to retrieve the XML content using an HTTP connection to the Goodreads site. Once it has done that, it will hand over the job of formatting to another function. Here's a first look at the function in its entirety: /** * Retrieve information from the Goodreads bookshelp XML API. * * This makes an HTTP connection to the given URL, and * retrieves XML data, which it then attempts to format * for display. * * @param $url * URL to the goodreads bookshelf. * @param $num_items * Number of items to include in results. * @return * String containing the bookshelf. */function _goodreads_fetch_bookshelf($url, $num_items=3) { $http_result = drupal_http_request($url); if ($http_result->code == 200) { $doc = simplexml_load_string($http_result->data); if ($doc === false) { $msg = "Error parsing bookshelf XML for %url: %msg."; $vars = array('%url'=>$url, '%msg'=>$e->getMessage()); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("Getting the bookshelf resulted in an error."); } return _goodreads_block_content($doc, $num_items); // Otherwise we don't have any data}else { $msg = 'No content from %url.'; $vars = array('%url' => $url); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("The bookshelf is not accessible."); }} Let's take a closer look. Following the Drupal coding conventions, the first thing in the above code is an API description: /** * Retrieve information from the Goodreads bookshelp XML API. * * This makes an HTTP connection to the given URL, and retrieves * XML data, which it then attempts to format for display. * * @param $url * URL to the goodreads bookshelf. * @param $num_items * Number of items to include in results. * @return * String containing the bookshelf. */ This represents the typical function documentation block. It begins with a one-sentence overview of the function. This first sentence is usually followed by a few more sentences clarifying what the function does. Near the end of the docblock, special keywords (preceded by the @ sign) are used to document the parameters and possible return values for this function. @param: The @param keyword is used to document a parameter and it follows the following format: @param <variable name> <description>. The description should indicate what data type is expected in this parameter. @return: This keyword documents what type of return value one can expect from this function. It follows the format: @return <description>. This sort of documentation should be used for any module function that is not an implementation of a hook. Now we will look at the method itself, starting with the first few lines. function _goodreads_fetch_bookshelf($url, $num_items=3) { $http_result = drupal_http_request($url); This function expects as many as two parameters. The required $url parameter should contain the URL of the remote site, and the optional $num_items parameter should indicate the maximum number of items to be returned from the feed. While we don't make use of the $num_items parameter when we call _goodreads_fetch_bookshelf() this would also be a good thing to add to the module's configurable parameters. The first thing the function does is use the Drupal built-in drupal_http_request() function found in the includes/common.php library. This function makes an HTTP connection to a remote site using the supplied URL and then performs an HTTP GET request. The drupal_http_request() function returns an object that contains the response code (from the server or the socket library), the HTTP headers, and the data returned by the remote server. Drupal is occasionally criticized for not using the object-oriented features of PHP. In fact, it does—but less overtly than many other projects. Constructors are rarely used, but objects are employed throughout the framework. Here, for example, an object is returned by a core Drupal function. When the drupal_http_request() function has executed, the $http_result object will contain the returned information. The first thing we need to find out is whether the HTTP request was successful—whether it connected and retrieved the data we expect it to get. We can get this information from the response code, which will be set to a negative number if there was a networking error, and set to one of the HTTP response codes if the connection was successful. We know that if the server responds with the 200 (OK) code, it means that we have received some data. In a more robust application, we might also check for redirect messages (301, 302, 303, and 307) and other similar conditions. With a little more code, we could configure the module to follow redirects. Our simple module will simply treat any other response code as indicating an error: if ($http_result->code == 200) { // ...Process response code goes here... // Otherwise we don't have any data} else { $msg = 'No content from %url.'; $vars = array( '%url' => $url ); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("The bookshelf is not accessible.");} First let's look at what happens if the response code is something other than 200: } else { $msg = 'No content from %url.'; $vars = array( '%url' => $url ); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("The bookshelf is not accessible.");} We want to do two things when a request fails: we want to log an error, and then notify the user (in a friendly way) that we could not get the content. Let's take a glance at Drupal's logging mechanism. The watchdog() Function Another important core Drupal function is the watchdog() function. It provides a logging mechanism for Drupal. Customize your loggingDrupal provides a hook (hook_watchdog()) that can be implemented to customize what logging actions are taken when a message is logged using watchdog(). By default, Drupal logs to a designated database table. You can view this log in the administration section by going to Administer | Logs. The watchdog() function gathers all the necessary logging information and fires off the appropriate logging event. The first parameter of the watchdog() function is the logging category. Typically, modules should use the module name (goodreads in this case) as the logging category. In this way, finding module-specific errors will be easier. The second and third watchdog parameters are the text of the message ($msg above) and an associative array of data ($vars) that should be substituted into the $msg. These substitutions are done following the same translation rules used by the t() function. Just like with the t() function's substitution array, placeholders should begin with !, @, or %, depending on the level of escaping you need. So in the preceding example, the contents of the $url variable will be substituted into $msg in place of the %url marker. Finally, the last parameter in the watchdog() function is a constant that indicates the log message's priority, that is, how important it is. There are eight different constants that can be passed to this function: WATCHDOG_EMERG: The system is now in an unusable state. WATCHDOG_ALERT: Something must be done immediately. WATCHDOG_CRITICAL: The application is in a critical state. WATCHDOG_ERROR: An error occurred. WATCHDOG_WARNING: Something unexpected (and negative) happened, but didn't cause any serious problems. WATCHDOG_NOTICE: Something significant (but not bad) happened. WATCHDOG_INFO: Information can be logged. WATCHDOG_DEBUG: Debugging information can be logged. Depending on the logging configuration, not all these messages will show up in the log. The WATCHDOG_ERROR and WATCHDOG_WARNING levels are usually the most useful for module developers to record errors. Most modules do not contain code significant enough to cause general problems with Drupal, and the upper three log levels (alert, critical, and emergency) should probably not be used unless Drupal itself is in a bad state. There is an optional fifth parameter to watchdog(), usually called $link, which allows you to pass in an associated URL. Logging back ends may use that to generate links embedded within logging messages. The last thing we want to do in the case of an error is return an error message that can be displayed on the site. This is simply done by returning a (possibly translated) string: return t("The bookshelf is not accessible."); We've handled the case where retrieving the data failed. Now let's turn our attention to the case where the HTTP request was successful. Processing the HTTP Results When the result code of our request is 200, we know the web transaction was successful. The content may or may not be what we expect, but we have good reason to believe that no error occurred while retrieving the XML document. So, in this case, we continue processing the information: if ($http_result->code == 200) { // ... Processing response here... $doc = simplexml_load_string($http_result->data); if ($doc === false) { $msg = "Error parsing bookshelf XML for %url: %msg."; $vars = array('%url'=>$url, '%msg'=>$e->getMessage()); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("Getting the bookshelf resulted in an error."); } return _goodreads_block_content($doc, $num_items); // Otherwise we don't have any data} else { // ... Error handling that we just looked at. In the above example, we use the PHP 5 SimpleXML library. SimpleXML provides a set of convenient and easy-to-use tools for handling XML content. This library is not present in the now-deprecated PHP 4 language version. For compatibility with outdated versions of PHP, Drupal code often uses the Expat parser, a venerable old event-based XML parser supported since PHP 4 was introduced. Drupal even includes a wrapper function for creating an Expat parser instance. However, writing the event handlers is time consuming and repetitive. SimpleXML gives us an easier interface and requires much less coding. For an example of using the Expat event-based method for handling XML documents, see the built-in Aggregator module. For detailed documentation on using Expat, see the official PHP documentation: http://php.net/manual/en/ref.xml.php. We will parse the XML using simplexml_load_string(). If parsing is successful, the function returns a SimpleXML object. However, if parsing fails, it will return false. In our code, we check for a false. If one is found, we log an error and return a friendly error message. But if the Goodreads XML document was parsed properly, this function will call another function in our module, _goodreads_block_content(). This function will build some content from the XML data.
Read more
  • 0
  • 0
  • 954

article-image-social-bookmarking-blogger-part-1
Packt
12 Oct 2009
7 min read
Save for later

Social Bookmarking in Blogger: Part 1

Packt
12 Oct 2009
7 min read
The features of social bookmarking sites are in constant evolution. Currently they can be broadly categorized into three types: User generated news: The main goal is to increase visits by getting on the front page of a site like Digg or Reddit. This will increase traffic to a site by huge amounts for anywhere from a few minutes to a day. Sites unprepared for the avalanche of hits often choke on the visitor overload. This is commonly known as the Slashdot effect (http://www.slashdot.org); a popular technologies site whose readers have broken many a site under the crush of their visits. Circle of friends sharing: When posting to Facebook (http://www.facebook.com), Twitter (http://www.twitter.com), Flickr (http://flickr.com), or a blog, the user knows that the main purpose of these sites is sharing content with friends and people. When a user shares a link with a friend, a slight increase in traffic may occur (unless the user is a "celebrity" blogger with thousands of followers). Focusing on such groups would be more effective for smaller blogs. Online bookmarks: Readers use these sites to manage their bookmarks online. Links can be public, and may even serve the public interest, such as "How To". Most people see these sites as a welcome alternative to trying to export or duplicate bookmarks across multiple browsers or computers. Adding links to these sites will increase the chance of first time readers becoming regulars. Examples include del.icio.us (http://del.icio.us), Furl (http://www.furl.net), and Ma.gnolia (http://ma.gnolia.com). How Social Bookmarking Works Social bookmarking works because people share information they find online with each other. The different features that social bookmark services such as online bookmarks, categories, and rss feeds provide make it easier for people to find sites that interest them in new and sometimes unpredictable ways. People are connected to each other through these services, forming social and interacting networks, helping others find information, and spreading the word about sites they enjoy. Submitting Posts without Bookmarks Bookmarks are convenient for readers and bloggers. Submitting articles and posts manually is extra time and work for a reader. Making it easier for them by linking the post title and URL automatically encourages readers to submit posts spontaneously. Let's recommend a site to Reddit (http://www.reddit.com) without using bookmarks. Reddit is a popular online bookmark and user-generated news service. Time for Action!—Become a "Bookmarker" Navigate to http://www.reddit.com and click the submit link at the top of the screen. You will be redirected to the register or login screen. A username and password are all that is needed. Enter a username into the username box. You can enter an email address such as [email protected] into the email text field. Type a password into the password box and again into the verify password box. You can choose to have the site remember your login for you by clicking on the remember me checkbox. After reviewing the privacy policy and user agreement pages, place a check in the box next to I understand…. Click on the create account button after the form has been filled out as shown in the following screenshot: Find an interesting article to submit. We will submit the latest post on the (http://cookingwithamy.blogspot.com) blog. An example of the post being submitted is shown in the following screenshot. Copy the URL and the title of the post into a text editor such as Notepad (Windows) or Textpad (Mac). Log in to Reddit and click the submit link. Enter all the data manually, as shown in the following screenshot. Click the submit button. The link has now been shared. What Just Happened? It took three steps to add one link to Reddit. That did not include the time spent finding the site we wanted to submit. Then we had to log in to the bookmarking service and go to the submit form. We had to copy all the submission information ourselves and then enter it all manually into the bookmarking site form. The URL had to be entered correctly. If we had made a mistake while typing, the process would have taken longer and been more frustrating. It took a minute or two instead of the few seconds a bookmark would take. Now let's see how social bookmarks are a useful addition to our blog. They save the readers' time and make it more likely that new readers will impulse bookmark. Sharing Posts by Email A common way for visitors to share posts and articles they like is to email them to other people. Blogger has an Email Post to a Friend feature. Using features that make sharing posts more convenient for visitors will increase the exposure of your blog. This is a small subset of a type of marketing known as viral marketing, where readers spread your message for you from one person to another. "How hard is it to turn on this feature?" asks Georgia as she navigates the blog. "I'd like to try it. Then my readers will have an easy way to share my posts!" Time for Action!—Turn On Email Posting Log in to the blog, click the Settings link, and navigate to the Basic sub tab link. Scroll down the list to Show Email Post links? and select Yes from the drop‑down list as shown in the following screenshot: Click on Save Settings. Now it's time to test the feature. View the blog and click on the small email icon below the post. The Email Post to a Friend screen will appear. The sender will need to enter his name and email address and the email address of the person he wants to send the post to. The Message box, which is not a required field, can contain any notes from the sender. A sample of the post content is displayed at the bottom of the screen. Click the Send Email button to send the message. An email will be sent to the address [email protected], and a success screen is displayed with a link back to the blog, as shown in the following screenshot: The submitter will be able to return to the blog using the link under Return to where you were on the confirmation screen. What Just Happened? When you logged into the blog and turned on the email post links feature, The Email post link setting in the blogger template was set to "show". The icon for the Email-Post-To-A-Friend feature was then visible under each blog post. Clicking on the icon brought up a new screen with a form that prompted the submitters to enter the email information for themselves and their friends. The code displayed the post at the bottom of the screen, automatically. The friend is then sent an email with a link to the post. Adding Bookmarks to Blogs Social bookmarks can be displayed on blogs as text links, buttons, or as dynamic mini‑widgets showing the number of submissions. Adding bookmarks to blogs is a task that ranges from simple cut and paste to custom coding. We will first choose the social bookmarks and then explore several different techniques to add them to our blog. Choosing the Right Bookmarks for Your Blog Blogs that focus on specific topics or points of views stand out from thousands of other blogs and attract a more regular following. The social bookmarks you choose should fit the subject and tone of your blog. A technology blog would most likely have bookmarks to Digg (http://www.digg.com), Slashdot (http://www.slashdot.org), and Reddit (http://www.reddit.com). "There are so many social bookmarking services out there," says Georgia. "How do I pick the ones that are right for my blog?" Earlier, we had defined three broad types of social bookmark systems. You could just choose whatever bookmark sites you see your friends using. But you're smarter than that. You are on a mission to make sure your blog post links will show up where readers interested in your topic congregate. Listed below are the most popular and useful social bookmark systems and networks.
Read more
  • 0
  • 0
  • 2516
Visually different images

article-image-social-bookmarking-blogger-part-2
Packt
12 Oct 2009
6 min read
Save for later

Social Bookmarking in Blogger: Part 2

Packt
12 Oct 2009
6 min read
Adding buttons gives the site a more homemade feel, but it is time consuming to hunt down the links to the different services on the social networking sites. Wouldn't it be great if there was a third-party service out there that did the gathering for you? AddThis (http://www.addthis.com) offers a multi-bookmark widget popular with many bloggers. Offering Multiple Bookmarks with One Button Using a widget like the one offered by AddThis frees you to spend your time blogging. You can choose to show all the main bookmark networks or pick and choose from an extensive list. We'll configure the widget and then install it on our blog. Time for Action!—Offering Multiple Bookmarks with AddThis Register at the AddThis (http://www.addthis.com) site. Georgia has already created an account for Fruit for All. The AddThis Social Widget Builder screen has multiple options to customize the widget code. Choose the Bookmarking widget option from the Which kind of widget? drop-down box. Select the style of bookmark button you want to use. We will choose the second one. The on a Blog option should be selected for Where? Choose Blogger for the Blogging Platform and then click Get Your Free Button>> for the code. Next, AddThis will provide you with the code. Copy the code from the site or type the code below in place of the button links, above the <p class='post-footer-line post-footer-line-2'> tag in the template code: <!-- AddThis Bookmark Post Dropdown BEGIN --> <div> <script type='text/javascript'>addthis_url='<data:post.url/>'; addthis_title='<data:post.title/>'; addthis_pub='fruitforall';</script> <script src='http://s7.addthis.com/js/addthis_widget.php?v=12' type='text/javascript'></script> </div> <!-- AddThis Bookmark Post Dropdown END --> Save the template changes and view the blog. Try hovering the cursor over the Bookmark button to see whether the list of bookmarks appears. The button looks great. We need to test an icon to see how AddThis submits posts. Click the Del.icio.us icon to bring up the submission window. The URL, description (title), and tags were auto populated for us. Taking a note of the recommended tags will help us label future posts, and will guide us in adding more labels to the current post. What Just Happened? The AddThis button replaced our group of social bookmark buttons. When the visitor hovers their cursor over the button, a list of social bookmark icons appear. The visitor also has the option to choose from social bookmarks not listed in the main group. A new window opens with a submission form for the service we selected. After the form is filled out, AddThis collects statistical data for us and displays it graphically on our AddThis account page. The icons displayed on the button can be changed on the AddThis site. You can't predict which bookmarks your visitors use. Using a multiple bookmark aggregator such as AddThis keeps your posts free of bookmark clutter while giving visitors more bookmarking choices. There are other options as well. ShareThis (http://www.sharethis.com) has recently released the latest version of its multiple bookmark service, which includes tracking. It is available at http://sharethis.com/publisher/. Adding Dynamic Counters to Bookmark Links Showing counters on social bookmark icons is becoming popular. Dynamic counters are offered by bookmark services Reddit, Del.icio.us, Ma.gnolia, and Digg. Bookmark services are adding their own counters every day. Readers can quickly see if a post has already been submitted to a service and can vote to increase or decrease the popularity of the post while still at the blog. We will add the popular del.icio.us dynamic bookmark and examine the features it offers. We will then explore and then explore using Feedburner Flare (http://www.feedburner.com) to show multiple counters easily. Time for Action!—Adding Dynamic Links with Counters to Posts Navigate to the Edit HTML screen on the blog, and click the Expand Widget Templates checkbox. Type the following block of code directly above the <p class='post-footer-line post-footer-line-2'> tag in the template code, deleting any existing social bookmark code we added before: <script type="text/javascript">if (typeof window.Delicious == "undefined") window.Delicious = {}; Delicious.BLOGBADGE_DEFAULT_CLASS = 'delicious- blogbadge-line';</script> <script src="http://images.del.icio.us/static/js/ blogbadge.js"></script> Save the template, and view the blog to see the changes. An example of how it should look now is shown in the following screenshot: Are there any differences between the information captured using this bookmark and others? Let's test the bookmark and find it out. Click on bookmark this on the del.icio.us button and review the results: The bookmark does not display the actual post title and post URL. We will need to customize it to display that information when the reader submits the post. What Just Happened? We inserted a ready made counter bookmark script from the del.icio.us site into our template code. The first JavaScript code snippet will check to see if a link to del.icio.us already exists. If it does not, a special default CSS class is set to control the appearance of the badge. The code is shown for reference below: <script type="text/javascript">if (typeof window.Delicious == "undefined") window.Delicious = {}; Delicious.BLOGBADGE_DEFAULT_CLASS = 'delicious-blogbadge-line';</script> Calling the code controlling the badge counter is done with the final script tag. It links to an external JavaScript file stored at the del.icio.us site. <script src="http://images.del.icio.us/static/js/blogbadge.js"> </script> The script counts how many times readers have recommended the blog site to del.icio.us using their own script counter. The number shown will increase each time the site is bookmarked by someone on del.icio.us.
Read more
  • 0
  • 0
  • 1846

article-image-show-additional-information-users-and-visitors-your-plone-site
Packt
12 Oct 2009
5 min read
Save for later

Show Additional Information to Users and Visitors of Your Plone Site

Packt
12 Oct 2009
5 min read
(For more resources on Plone, see here.) What's a portlet, anyway? A portlet is a chunk of information that can be shown outside of the main content area of a page. In the following screenshot of Plone's default home page, the Log in box and the calendar are portlets. Plone's default theme has two portlet managers that control the assignment of portlets on the right and left sidebars of the page. You can place portlets into these slots on the page. It's also possible to add portlet manager slots to a custom theme so that you can display portlets in other areas of the page, but that's beyond the scope of this book. For more information, refer to: http://plone.org/documentation/how-to/adding-portlet-managers. There are two things that we need to know about portlets before we dive into adding them: Portlets can only be added to portlet managers. They can't be added into the body content of your pages. Portlets can be assigned to folders, content types, or user groups, and will cascade down through the site hierarchy unless you explicitly block inheritance. Plone's built-in portlets Plone ships with a generous assortment of basic portlets. Here's a quick list of Plone's default portlet offerings: Login: Shows Plone's login box to anonymous users; is hidden if a user is already logged in Collection portlet: Shows the results of a Collection Review list: Visible only to the users with the Reviewer role; this portlet shows a list of items that users have submitted for review before publishing RSS feed: Shows a list of items in an RSS feed Classic portlet: A wrapper for Zope 2 style portlets, which may have been developed prior to the advent of Plone 3 and its new portlet system Calendar portlet: Shows a simple calendar that highlights the dates of upcoming events for your site Search: Shows Plone's search box useful if you have chosen to disable the standard search box, and want to show it in a sidebar instead Recent items: Shows the most recently-published content items on your site Static text portlet: Shows a chunk of static, editable HTML content; this is one of Plone's most versatile and useful portlets Navigation: Shows the navigation tree Events: Shows upcoming published events on your site You're likely only to use Classic portlets if you are using an add-on product that hasn't fully embraced the new style of building portlets, or if you are building your own custom portlets. Add-on portlets Many add-on products for Plone will supply one or more relevant portlets when the product is installed. There are also additional standalone portlets available as separate add-on products. Among the most useful standalone add-on portlets are: TAL Portlet: A portlet that allows you to write your own simple portlets in Plone's templating language, TAL. Optionally, you could just write a Classic portlet. Feedmixer: A portlet that allows you to aggregate multiple RSS feeds into a single portlet. These products can be found in the Products section of Plone.org. Adding portlets There are three ways to add portlets to your site: Add portlets to specific locations on your site. Add portlets that are associated with specific content types—for example, a portlet that shows on all News Items. Add portlets that are shown only to specific groups of users in your site. Adding portlets to specific sections of your site We'll start with adding portlets to a specific section of your site, as this is the most common and the simplest thing to do. Log in to your site (via the Log in portlet) and look at the bottom of the rightmost sidebar for the Manage portlets link. This will take you to the Manage portlets screen. Managing Portlets PeacefullyBecause you were on the front page of your site, when you clicked on the Manage portlets link, you are now managing the portlets for your entire site. If you only want to manage portlets for a single section of your site, first navigate to that section, and then click on the Manage portlets link. The header of the Manage Portlets screen will tell you which section of the site you are in. The Manage Portlets screen tells you that certain portlets are already assigned to all of the pages of your site. In the example above, the left sidebar portlet manager has the Navigation portlet and the Log in portlet. The right sidebar portlet manager has the Review List, News, Events and Calendar portlets. Moving and Removing PortletsYou can move existing portlets around within a portlet manager by clicking on the up and down arrows within the portlet. You can remove a portlet from the portlet manager by clicking on the red X. To add a portlet to your site, select the Add portlet... drop-down menu at the top of either the right or left sidebar, and choose a portlet type to be added. For practice, let's try adding a static content portlet to the right sidebar. This screen contains the familiar Kupu-powered rich text editing widget, along with: A Portlet header (title) field. A Portlet footer field. A optional hyperlink field, which will be clickable from the portlet header and footer. An Omit portlet border checkbox. If selected, this hides the portlet header, footer, and border. This is very useful if you only want to place an image or some fl oating text in your sidebar. Enter some text into your new portlet, click on the Save button at the bottom of the screen, and then click on the Home tab to return to your site's homepage. You should now see your new static text portlet. If you click around the site, you'll continue to see the portlet on all of the pages of your site.
Read more
  • 0
  • 0
  • 2129

article-image-testing-your-business-rules-jboss-drools
Packt
12 Oct 2009
9 min read
Save for later

Testing your Business Rules in JBoss Drools

Packt
12 Oct 2009
9 min read
When we start writing 'real' business rules, there is very little space to make mistakes as the mistakes made can cause a lot of wastage of money. How much money would a company lose if a rule that you wrote gave double the intended discount to a customer? Or, what if your airline ticket pricing rule started giving away first class transatlantic flights for one cent? Of course, mistakes happen. This article makes sure that these costly mistakes don't happen to you. If you're going through the trouble of writing business rules, you will want to make sure that they do what you intend them to, and keep on doing what you intend, even when you or other people make changes, both now and in the future. But first of all, we will see how testing is not a standalone activity, but part of an ongoing cycle. Testing when building rules It's a slightly morbid thought, but there's every chance that some of the business rules that you write will last longer than you do. Remember the millennium bug caused by programmers in the 1960's, assuming that nobody would be using their work in 40 years' time, and then being surprised when the year 2000 actually came along? Rather than 'play and throw away', we're more likely to create production business rules in the following cycle: Write your rules (or modify an existing one) based on a specification, or feedback from end users. Test your rules to make sure that your new rules do what you want them to do, and ensure that you haven't inadvertently broken any existing rules. Deploy your rules to somewhere other than your local machine, where end users (perhaps via a web page or an enterprise system) can interact with them. You can repeat steps 1, 2, and 3 as often as required. That means, repeat as many times as it takes you to get the first version into production. Or, deploy now and modify it anytime later –in 1, 2, or 10 years time. Making testing interesting Normal testing, where you inspect everything manually, is booooooooring! You might check everything the first time, but after the hundredth deployment you'll be tempted to skip your tests—and you'll probably get away with it without any problems. You'll then be tempted to skip your tests on the 101st deployment—still no problems. So, not testing becomes a bad habit either because you're bored, or because your boss fails to see the value of the tests. The problem, then comes one Friday afternoon, or just when you're about to go on vacation, or some other worst possible time. The whole world will see any mistakes in the rules that are in production. Therefore, fixing them is a lot more time and money consuming than if you catch the error at the very start on your own PC. What's the solution? Automate the testing. All of your manual checks are very repetitive—exactly the sort of thing that computers are good at. The sort of checks for our chocolate shipment example would be 'every time we have an order of 2000 candy bars, we should have 10 shipments of 210 bars and one shipment of 110 bars'. Testing using Guvnor There is one very important  advantage of testing—we can instantly see whether our tests are correct, without having to wait for our rules to be deployed into the target system. At a high level, Guvnor has two main screens that deal with testing: An individual test screen: Here you can edit your test by specifying the values that you want to input, and the values that you expect once your rules have fired A package or multiple tests screen (below): This allows you to run (later on) all of the tests in your package, to catch any rules that you may have inadvertently broken Another way of saying this is: You write your tests for selfish reasons because you need them to ensure that your rules do what you want them to do. By keeping your tests for later, they automatically become a free safety net that catches bugs as soon as you make a change. Testing using FIT Guvnor testing is great. But, often, a lot of what you are testing for is already specified in the requirements documents for the system. With a bit of thought in specifying various scenarios in your requirements documents, FIT allows you to automatically compare these requirements against your rules. These requirements documents can be written in Microsoft Word, or similar format, and they will highlight if the outputs aren't what is specified. Like Drools, FIT is an open source project, so there is no charge for either using it, or for customizing it to fit your needs. Before you get too excited about this, your requirements documents do have some compromises. The tests must specify the values to be input to the rules, and the expected result—similar to the examples, or scenarios, that many specifications already contain. These scenarios have to follow a FIT-specific format. Specification documents should follow a standard format anyway—the FIT scenario piece is often less than 10% of it, and it is still highly human-readable! Even better, the document can be written in anything that generates HTML, which includes Microsoft Word, Excel, OpenOffice, Google documents, and most of the myriad of editors that are available today. Like the Guvnor testing, we can use FIT to test whether our individual requirements are being met when writing our rules. It is possible to run FIT automatically over multiple requirement documents to ensure that nothing has 'accidentally' broken as we update other rules. Getting FIT When you download the samples, you will probably notice three strange packages and folders. fit-testcase: This folder resides just within the main project folder, and contains the FIT requirements documents that we're going to test against. chap7: This is a folder under src/main/java/net/firstpartners, and contains the startpoint (FitRulesExample.java) that we'll use to kick-start our FIT Tests. FIT: This folder is next to the chap7 folder. It folder contains some of the 'magic plumbing' that makes FIT work. Most business users won't care how this works (you probably won't need to change what you find here), but we will take a look at it in more detail in case we want to customize exactly how FIT works. If you built the previous example using Maven, then all of the required FIT software will have been downloaded for you. (Isn't Maven great?) So, we're ready to go. The FIT requirements document Open the word document fit-testcase.doc using Word, or OpenOffice. Remember that it's in the fit-testcase folder. fit-testcase.doc is a normal document, without any hidden code. The testing magic lies in the way the document is laid out. More specifically, it's in the tables that you see in the document. All of the other text is optional. Let's go through it. Logo and the first paragraph At the very top of the document is the Drools logo and a reference to where you can download FIT for rules code. It's also worth reading the text here, as it's another explanation of what the FIT project does and how it works. None of this text matters, or rather FIT ignores it as it contains no tables. We can safely replace this (or any other text in this document that isn't in the table) with your company logo, or whatever you normally put at the top of your requirement documents. FIT is a GPL (General Public License) open source software. This means you can modify it (as long as you publish your changes). In this sample we've modified it to accept global variables passed into the rules. (We will use this feature in step 3.) The changes are published in the FIT plumbing directory, which is a part of the sample. Feel free to use it in your own projects. First step—setup The setup table prepares the ground for our test, and explains the objects that we want to use in our test. These objects are familiar as they are the Java facts that we've used in our rules. There's a bit of text (worth reading as it also explains what the table does), but FIT ignores it. The bit that it reads is given in the following table: net.firstpartners.fit.fixture.Setup net.firstpartners.chap6.domain.CustomerOrder AcmeOrder net.firstpartners.chap6.domain.OoompaLoompaDate nextAvailableShipmentDate If you're wondering what this does, try the following explanation in the same table format: Use the piece of plumbing called 'Setup'   Create CustomerOrder and call it AcmeOrder Create OoompaLoompaDate and call it nextAvailableShipmentDate There is nothing here that we haven't seen before. Note that we will be passing nextShipmentDate as a global so that it matches the global of a same name in our rules file (the match includes the exact spelling, and the same lower-and uppercase). Second step—values in The second part also has the usual text explanation (ignored by FIT) and table (the important bit), which explains how to set the values. net.firstpartners.fit.fixture.Populate AcmeOrder Set initial balance 2000 AcmeOrder Set current balance 2000 It's a little bit clearer than the first table, but we'll explain it again anyway. Use the piece of plumbing called Populate AcmeOrder Take the ... we created earlier, and set it to have an initial balance of ... 2000 AcmeOrder Take the ... we created earlier, and set it to have a current balance of ... 2000 Third step—click on the Go button Our next part starts the rules. Or rather, the table tells FIT to invoke the rules. The rest of the text (which is useful to explain what is going on to us humans) gets ignored. net.firstpartners.fit.fixture.Engine Ruleset src/main/java/net/firstpartners/chap6/shipping-rules.drl Assert AcmeOrder Global nextAvailableShipmentDate Execute   The following table is the same again, in English: Use the piece of plumbing called 'Engine' Ruleset Use the rules in shipping-rules.drl Assert Pass our AcmeOrder to the rule engine (as a fact) Global Pass our nextAvailableShipmentDate to the rule engine (as a global) Execute Click on the Go Button
Read more
  • 0
  • 0
  • 4081
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 $15.99/month. Cancel anytime
article-image-blog-cms
Packt
12 Oct 2009
10 min read
Save for later

Blog CMS

Packt
12 Oct 2009
10 min read
Let's get started right away. The first question-do I need a self-hosted or service-based CMS? Blogs have taken the Internet by storm. They started like simple diaries and have grown to be full-fledged CMSs now. If you want to start a blog, you have the following two options: Sign up with a hosted blog service such as WordPress.com, Typepad.com, Blogger.com, or any other similar services available Set up blogging software, such as WordPress, Movable Type, ExpressionEngine, and so on, on your own server If you are a casual blogger, signing up with a hosted service is a suitable choice. But if you want full control of your blog, setting up your own system is the best option. It's not very difficult—you could do it within five minutes. We will cover only self-hosted solutions for this article. But you can easily apply this knowledge to a blog service. Top blogging CMSs  WordPress (www.WordPress.org) is the most popular self-hosted blogging software. Hundreds of thousands of sites run on WordPress, and tens of millions of people see WordPress-driven content every day. The following images are of the PlayStation ( http://blog.us.playstation.com/ ) and the People ( http://offtherack.people.com/ ) blog sites, which use WordPress: Movable Type (www.movabletype.org) is another longtime favorite. It's very easy to use and has a strong fan following. There are many contenders after the top two blogging CMSs. All general-purpose CMSs have a blogging component. Many old blog software applications are no longer actively maintained. There are new entrants on the scene that focus on niches, such as photo blogging. Let us cover the top choices We can't cover all of the blog software in this article. So, we will only cover WordPress at length. We will talk about Movable Type and ExpressionEngine briefly. At the end, we will touch upon other blogging software. What we are interested in is to find out answers to the following questions: What sort of a site is that CMS good for? How easy is it to build a site? How easy is it to edit content? What's its plug-in/template support like? How extensible/customizable is it? What are the interesting or high-profile examples of that CMS? Taking WordPress for a test drive Let's try creating a site structure, adding and editing content, applying design templates, and making a few customizations with WordPress to see how it performs. Time for action-managing content with WordPress Log in to the administration panel of your WordPress installation. Click on the New Post link in the top bar. This opens the Add New Post page.Enter a title for your first blog post where your cursor is blinking. We will enter definition of the word Yoga for our Yoga Site. Start writing your text in the large text entry box. It's a WYSIWYG editor. You can use buttons in the toolbar to format text, insert links, and so on. Let's insert an image into our post. Click on the first icon next to Upload/Insert. When you move your mouse over it, you will see Add an Image in the tooltip. Click on that icon. Upload a file from your computer. Once a file is uploaded, you can enter additional parameters for this image. This includes Title, Caption, Alignment, a link to open when an image is clicked, and so on. Here's how your screen may look at this stage. Click on Insert into Post to add this image to your post. Complete writing the blog entry. If you want to add tags (keywords) to this post, you can do that from the Tagssection at right. WordPress will autocomplete long tags and will create newones as you Add them. We have not yet created any categories for our blog. Navigate to the Categories section below Tags. Click on the + Add New Category link. Enter Background as your category name and Add it. Any new categories youadd are selected automatically. Notice that you can post a blog entry in multiplecategories at once. There are a few other options too. There are the settings for Discussion. We want to allow both comments and trackbacks, so keep both options checked. Scroll up and click on the Publish button on the right to make this post live. Click on View Post at the top left to see how your site looks at the moment. What just happened? We published a new blog post with WordPress! This was the first time we used WordPress, but we could accomplish everything we needed to post this entry just from one screen. This is an important thing. Many CMSs require that you set up categories and images separately. This means you have to know the system before you can use it! WordPress allows you to learn about the system while using it. All sections in the Add New Postpage are well-labeled. There are sufficient descriptions, and what is not needed is hidden by default. Our title automatically became a search engine friendly permalink for this post. We could format our text with a simple WYSIWYG editor. It was packed with features—spell check, full screen editing, and further formatting options via Kitchen Sink. The editor allowed advanced editing by switching to the HTML mode. Adding an image was very easy. Upload, set options, and insert. We could select a previously uploaded image from the gallery, too. We could enter keyword tags for a post quickly. Selecting a category and adding new categories was simple. We created a new category on the Add New Post page itself. WordPress is intelligent enough to understand that if we added a new category on a post page, we would want to use it for that post. So, it was selected automatically. Advance options were available, but were hidden by default. We could publish the post right away, or at a later date. WordPress could also keep history of all the revisions we make to a post, could preview the post, and would auto-save it frequently. WordPress looks easy and powerful so far. Let us look at how we can harness it further. Surviving blog jargon and benefitting from itBlogs have their own terminology. You may not have heard of trackbacks, pingbacks, tags, or permalinks. You can learn more about these terms from http://en.wikipedia.org/wiki/List_of_blogging_terms and http://www.dailyblogtips.com/the-bloggers-glossary/. Similarly, there are excellent features that blogs have—comments, aggregating content from other sources, ability to get updates via RSS feeds, and so on. I recommend you to go through these glossaries to learn more about blogs. Extending WordPress Managing content with WordPress seems easy. We want to see how easy is it to customize its design and extend its features. Let's begin with the action. Time for action-customizing the design Find some themes you like. You can browse through theme galleries at http://WordPress.org/extend/themes/ or Google WordPress themes. There are thousands of free and paid themes available for WordPress. Download some themes that you like. Unzip each theme's ZIP file. Each theme should create a new folder for itself. Upload all these folders to the wp-content/themes folder on your server. In WordPress, go to Admin  Appearance|. You should see new themes you uploaded in the Available Themes section. The page also lists the WordPress Classic andDefault themes. We have three new themes showing up. Click on one of the themes to see a live preview. This is how it will look. Review all themes. Activate the one you like the most by clicking on the Activate link at the top right in the preview window. We liked oriental and activated it. Our site now shows up just like the live preview. What just happened? We installed a new design theme for our WordPress blog. We downloaded three themes from the Web, unzipped them, and uploaded them to our WordPress themes folder. The themes showed up in WordPress admin. Clicking on a theme showed a live preview. This made our decision easy. We activated the theme we liked. That's how easy it was to change the design of our blog! If you recall, installing a new design was similar in Joomla!, except that Joomla! allowed us to upload a ZIP file using its administration interface itself. The tricky part in giving a new design to your site was shortlisting and selecting a design, not setting it up. Customizing the theme Consider the following theme editor in WordPress If you want to further customize your theme, you can do that. In fact, you have full control over how your site looks with WordPress. You can use Appearance | Editor to change individual theme files. We recommend making template customizations on a local installation of WordPress first.Once you get everything done according to your choice, you can upload the changed files to the theme's folder and activate it. WordPress widgets Widgets are content blocks that can be used in a theme. Search, RSS feeds, Blog Post Archives, Tag Cloud, and Recent Posts are some of the built-in widgets available in WordPress. You can turn them on or off independently, determine their position in the sidebar, and also change their settings. Go to the Appearance | Widgets page to take over the control of WordPress widgets. Add unlimited power with plug-ins Our Yoga Site needs a lot more than just the core content management. How can we achieve that with WordPress? And will it be wise to use WordPress for our Yoga Site? The WordPress plug-in architecture is solid. You will find hundreds of high-quality plug-ins from photo galleries to e-commerce. But remember that the core of WordPress is a blog engine, which chronologically displays content under set categories. It encourages sharing and contribution. Theoretically, you can customize WordPress to any need you have. But we recommend you to evaluate the most important features for your site and then decide whether you want to use WordPress as a base, or something else. I use WordPress for my blog and have a range of plug-ins installed. WordPress is painless, and it allows me to focus on the core goal of my blog—sharing knowledge. Take a look at the list of plug-ins on my blog at www.mehtanirav.com. You may have noticed a few plug-ins to handle comments and spam. Why would you need that? Well, because you will end up spending all your time removing spam comments from your system if you don't have them activated. Comment spam is a real pain with all blogs. Spammers have written spam-bots (automatic software) that keep posting junk comments on your blog. If you don't protect comment submission, your blog will soon be flooded with advertisements of pills you don't want to take and a lot of other things you don't want your visitors to attend to. Comment protection plug-ins are the first you should install. I use Akismet with Simple Math. Simple Math poses a simple mathematical question to the comment writer. A human can easily answer that. This takes care of most of the spam comments. Comments that pass through this test need to pass through Akismet. Askimet is an excellent spam-protection plug-in from the WordPress team. These two plug-ins kill almost 99.99% of spam comments on my blog. Once I am left with legitimate comments, I can go to WordPress's Admin | Comments, and Approve, Unapprove, Delete, or Mark as Spam all comments. The Edit Comments screen looks like the following screenshot:| WordPress is a superb choice for creating a blog. It can be used as a general-purpose CMS as well. We have covered most of the day-to-day operations with WordPress so far. Here are some additional resources for you.
Read more
  • 0
  • 1
  • 5305

article-image-programmatically-creating-ssrs-report-microsoft-sql-server-2008
Packt
09 Oct 2009
4 min read
Save for later

Programmatically Creating SSRS Report in Microsoft SQL Server 2008

Packt
09 Oct 2009
4 min read
Introduction In order to design the MS SQL Server Reporting Services report programmatically you need to understand what goes into a report. We will start with a simple report shown in the next figure: The above tabular report gets its data from the SQL Server database TestNorthwind using the query shown below: Select EmployeeID, LastName, FirstName, City, Country from Employees. A report is based completely on a Report Definition file, a file in XML format. The file consists of information about the data connection, the datasource in which a dataset is defined, and the layout information together with the data bindings to the report. In the following, we will be referring to the Report Server file called RDLGenSimple.rdl. This is a file written in Report Definition Language in XML Syntax. The next figure shows this file opened as an XML file with the significant nodes collapsed. Note the namespace references. The significant items are the following: The XML Processing instructions The root element of the report collapsed and contained in the root element are: The DataSources Datasets Contained in the body are the ReportItems This is followed by the Page containing the PageHeader and PageFooter items In order to generate a RDL file of the above type the XMLTextWriter class will be used in Visual Studio 2008. In some of the hands-on you have seen how to connect to the SQL Server programmatically as well as how to retrieve data using the ADO.NET objects. This is precisely what you will be doing in this hands-on exercise. The XMLTextWriter Class In order to review the properties of the XMLTextWriter you need to add a reference to the project (or web site) indicating this item. This is carried out by right-clicking the Project (or Website) | Add Reference… and then choosing SYSTEM.XML (http://msdn.microsoft.com/en-us/library/system.xml.aspx) in the Add Reference window. After adding the reference, the ObjectBrowser can be used to look at the details of this class as shown in the next figure. You can access this from View | Object Browser, or by clicking the F2 key with your VS 2008 IDE open. A formal description of this can be found at the bottom of the next figure. The XMLTextWriter takes care of all the elements found in the XML DOM model (see for example, http://www.devarticles.com/c/a/XML/Roaming-through-XMLDOM-An-AJAX-Prerequisite). Hands-on exercise: Generating a Report Definition Language file using Visual Studio 2008 In this hands-on, you will be generating a server report that will display the report shown in the first figure. The coding you will be using is adopted from this article (http://technet.microsoft.com/en-us/library/ms167274.aspx) available  at Microsoft TechNet (http://technet.microsoft.com/en-us/sqlserver/default.aspx). Follow on In this section, you will create a project and add a reference. You add code to the page that is executed by the button click events. The code is scripted and is not generated by any tool. Create project and add reference You will create a Visual Studio 2008 Windows Forms Application and add controls to create a simple user interface for testing the code. Create a Windows Forms Application project in Visual Studio 2008 from File | New | Project… by providing a name. Herein, it is called RDLGen2. Drag-and-drop two labels, three buttons and two text boxes onto the form  as shown: When the Test Connection button Button1 in the code is clicked, a connection to the TestNorthwind database will be made. When the button is clicked, the code in the procedure Connection () is executed. If there are any errors, they will show up in the label at the bottom. When the Get list of Fields button Button2 in the code is clicked, the Query will be run against the database and the retrieved field list will be shown in the adjoining textbox. The Generate a RDL file button Button 3 in the code, creates a report file at the location indicated in the code.
Read more
  • 0
  • 0
  • 4030

article-image-drupal-6-content-construction-kit-cck
Packt
09 Oct 2009
6 min read
Save for later

Drupal 6 Content Construction Kit (CCK)

Packt
09 Oct 2009
6 min read
Views module provide administrators with the means to modify how Drupal displays lists of content, and CCK exposes its fields to the Views module, making them perfect partners when it comes to creating custom content and then displaying that content in a highly configurable manner. At the time of writing, Views is not available for Drupal 6 (although the module is being actively developed and should hopefully be ready by the time you read this) so it is left as an exercise to download and install it, and create at least one new View, utilizing fields created in the following sections. Installing CCK CCK is available, so go ahead and download the latest version and extract the file to your modules folder. CCK adds its own section to the Modules page under Site building: There are a number of interdependent sections for this module, but all of them rely on the first option, Content, so go ahead and enable this first. We are going to look over all the features provided by CCK, by default, in this section. So go ahead and enable those modules that rely only on Content. With that done, enable the remaining options so that you end up with everything working, like this: Notice that some of the options are disabled to prevent us from inadvertently disabling an option that is required by something else. If, for example, you wish to disable Text, then disable Node Reference and User Reference first. Working with CCK With all the options enabled, we can now go ahead and create a new content type. Actually, it is possible to create new content types without the use of CCK, it's just that the new content types will look pretty much like the standard content types already available, because there are no really interesting fields to add. Head over to Content types under Content management and select the Add content type field to bring up the following page: The identification section is pretty straightforward. You can go ahead and fill in whatever new content settings are appropriate. Of special interest is the Submission form settings below this that allows you to decide whether the default Title and Body fields should be changed or even retained (in the case of the Body field): In the case of the Endangered Species content type, it doesn't really make sense to have a species Title, rather a Common name makes more sense. Leaving the Body field label blank will cause this field to be omitted completely in the event that it is not suitable for the type of content you have in mind. You may have noticed that there are several additional tabs to the right of Add content type tab that provide additional functionality. These options are discussed a little later on in this section. So for now, go ahead and fill out the Name, Type, and Description fields and click Save content type to add this to the default list: We are now ready to begin customizing this new type utilizing whatever options are available—depending on what is or is not enabled. It is possible to customize any type that is available on Drupal, including the default ones like Blog entry or Poll, but to begin with it is best to leave these alone. To begin working on the new content type, click on edit in the Endangered Species row. We can now look at the various aspects of working with content types, beginning with… Adding Fields Select the Add field tab to bring up the following page: This dialog allows you to specify the new field's machine readable name and then select what type of input it is going to be. Presently, only the Create new field section is displayed on this page, because we have yet to add new fields. Once there is at least one custom field available, this page will have an additional section allowing existing fields to be added directly from any content type (you can come back here once there are a few saved fields): Regardless, the Create new field list presently comprises of the following options: Node Reference – Allows the poster to reference another node using its ID value Integer, Decimal, Float – Allows posters to store numbers in various formats Text – Allows posters to enter content User Reference – Allows posters to reference other users. Remember that this list is subject to change, depending on whether you disable various components of the default package, for example, Node Reference or User Reference, or include additional modules that add field types such as Date or Fivestar. Each value type comes with a set of options for how that data should be entered. Looking at the Integer type, we can see that users can be prompted for an integer with a Text Field, Select list, Check boxes, and radio buttons—in this case, the Select list is going to be used. Be careful about how information is stored—it is important to be efficient. For example, don't store information as text when there is only a certain number of options available, instead, store them as a number and provide the right input type to display the various options appropriately. To demonstrate this point, consider that at the moment, the numbers_in_wild field is set as an integer with the Select list input type. We are not going to provide a select list of every possible integer, but we are going to represent a range of numbers with an integer. For example, the value 1 will correspond to the range 1-10, 2 will correspond to 11-100, and so on. With the new field created, the configuration page for this field (Click on configure in the Operations column of the Manage fields page) now displays the current settings available. To begin with, the options in the Endangered Species settings are not of much interest as we have not specified what data this field will hold. To do this, scroll down the page to the Global settings section. From here, you can decide on how the data will be presented to the user and whether or not the field itself will be compulsory or not: Along with the Allowed values list used to input key-value pairs, there are a few other settings that may be of use, depending on what data the field should capture. Minimum and Maximum values along with Suffix and Prefix values allow for some minor input validation, as well as some useful display properties like currency denominations or physical units of measurement.
Read more
  • 0
  • 0
  • 2556

article-image-searching-data-using-phpmyadmin-and-mysql
Packt
09 Oct 2009
4 min read
Save for later

Searching Data using phpMyAdmin and MySQL

Packt
09 Oct 2009
4 min read
In this article by Marc Delisle, we present mechanisms that can be used to find the data we are looking for instead of just browsing tables page-by-page and sorting them. This article covers single-table and whole database searches. Single-Table Searches This section describes the Search sub-page where single-table search is available. Daily Usage of phpMyAdmin The main use for the tool for some users is with the Search mode, for finding and updating data. For this, the phpMyAdmin team has made it possible to define which sub-page is the starting page in Table view, with the $cfg['DefaultTabTable'] parameter. Setting it to 'tbl_select.php' defines the default sub-page to search. With this mode, application developers can look for data in ways not expected by the interface they are building, adjusting and sometimes repairing data. Entering the Search Sub-Page The Search sub-page can be accessed by clicking the Search link in the Table view. This has been done here for the book table: Selection of Display Fields The first panel facilitates a selection of the fields to be displayed in the results: All fields are selected by default, but we can control-click other fields to make the necessary selections. Mac users would use command-click to select / unselect the fields. Here are the fields of interest to us in this example: We can also specify the number of rows per page in the textbox just next to the field selection. The Add search conditions box will be explained in the Applying a WHERE Clause section later in this article. Ordering the Results The Display order dialog permits to specify an initial sorting order for the results to come. In this dialog, a drop-down menu contains all the table's columns; it's up to us to select the one on which we want to sort. By default, the sorting will be in Ascending order, but a choice of Descending order is available. It should be noted that on the results page, we can also change the sort order. Search Criteria by Field: Query by Example The main usage of the Search panel is to enter criteria for some fields so as to retrieve only the data in which we are interested. This is called Query by example because we give an example of what we are looking for. Our first retrieval will concern finding the book with ISBN 1-234567-89-0. We simply enter this value in the isbn box and choose the = operator: Clicking on Go gives the results shown in the following screenshot. The four fields displayed are those selected in the Select fields dialog: This is a standard results page. If the results ran in pages, we could navigate through them, and edit and delete data for the subset we chose during the process. Another feature of phpMyAdmin is that the fields used as the criteria are highlighted by changing the border color of the columns to better reflect their importance on the results page. It isn't necessary to specify that the isbn column be displayed. We could have selected only the title column for display and selected the isbn column as a criterion. Print View We see the Print view and Print view (with full texts) links on the results page. These links produce a more formal report of the results (without the navigation interface) directly to the printer. In our case, using Print view would produce the following: This report contains information about the server, database, time of generation, version of phpMyAdmin, version of MySQL, and SQL query used. The other link, Print view (with full texts) would print the contents of TEXT fields in its entirety.
Read more
  • 0
  • 0
  • 6550
article-image-search-engine-optimization-wordpress-part2
Packt
09 Oct 2009
8 min read
Save for later

Search Engine Optimization in WordPress-part2

Packt
09 Oct 2009
8 min read
Inbound Links Having plenty of good quality inbound links to your blog will improve your ranking in the search engines. Google started life as a student project to rank the importance of websites based on the number of incoming links; link popularity is still at the heart of Google's ranking process. But for many people link building seems like a daunting task. How do you get other people to link to you? It's actually not as difficult as it first seems—once you get into it, you'll see there are plenty of strategies to use. The point is to stick at it and treat link building as an integral part of your blogging routine. You can check how many inbound links Google has found for your blog by using the link: command. Enter link:http://www.packtpub.com into the Google search box to see all the inbound links for the Packt website. You can do the same for your blog.  There is a more 'organic' technique that we'll discuss here. It's often referred to by SEO pros as link baiting. It's basically creating content that other bloggers and webmasters just can't resist linking to. Obviously, you should always be trying to create interesting and exciting content, but every now and then it pays to come up with a killer post that is intended purely to attract links. There are several methods to achieve this. Here are a few suggestions to get you thinking: Write something controversial that other people will just have to disagree with. Be careful not to upset anyone and don't be offensive, but come up with something that goes against the grain and makes your opinion on an issue stand out. Disagree with a renowned expert. A post title like Seth Godin Is Plain Wrong About XYZ, backed up with a reasoned argument, could attract plenty of attention and encourage back links to the post. Provide a really useful resource. This could be something like a 'Top 10' list or a how-to guide. Run a contest, competition, or some other event that is likely to attract attention. Give away a useful 'freebie'. For example, a PDF e-book, a piece of software (that you own the rights to), or a free sample of one of your products. These are the kind of posts that are likely to attract attention and links back to your blog. Try brainstorming a few ideas along these lines and you'll be surprised how many you come up with. As well as link baiting you can also simply ask other people to link to you. This is a fairly straightforward approach, but you need to be careful not to come across as a spammer. It may be worth restricting this to people you know or people who regularly leave comments on your blog. Some people may be annoyed about receiving an email out of the blue requesting a back link, so exercise some discretion here. Definitely don't send out a broadcast email to lots of addresses requesting links. Don't be tempted to buy inbound links. There are many unscrupulous dealers on the Web who will sell you quantities of inbound links. Google and the other search engines regard this practice as 'cheating' and severely frown upon anyone involved. If you buy links, you will be banned from the search engines. Robots.txt Optimization A robots.txt file is read by search engine robots when they crawl on your blog. You can use it to tell them which pages should be indexed. There are a couple of reasons why using a robots.txt file is good for SEO. First, Google and other search engines recommend you use one and it's generally a good idea to do what they say. Second, it can help you to cut down on duplicated content. Search engines do not like duplicated content (that is the same content appearing at two different URLs within a website) because they suspect it might be spam. One minor drawback with WordPress is that it can create a lot of duplicate content. For example, http://blog.chilliguru.com/category/recipes points to exactly the same content as http://blog.chilliguru.com/recipes. Also, the same content is repeated on different pages. For example, most of the posts listed at http://blog.chilliguru.com/category/recipes are also listed on http://blog.chilliguru.com/tag/receipe. We can tell the search engines to ignore any duplicate content by giving instructions in the robots.txt file. Here is the robots.txt file for ChilliGuru: Sitemap: http://blog.chilliguru.com/sitemap.xmlUser-agent: *Disallow: /cgi-bin/Disallow: /wp-admin/Disallow: /wp-includes/Disallow: /wp-content/plugins/Disallow: /wp-content/cache/Disallow: /wp-content/themes/Disallow: /wp-Disallow: /category/Disallow: /comments/Disallow: /tag/Disallow: /author/Disallow: /trackback/ The first line is a big signpost to your Google Sitemap. User-agent: * means that the file is intended for all robots to read. It is possible to target the different search engine robots with specific instructions, for example, User-agent: Googlebot would just apply to the Google robot; however, you don't need to do this with your blog. The lines that begin with Disallow: tell the robots not to visit those files and folders. This is how you tell them to ignore certain parts of your site. For example, we don't need any of the content in the wp- directories to be indexed because it's mainly just PHP code. The one exception is /wp-content/uploads/. We haven't included this one in the robots.txt file, because we do want the search engines to crawl its contents. There may be images in there that should be indexed. Disallow: /category/ should cure the duplicate content problem we outlined above. You can use a simple text editor (for example, Notepad or Crimson Editor) to create your robots.txt file (you can go to http://blog.chilliguru.com/robots.txt and use that file as a starting point). Then it's simply a matter of using your FTP client to upload it to the root directory of your blog. Using Excerpts on the Home Page Another way to cut down on duplicated content is to display just excerpts of the posts on your home page instead of showing them in full. Obviously, each post is displayed in full on its own single post page, so having them in full on the home page may be regarded as duplicate content by the search engines. In fact, it's not just the home page, as the posts slip down to pages 2, 3, 4, and so on; they are still displayed in full. Using excerpts is not only a great SEO strategy; it is also becoming popular amongst bloggers in its own right. Some people prefer it as it makes the home page more concise and there is less vertical scrolling required to get an overview of all the posts. It makes it easier for readers to scan the posts and pick the ones they are really interested in. Also, forcing readers to click through to the single post page means they see the comments in full for each post and so may be more inclined to make a contribution to the discussion. It should still be OK to display the most recent post in full as it can take up to a week for a new post to be indexed by the search engines. By then, the post will have moved down the list and become excerpted, thus removing the risk of duplicate content. I'm noticing home page excerpts more and more. I just did a very quick (and unscientific) survey of the current top-10 blogs on technorati.com and seven of them used excerpts on their home page (these are big names like Gizmodo, The Huffington Post, Lifehacker, and so on). However, there will always be some traditionalists who prefer to see the full posts on the home page. You need to balance the SEO and usability benefits against the possibility of alienating some of your readers. Personally, I think the benefits of using excerpts outweigh any drawbacks, so we'll go ahead and set them up on ChilliGuru. You could go through and edit each post adding a tag where appropriate. However, there is a plugin we can use that will do this automatically. It's called Excerpt Editor by Andrew Ozz. Go to http://wordpress.org/extend/plugins/excerpt-editor/, download, install, and activate it in the usual way on your local development server. Select the plugin (it's under the Manage tab). First, select Auto-Generate from the menu and enter the following settings: Click Save Auto-Generate Options. Now select Replace Posts from the menu and enter the following settings: Click Save the Replace Posts options and view your home page. You will see that the latest post is shown in full but all the others have been excerpted and now have a Continue reading link. The same thing has been applied on all the Archive pages (Category, Author, Day, Month, and Year). The default settings in the plugin mean that the first 70 words are used in the excerpts. On the Auto-Generate page of the plugin, you can change the number of words to be included in the excerpts. Or, if you don't like having the post cut-off in the middle of a sentence, you can use the Editor to select each post and then manually set the content you want to appear in the excerpt. Having set the Auto-Generate options, every new post you publish will be excerpted accordingly. Simply deactivate the plugin if you ever want to revert to full posts.
Read more
  • 0
  • 0
  • 1599

article-image-search-engine-optimization-wordpress-part1
Packt
09 Oct 2009
8 min read
Save for later

Search Engine Optimization in WordPress-part1

Packt
09 Oct 2009
8 min read
Search Engine Optimization Having put so much time and effort into making your blog look pretty and creating fabulous content, you would want people to find it. The most common way for this to happen is via search engines. For many people, a typical web browsing session begins with a visit to their favorite search engine, so you want to be sure your blog appears high up in the rankings. Unfortunately, having a great-looking blog with lots of interesting posts isn't enough. To get a good place in the rankings takes time, perseverance, and no small amount of knowledge. The good news is that search engines love blogs. This fact, coupled with the techniques covered in this article, will go a long way to making your blog as findable as possible. Search engine optimization (SEO) is the art and science of getting your blog noticed by the search engines and ranked as high as possible. This article outlines the most important SEO strategies and how to apply them. We'll also discuss how to submit your blog to the search engines as well as look at some SEO software and tools, which could save you time and improve your results. The Principles of SEO SEO is a huge subject. There are thousands of professionals all over the world who earn their living by providing SEO services to website owners. The good SEO pros spend huge amounts of time and resources learning the skills of effective optimization. This goes to show that you could easily spend your entire life boning up on SEO—there's so much to learn. Obviously, you won't have anything like this amount of time to spend on your own SEO education. However, you can still do a lot to improve your blog's performance with the major search engines. The option to bring in a professional to really rocket through the rankings is there, if your marketing budget allows. If you do decide to hire a professional, make sure you choose a reputable one who does not use unscrupulous tactics, which could harm you more than help you. The good news is that WordPress has been made with SEO in mind. The software comes with many built-in SEO features. For example, you don't need to worry too much about the validity of the XHTML on your blog. The WordPress developers have ensured their code is valid. This is a big help as search engines will rank sites with valid code higher than those that have been poorly put together. There is plenty of other stuff going on behind the scenes in your WordPress installation that will aid your search engine findability—the WordPress developers have been very thoughtful. We'll be considering the aspects of SEO that are your responsibility. But first, a quick '101' on how search engines work. How Search Engines Find Stuff Search engines use special programs called robots that automatically crawl the Web and send back information about the web pages to the search engines' servers. They navigate the Web by following all the links they find. This is how a search engine collects the data for its index. The index is a huge database of entries cross-referenced between keywords and relevant website pages. The search engines use special algorithms to determine the rank of the web pages held in their index. When a web user enters a search query, the engine returns a list of results. The order of the search results depends on the rank of the pages, as determined by the algorithm. These algorithms are closely guarded secrets and the search engine companies are constantly updating them. The aim of the updates is to improve the relevancy of the search results. Because of the secrecy of the algorithms and the constant changes, it is very difficult for website owners to figure out the exact criteria used to rank pages. This prevents website owners from unfairly influencing the search rankings. However, by subscribing to the blogs or feeds of the major search engines, and using tools such as Google's Webmaster tools (more on this later), you can keep abreast of major changes. SEO professionals spend their lives trying to second-guess the search algorithms, but the search engine companies usually remain one step ahead. It's a game of cat and mouse, with the odds strongly skewed in favor of the search engines—they make the rules and can change them whenever they want. Despite the ever-changing algorithms, there are certain principles of SEO that stay constant. These are what we will look at in this article. For the purposes of this article, we will be concentrating on techniques for the 'traditional' search engines such as Google, MSN, Yahoo, and Ask. We will look at some of the blog-specific search engines, such as Technorati, in the next article. Keywords Keywords are the search terms that people type into a search engine when they are looking for something on the Web. They can be single words or several words that make up a phrase. It's essential to know the keywords being used by people who are looking for the type of content on your blog. You then need to ensure that you're using those keywords correctly. Let's look at a few strategies for finding and using keywords effectively. Choosing Your Keywords You should spend some time building up a list of your blog's keywords. The first step is to be clear in your mind about what your blog's content is about. What are the main themes you are writing about? Once you are clear about the main theme(s) of your blog, try a quick brainstorming exercise. You can do this alone or enlist the help of colleagues and friends. Put yourself in the shoes of someone looking for the kind of information you publish on your blog. What words or phrases are they likely to type into a search engine? We could run this exercise for ChilliGuru.com. People looking for the kind of content on ChilliGuru, may use the following keywords: Chilli (UK spelling) Chili (US spelling) Spicy food Growing chilies Chili recipe Mexican food Indian food Thai food Birds eye chilies Jalapeno Scotch bonnet Cook chilies OK, that's just a small handful of the more obvious keywords that took me about 60 seconds to come up with. If I spent longer, I'm sure I could come up with a list of 50 or more words and phrases. The more people you enlist into your keyword brainstorming, the more you are likely to come up with. Once you have a fairly good list, you can use keyword software to help you find even more. There are literally hundreds of keyword tools out there. Some are free, some are paid for, and they have a range of features. Later in this article, in the section on search engine submissions, we will introduce some software called Web CEO, which includes a good keyword tool. In the meantime, you can start with some of the tools provided by the search engines themselves. For example, Google provides a keyword selector tool for its advertising (Ad Words) customers, but you can use it to research your keywords. Go to https://adwords.google.com/select/KeywordToolExternal and enter a keyword or phrase into the search box. Keep the Use synonyms box checked. Enter the security code and click Get keyword ideas and you will be presented with a list of related keywords: OK, so it's a pretty long list; not all of the keywords will be relevant to your blog. For example, for ChilliGuru we could ignore 'red hot chilli peppers lyrics' and any other references to the band, The Red Hot Chilli Peppers. The preceding screen shot shows just the first few suggestions for one keyword, 'chilli' (the whole list runs into dozens). So you can see that if you were to use this tool for all the keywords in your original brainstorming list, you could easily end up with a very long list. This might seem like a good idea, but when we discuss using your keywords, shortly, you'll see that you don't actually want too many. When you're working on your list, try to be selective and keep the list manageable. Use your judgment to pick the important keywords and also look at the Avg Search Volume column in the Google list. This tells you how often each keyword is actually being used. Focus on the most popular ones. There's no point in my giving you a recommended number of keywords for your list, as this will depend on the type of content in your blog. If your blog covers a fairly narrow subject area, then you won't need as many keywords as if your blog covers a wide subject or even a range of subjects. Once you've read the next section on using keywords, you'll also have a better idea of how many you need.
Read more
  • 0
  • 0
  • 1756

article-image-multi-table-query-generator-using-phpmyadmin-and-mysql
Packt
09 Oct 2009
4 min read
Save for later

The Multi-Table Query Generator using phpMyAdmin and MySQL

Packt
09 Oct 2009
4 min read
The Search pages in the Database or Table view are intended for single-table lookups. This article by Marc Delisle, covers the multi-table Query by example (QBE) feature available in the Database view. Many phpMyAdmin users work in the Table view, table-by-table, and thus tend to overlook the multi-table query generator, which is a wonderful feature for fine-tuning queries. The query generator is useful not only in multi-table situations but also for a single table. It enables us to specify multiple criteria for a column, a feature that the Search page in the Table view does not possess. The examples in this article assumes that a multi-user installation of the linked-tables infrastructure has been made and that the book-copy table created during an exercise in the article on Table and Database Operations in PHP is still there in the marc_book database. To access the code used in this article Click Here. To open the page for this feature, we go to the Database view for a specific database (the query generator supports working on only one database at a time) and click on Query. The screenshot overleaf shows the initial QBE page. It contains the following elements: Criteria columns An interface to add criteria rows An interface to add criteria columns A table selector The query area Buttons to update or to execute the query Choosing Tables The initial selection includes all the tables. In this example, we assume that the linked-table infrastructure has been installed into the marc_book database. Consequently, the Field selector contains a great number of fields. For our example, we will work only with the author and book tables: We then click Update Query. This refreshes the screen and reduces the number of fields available in the Field selector. We can always change the table choice later, using our browser's mechanism for multiple choices in drop-down menus (usually, control-click). Column Criteria Three criteria columns are provided by default. This section discusses the options we have for editing their criteria. These include options for selecting fields, sorting individual columns, entering conditions for individual columns, and so on. Field Selector: Single-Column or All Columns The Field selector contains all individual columns for the selected tables, plus a special choice ending with an asterisk (*) for each table, which means all the fields are selected: To display all the fields in the author table, we choose `author`.* and check the Show checkbox, without entering anything in the Sort and Criteria boxes. In our case, we select `author`.`name`, because we want to enter some criteria for the author's name. Sorts For each selected individual column, we can specify a sort (in Ascending or Descending order) or let this line remain intact (meaning no sort). If we choose more than one sorted column, the sort will be done with a priority from left to right. When we ask for a column to be sorted, we normally check the Show checkbox, but this is not necessary because we might want to do just the sorting operation without displaying this column. Showing a Column We check the Show checkbox so that we can see the column in the results. Sometimes, we may just want to apply a criterion on a column and not include it in the resulting page. Here, we add the phone column, ask for a sort on it, and choose to show both the name and phone number. We also ask for a sort on the name in ascending order. The sort will be done first by name, and then by phone number, if the names are identical. This is because the name is in a column criterion to the left of the phone column, and thus has a higher priority:
Read more
  • 0
  • 0
  • 7344
article-image-file-sharing-grails
Packt
09 Oct 2009
7 min read
Save for later

File Sharing in Grails

Packt
09 Oct 2009
7 min read
File domain object The first step, as usual, is to create a domain object to represent a file. We want to store the following information: Name The data of the file A description of the file The file size Who uploaded the file The date the file was created and last modified Create the File domain class as follows: package app class File { private static final int TEN_MEG_IN_BYTES = 1024*1024*10 byte[] data String name String description int size String extension User user Date dateCreated Date lastUpdated static constraints = { data( nullable: false, minSize: 1, maxSize: TEN_MEG_IN_BYTES ) name( nullable: false, blank: false ) description( nullable: false, blank: false ) size( nullable: false ) extension( nullable: false ) user( nullable: false ) } } There should be nothing unfamiliar here. You have created a new domain class to represent a file. The file data will be stored in the data property. The other properties of the file are all metadata. Defining the user property creates the association to a user object. The constraints are then defined to make sure that all of the information that is needed for a file has been supplied. There is one important side effect of setting the maxSize constraint on the data property. GORM will use this value as a hint when generating the database schema for the domain objects. For example, if this value is not specified, the underlying database may end up choosing a data type to store the binary file data that is too small for the size of files that you wish to persist. FileController Now, we will need a controller. Let's name it FileController. Our controller will allow users to perform the following actions: Go to a page that allows users to select a file Submit a file to the server Download the file Create the FileController groovy class, alongside our existing MessageController, by following the actions shown below: package app class FileController { def create = { return [ file: new File() ] } def save = { } def download = { } } In the create action, we are simply constructing a new file instance that can be used as the backing object when rendering the file-upload form. We will fill in the implementation details of the save and download actions as and when we will need them. File Upload GSP The next step is to create a GSP to render the form that allows users to upload a file to the application. Create the file grails-app/views/file/create.gsp and enter the following markup: <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <meta http-equiv="Content-Type" content= "text/html; charset=UTF-8"/> <meta name="layout" content="main"/> <title>Post File</title> </head> <body> <g:hasErrors bean="${file}"> <div class="validationerror"> <g:renderErrors bean="${file}" as="list"/> </div> </g:hasErrors> <g:form action="save" method="post" enctype="multipart/form-data" class="inputform"> <fieldset> <dl> <dt>Title <span class="requiredfield">required</span></dt> <dd><g:textField name="name" value="${file.name}" size="35" class="largeinput"/></dd> <dt>File <span class="requiredfield">required</span></dt> <dd><input type="file" name="data"/></dd> <dt>File description <span class="requiredfield">required</span></dt> <dd><g:textArea name="description" value="${file .description}" cols="40" rows="10"/></dd> </dl> </fieldset> <g:submitButton name="Save" value="Save"/> | <g:link controller="home">Cancel</g:link> </g:form> </body> </html> This GSP looks very similar to the create.gsp file for messages. Obviously, it has different fields that correspond to fields on the File domain class. The important difference is that this form tells the browser it will be submitting the file data: <g:form action="save" method="post" enctype="multipart/form-data">   Run the application, go to http://localhost:8080/teamwork/file/create and sign in with the username flancelot and the password password. You should see the window as shown in the following screenshot: Saving the file Now that our users can select files to upload, we need to implement the save action so that these files can be persisted and can be viewed by other users. Grails file upload Grails provides two methods of handling file upload. We are going to use both of them. The two approaches are: Using data binding Using the Spring MultipartFile interface Data binding makes receiving the data of the file very simple, but is quite limited if used on its own. There is no way of binding anything other than the data of the file, such as the filename or the size of the file, to our domain object. By also providing access to the Spring MultipartFile interface, Grails allows us to programmatically access any other information we might want from the file. The save action Update the FileController class and implement the save action as follows: package app import org.springframework.web.multipart.MultipartFile class FileController { def userService def create = { return [ file: new File() ] } def save = { def file = new File( params ) file.user = userService.getAuthenticatedUser() MultipartFile f = request.getFile( 'data' ) file.size = f.getSize() / 1024 file.extension = extractExtension( f ) if(file.save()) { flash.userMessage = "File [${file.name}] has been uploaded." redirect(controller: 'home') } else { render(view: 'create', model: [file: file]) } } def extractExtension( MultipartFile file ) { String filename = file.getOriginalFilename() return filename.substring(filename.lastIndexOf( "." ) + 1 ) } def download = { } } Apart from the implementation of the save action, we have had to import Spring MultipartFile and also inject the userService. The first highlighted line within the save action performs the binding of request parameters to the File domain object. The usual binding will take place, that is, the name and the description properties of the File object will be populated from the request. In addition, since we have a property on our domain object that is an array of bytes, the contents of the file object in the request will also be bound into our File object. A quick review of our code shows that we have the following property on theFile class: byte[] data Also the create.gsp defines the file input field with the same name: <dd><input type="file" name="data" /></dd> Grails is also capable of binding the contents of a file to a String property. In this case, we could just declare the data property in our File class as a String, and Grails would bind the file contents as a String. The next line of interest occurs when we fetch the MultipartFile off the request by using the getFile method. We simply specify the request parameter that contains the file data and Grails does the rest. With an instance of MultipartFile we can access the file size and the original file name to extract the file extension. Once we have finished populating our File object, we can call the save method and GORM will manage the persistence of the file object and the file data to the database. Validation messages The last thing we need to remember to add is the validation messages that will be displayed if the users don't enter all the data that is needed to save a file. Add the following to grails-app/i18n/messages.properties: file.name.blank=You must give the file a name file.description.blank=The file must have a description file.data.minSize.notmet=No file has been uploaded file.data.maxSize.exceeded=The file is too large. The maximum file size is 10MB
Read more
  • 0
  • 0
  • 1952

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

Creating a new Zen Cart Template

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