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

How-To Tutorials - Web Development

1802 Articles
article-image-building-web-service-driven-application-flash-drupal
Packt
20 Oct 2009
6 min read
Save for later

Building a Web Service-driven Application with Flash in Drupal

Packt
20 Oct 2009
6 min read
So, let's take a step-by-step approach on how to accomplish this on the Flash side, which as far as I am concerned, is the fun side! Click here to access all the codes used in this article. Step 1: Creating our Flash application With our chapter2 project open, we can shift our focus to the Actions panel within the Flash IDE. Although working with the Actions panel is great for small applications, we will eventually build onto this Flash application, which might make it impractical to keep all of our ActionScript code within the Actions panel. Because of this, we will first need to create a separate ActionScript file that will serve as our main entry point for our Flash application. This will allow us to easily expand our application and add to the functionality without modifying the Actions panel for every addition we make. Step 2: Creating a main.as ActionScript file For this step, we will simply create an empty file next to our chapter2.fla file called main.as. After you have created this new file, we will then need to reference it within our Actions panel. To do this, we will use the include keyword in ActionScript to include this file as the main entry point for our application. So, shifting our focus back to the chapter2.fla file, we will then place the following code within the Actions panel: include "main.as";stop(); Now that we are referencing the main.as file for any of the ActionScript functionality, we will no longer need to worry about the Actions panel and add any new functionality directly to the main.as file. Now, for the following sections, we will use this main.as file to place all of our ActionScript code that will connect and extract information from our Drupal system, and then populate that information in a TextField that we will create later. So, let's jump right in and write some code that connects us with our Drupal system. Step 3: Connecting to Drupal For this step, we will first need to open up our empty main.as file so that we can add custom functionality to our Flash application. With this file open in our Flash IDE, our first task will be to connect with Drupal. Connecting to Drupal will require us to make a remote call to our Drupal installation, and then handle its response correctly. This will require the use of asynchronous programming techniques along with some standard remoting classes built into the ActionScript 3 library. I will spend some time here discussing the class used by ActionScript 3 to achieve remote communication. This class is called NetConnection. Using the NetConnection class The NetConnection class in ActionScript 3 is specifically used to achieve remote procedure calls within a Flash application. Luckily, this class is pretty straight forward and does not have a huge learning curve on understanding how to utilize it for communicating with Drupal. Using this class requires that we first create an instance of this class as an object, and then initialize that object with the proper settings for our communication. But let's tackle the creation first, which will look something like this in our main.as file: // Declare our Drupal connectionvar drupal:NetConnection = new NetConnection(); Now, you probably noticed that I decided to name my instance of this net connection drupal. The reason for this is to make it very clear that any place in our Flash application where we would like to interact with Drupal, we will do so by simply using our drupal NetConnection object. But before we use this connection, we must first specify what type of connection we will be using. In any NetConnection object, we can do this by providing a value for the variable objectEncoding . This variable lets the connection know how to structure the XML format when communicating back and forth between Flash and Drupal. Currently, there are only two types of encoding to choose from: AMF0 or AMF3. AMF0 is used for ActionScript versions less than 3, while AMF3 is used for ActionScript 3. ActionScript 1 and 2 are much less efficient than version 3, so it is highly recommended to use ActionScript 3 over 1 or 2. Since we are using ActionScript 3, we will need to use the AMF3 format, and we can provide this as follows: // Declare our Drupal connectionvar drupal:NetConnection = new NetConnection();drupal.objectEncoding = ObjectEncoding.AMF3; Now that we have an instance ready to go, our first task will be to connect to the Drupal gateway that we set up in the previous section. Connecting to a remote gateway Connecting to a remote gateway can be performed using the connect command on our drupal NetConnection object. But in order for us to connect, we must first determine the correct gateway URL to pass to this function. We can find this by going back to our Drupal installation and navigating to Administer | Services. In the Browse section, you will see a link to the servers available for remote procedure calls as shown in the following screenshot: For every listed server, we can click on each link to verify that the server is ready for communication. Let's do this by clicking on the link for AMFPHP, which should then bring up a page to let us know that our AMFPHP gateway is installed properly. We can also use this page to determine our AMFPHP gateway location, since it is the URL of this page. By observing the path of this page, we can add our AMFPHP server to our main.as file by combining the base URL of our site and then adding the AMFPHP services gateway to that base. // Declare our baseURL and gateway string.var baseURL:String = "http://localhost/drupal6";var gateway:String = baseURL + "/services/amfphp";// Declare our Drupal connectionvar drupal:NetConnection = new NetConnection();drupal.objectEncoding = ObjectEncoding.AMF3;// Connect to the Drupal gatewaydrupal.connect( gateway ); It is important to note that the connect routine is synchronous, which means that once this function is called, we can immediately start using that connection. However, any remote procedure call that we make afterwards, will be asynchronous, and will need to be handled as such. The function that can be used to make these remote procedure calls to Drupal is called call.
Read more
  • 0
  • 0
  • 2319

article-image-making-content-findable-drupal-6
Packt
20 Oct 2009
5 min read
Save for later

Making Content Findable in Drupal 6

Packt
20 Oct 2009
5 min read
What you will learn In this article, you will learn about: Using Taxonomy to link descriptive terms to Node Content Tag clouds Path aliases What you will do In this article, you will: Create a Taxonomy Enable the use of tags with Node Content Define a custom URL Activate site searching Perform a search Understanding Taxonomy One way to find content on a site is by using a search function, but this can be considered as a hit-or-miss approach. Searching for an article on 'canines' won't return an article about dogs, unless it contains the word 'canines'. Certainly, navigation provides a way to navigate the site, but unless your site has only a small amount of content, the navigation can only be general in nature. Too much navigation is annoying. There are far too many sites with two or three sets of top navigation, plus left and bottom navigation. It's just too much to take in and still feel relaxed. Site maps offer additional navigation assistance, but they're usually not fun to read, and are more like a Table of Contents, where you have to know what you're looking for. So, what's the answer?—Tags! A Tag is simply a word or a phrase that is used as a descriptive link to content. In Drupal, a collective set of terms, from which terms or tags are associated with content, is called a Vocabulary. One or more Vocabularies comprise a Taxonomy. This a good place to begin, so let's create a Vocabulary. Activity 1: Creating a Taxonomy Vocabulary In this activity, we will be adding two terms to our Vocabulary. We shall also learn how to assign a Taxonomy to Node Content that has been created. We begin in the Content management area of the admin menu. There, you should find the Taxonomy option listed, as shown in the following screenshot. Click on this option. Taxonomy isn't listed in my admin menuThe Taxonomy module is not enabled by default. Check on the Modules page (Admin | Site building | Modules) and make sure that the module is enabled. For the most part, modules can be thought of as options that can be added to your Drupal site, although some of them are considered essential. Some modules come pre-installed with Drupal. Among them, some are automatically activated, and some need to be activated manually. There are many modules that are not included with Drupal, but are available freely from the Drupal web site. The next page gives us a lengthy description of the use of a taxonomy. At the top of the page are two options, List and Add vocabulary. We'll choose the latter. On the Add vocabulary page, we need to provide a Vocabulary name. We can create several vocabularies, each for a different use. For example, with this site, we could have a vocabulary for 'Music' and another for 'Meditation'. For now, we'll just create one vocabulary, and name it Tags, as suggested below, in the Vocabulary name box. In the Description box, we'll type This vocabulary contains Tag terms. In the Help text box, we'll type Enter one or more descriptive terms separated by commas. Next is the [Node] Content types section. This lists the types of Node Content that are currently defined. Each has a checkbox alongside it. Selecting the checkbox indicates that the associated Node Content type can have Tags from this vocabulary assigned to it. Ultimately, it means that if a site visitor searches using a Tag, then this type of Node Content might be offered as a match. We will be selecting all of the checkboxes. If a new Node Content type is created that will use tags, then edit the vocabulary and select the checkbox. The Settings section defines how we will use this vocabulary. In this case, we want to use it with tags, so we will select the Tags checkbox. The following screenshot shows the completed page. We'll then click on the Save button. At this point, we have a vocabulary, as shown in the screenshot, but it doesn't contain anything. We need to add something to it, so that we can use it. Let's click on the add terms link. On the Add term page, we're going to add two terms, one at a time. First we'll type healing music into the Term name box. We'll purposely make the terms lower case, as it will look better in the display that we'll be creating soon. We'll click on the Save button, and then repeat the procedure for another term named meditation. The method we used for adding terms is acceptable when creating new terms that have not been applied to anything, yet. If the term does apply to existing Node Content, then a better way to add it is by editing that content. We'll edit the Page we created, entitled Soul Reading. Now that the site has the Taxonomy module enabled, a new field named Tags appears below Title. We're going to type soul reading into it. This is an AJAX field. If we start typing a tag that already exists, then it will offer to complete the term. AJAX (Asynchronous JavaScript + XML) is a method of using existing technologies to retrieve data in the background. What it means to a web site visitor is that data can be retrieved and presented on the page being viewed, without having to reload the page. Now, we can Save our Node Content, and return to the vocabulary that we created earlier. Click on the List tab at the top of the page. Our terms are listed, as shown in the following screenshot.  
Read more
  • 0
  • 0
  • 2734

article-image-themes-and-templates-apache-struts-2
Packt
20 Oct 2009
10 min read
Save for later

Themes and Templates with Apache Struts 2

Packt
20 Oct 2009
10 min read
Extracting the templates The first step to modifying an existing theme or creating our own is to extract the templates from the Struts 2 distribution. This actually has the advantageous performance side effect of keeping the templates in the file system (as opposed to in the library file), which allows FreeMarker to cache the templates properly. Caching the templates provides a performance boost and involves no work other than extracting the templates. The issue with caching templates contained in library files, however, will be fixed. If we examine the Struts 2 core JAR file, we'll see a /template folder. We just need to put that in our application's classpath. The best way to do this depends on your build and deploy environment. For example, if we're using Eclipse, the easiest thing to do is put the /template folder in our source folder; Eclipse should deploy them automatically. A maze of twisty little passages Right now, consider a form having only text fields and a submit button. We'll start by looking at the template for the text field tag. For the most part, Struts 2 custom tags are named similarly to the template file that defines it. As we're using the "xhtml" theme, we'll look in our newly-created /template/xhtml folder. Templates are found in a folder with the same name as the theme. We find the <s:textfield> template in /template/xhtml/text.ftl file. However, when we open it, we are disappointed to find it implemented by the following files—controlheader.ftl file retrieved from the current theme's folder, text.ftl from the simple theme, and controlfooter.ftl file from "xhtml" theme. This is curious, but satisfactory for now. We'll assume what we need is in the controlheader.ftl file. However, upon opening that, we discover we actually need to look in controlheader-core.ftl file. Opening that file shows us the table rows that we're looking for. Going walkabout through source code, both Java and FreeMarker, can be frustrating, but ultimately educational. Developing the habit of looking at framework source can lead to a greater mastery of that framework. It can be frustrating at times, but is a critical skill. Even without a strong understanding of the FreeMarker template language, we can get a pretty good idea of what needs to be done by looking at the controlheader-core.ftl file. We notice that the template sets a convenience variable (hasFieldErrors) when the field being rendered has an error. We'll use that variable to control the style of the table row and cells of our text fields. This is how the class of the text field label is being set. Creating our theme To keep the template clean for the purpose of education, we'll go ahead and create a new theme. (Most of the things will be the same, but we'll strip out some unused code in the templates we modify.) While we have the possibility of extending an existing theme (see the Struts 2 documentation for details), we'll just create a new theme called s2wad by copying the xhtml templates into a folder called s2wad. We can now use the new theme by setting the theme in our <s:form> tag by specifying a theme attribute: <s:form theme="s2wad" ... etc ...> Subsequent form tags will now use our new s2wad theme. Because we decided not to extend the existing "xhtml" theme, as we have a lot of tags with the "xhtml" string hard coded inside. In theory, it probably wasn't necessary to hard code the theme into the templates. However, we're going to modify only a few tags for the time being, while the remaining tags will remain hard coded (although incorrectly). In an actual project, we'd either extend an existing theme or spend more time cleaning up the theme we've created (along with the "xhtml" theme, and provide corrective patches back to the Struts 2 project). First, we'll modify controlheader.ftl to use the theme parameter to load the appropriate controlheader-core.ftl file. Arguably, this is how the template should be implemented anyway, even though we could hard code in the new s2wad theme. Next, we'll start on controlheader-core.ftl. As our site will never use the top label position, we'll remove that. Doing this isn't necessary, but will keep it cleaner for our use. The controlheader-core.ftl template creates a table row for each field error for the field being rendered, and creates the table row containing the field label and input field itself. We want to add a class to both the table row and table cells containing the field label and input field. By adding a class to both, the row itself and each of the two table cells, we maximize our ability to apply CSS styles. Even if we end up styling only one or the other, it's convenient to have the option. We'll also strip out the FreeMarker code that puts the required indicator to the left of the label, once again, largely to keep things clean. Projects will normally have a unified look and feel. It's reasonable to remove unused functionality, and if we're already going through the trouble to create a new theme, then we might as well do that. We're also going to clean up the template a little bit by consolidating how we handle the presence of field errors. Instead of putting several FreeMarker <#if> directives throughout the template, we'll create some HTML attributes at the top of the template, and use them in the table row and table cells later on. Finally, we'll indent the template file to make it easier to read. This may not always be a viable technique in production, as the extra spaces may be rendered improperly, (particularly across browsers), possibly depending on what we end up putting in the tag. For now, imagine that we're using the default "required" indicator, an asterisk, but it's conceivable we might want to use something like an image. Whitespace is something to be aware of when dealing with HTML. Our modified controlheader-core.ftl file now looks like this: <#assign hasFieldErrors = parameters.name?exists && fieldErrors?exists && fieldErrors[parameters.name]?exists/><#if hasFieldErrors> <#assign labelClass = "class='errorLabel'"/> <#assign trClass = "class='hasErrors'"/> <#assign tdClass = "class='tdLabel hasErrors'"/><#else> <#assign labelClass = "class='label'"/> <#assign trClass = ""/> <#assign tdClass = "class='tdLabel'"/></#if><#if hasFieldErrors> <#list fieldErrors[parameters.name] as error> <tr errorFor="${parameters.id}" class="hasErrors"> <td>&nbsp;</td> <td class="hasErrors"><#rt/> <span class="errorMessage">${error?html}</span><#t/> </td><#lt/> </tr> </#list></#if><tr ${trClass}> <td ${tdClass}> <#if parameters.label?exists> <label <#t/> <#if parameters.id?exists> for="${parameters.id?html}" <#t/> </#if> ${labelClass} ><#t/> ${parameters.label?html}<#t/> <#if parameters.required?default(false)> <span class="required">*</span><#t/> </#if> :<#t/> <#include "/${parameters.templateDir}/s2e2e/tooltip.ftl" /> </label><#t/> </#if> </td><#lt/> It's significantly different when compared to the controlheader-core.ftl file of the "xhtml" theme. However, it has the same functionality for our application, with the addition of the new hasErrors class applied to both the table row and cells for the recipe's name and description fields. We've also slightly modified where the field errors are displayed (it is no longer centered around the entire input field row, but directly above the field itself). We'll also modify the controlheader.ftl template to apply the hasErrors style to the table cell containing the input field. This template is much simpler and includes only our new hasErrors class and the original align code. Note that we can use the variable hasFieldErrors, which is defined in controlheader-core.ftl. This is a valuable technique, but has the potential to lead to spaghetti code. It would probably be better to define it in the controlheader.ftl template. <#include "/${parameters.templateDir}/${parameters.theme}/controlheader-core.ftl" /><td<#if hasFieldErrors>class="hasErrors"<#t/></#if><#if parameters.align?exists>align="${parameters.align?html}"<#t/></#if>><#t/> We'll create a style for the table cells with the hasErrors class, setting the background to be just a little red. Our new template sets the hasErrors class on both the label and the input field table cells, and we've collapsed our table borders, so this will create a table row with a light red background. .hasErrors td {background: #fdd;} Now, a missing Name or Description will give us a more noticeable error, as shown in the following screenshot: This is fairly a simple example. However, it does show that it's pretty straightforward to begin customizing our own templates to match the requirements of the application. By encapsulating some of the view layer inside the form tags, our JSP files are kept significantly cleaner. Other uses of templates Anything we can do in a typical JSP page can be done in our templates. We don't have to use Struts 2's template support. We can do many similar things in a JSP custom tag file (or a Java-based tag), but we'd lose some of the functionality that's already been built. Some potential uses of templates might include the addition of accessibility features across an entire site, allowing them to be encapsulated within concise JSP notation. Enhanced JavaScript functionality could be added to all fields, or only specific fields of a form, including things such as detailed help or informational pop ups. This overlaps somewhat with the existing tooltip support, we might have custom usage requirements or our own framework that we need to support. Struts 2 now also ships with a Java-based theme that avoids the use of FreeMarker tags. These tags provide a noticeable speed benefit. However, only a few basic tags are supported at this time. It's bundled as a plug-in, which can be used as a launching point for our own Java-based tags. Summary Themes and templates provide another means of encapsulating functionality and/or appearance across an entire application. The use of existing themes can be a great benefit, particularly when doing early prototyping of a site, and are often sufficient for the finished product. Dealing effectively with templates is largely a matter of digging through the existing template source. It also includes determining what our particular needs are, and modifying or creating our own themes, adding and removing functionality as appropriate. While this article only takes a brief look at templates, it covers the basics and opens the door to implementing any enhancements we may require. If you have read this article you may be interested to view : Exceptions and Logging in Apache Struts 2 Documenting our Application in Apache Struts 2 (part 1) Documenting our Application in Apache Struts 2 (part 2)
Read more
  • 0
  • 0
  • 5601

article-image-rotating-post-titles-post-preview-gadget
Packt
20 Oct 2009
6 min read
Save for later

The Rotating Post Titles with Post Preview Gadget

Packt
20 Oct 2009
6 min read
The Rotating Post Titles with Post Preview gadget lists all your blog posts classified according to labels or categories. Blogger uses Labels to classify posts while Wordpress uses Categories for the same. Clicking on a Label or a category in the sidebar of a blog brings up all posts associated with that particular label or category. However, you will see only posts associated with that one label. In this gadget post titles are grouped under their respective labels. In this gadget in one look you can see all the post titles in that blog and all the labels in it. Thus you get a full summary of the blog. Hovering on a post title shows the Post Preview in the top pane. You can then click on it to go to that post to read it in full detail. What is Google AJAX feed API? AJAX (shorthand for asynchronous JavaScript and XML) is a web development technique which retrieves data from the server asynchronously in the background without interfering with the display, and behaviour of the existing page. The whole page is not refreshed when data is retrieved. Only that section of the page which is a part of the gadget shows the data brought. With the Google AJAX Feed API, you can retrieve feeds and mash them up using Javascript. In this gadget, we will retrieve the post titles from the label feeds and display them using Javascript code. See picture below: This gadget shows list of posts grouped by label from my blog http://www.blogdoctor.me. Four post titles from three labels are shown but the code can be modified to show all posts from all labels (categories). This label is also shown as Gadget No 4 in My Gadget Showcase blog. The cursor autoscrolls down the post titles, and each post preview is shown at the top as an excerpt for five seconds before moving on to the next post. Obtaining the Google AJAX API Key The first step in installing the above gadget is to get the Google AJAX API Key. It is free and you can easily obtain it for any site blog or page by signing up for the key at the API key signup page. Type in your blog address in the My web site URL text box and click the "Generate API Key" button. On the resulting page copy the key and paste it in code below as shown. Customizing the code In the code below replace PASTE AJAX API KEY HERE with your actual key obtained above. <!-- ++Begin Dynamic Feed Wizard Generated Code++ --><!-- // Created with a Google AJAX Search and Feed Wizard // http://code.google.com/apis/ajaxsearch/wizards.html --> <!-- // The Following div element will end up holding the actual feed control. // You can place this anywhere on your page. --><div id="content"> <span style="color:#676767;font-size:11px;margin:10px;padding:4px;">Loading...</span> </div><!-- Google Ajax Api --> <script src="http://www.google.com/jsapi?key=PASTE AJAX API KEY HERE" type="text/javascript"></script> <!-- Dynamic Feed Control and Stylesheet --> <script src="http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.js" type="text/javascript"></script> <style type="text/css"> @import url("http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.css"); </style><script type="text/javascript"> google.load('feeds', '1'); function OnLoad() { var feeds = [ { title: 'LABEL_1', url: 'http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL1?max-results=100' }, { title: 'LABEL_2', url: 'http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL2?max-results=100' }, { title: 'LABEL_3', url: 'http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL3?max-results=100' } ]; var options = { stacked : true, horizontal : false, title : "Posts from BLOG_TITLE" }; new GFdynamicFeedControl(feeds, 'content', options); document.getElementById('content').style.width = "200px"; } google.setOnLoadCallback(OnLoad); </script> In the above code replace LABEL_1, LABEL_2 and LABEL_3 and LABEL1, LABEL2 and LABEL3 by respective Label Names and BLOG_TITLE by the actual title of your blog. Also replace MYBLOG by actual blog subdomain. This is for blogspot blogs only. For Wordpress blog you will have to replace the label feeds:: http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL1?max-results=100 http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL2?max-results=100 http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL3?max-results=100 by the Category feed URLs from Wordpress blog. After customizing the above code in Blogger paste it in a HTML gadget while in Wordpress paste it in a Text widget. Further Customization To show more than four posts per label or category, you will have to modify the following Javascript code file: http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.js In the above mentioned Javascript code file, alter the following code line in it : GFdynamicFeedControl.DEFAULT_NUM_RESULTS = 4; Change '4' to '1000' and save the file as a MODgfdynamicfeedcontrol.js file in a text editor like Notepad. Upload the file to a free host and replace the link of the file in the above code. To change the styling of the gadget, you will have to modify the following file: http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.css Then save the modified file and upload it to a free host and replace its link in the above code. Working Example Posts from The Blog Doctor Change Post Formatting According to Author. by Vin - 30 Apr 2008 If you have a Team Blog made up of two authors you can change the formatting of the posts written by one author to ... Template Calling all Newbie Bloggers! Upgrade Classic Template without the "UPGRADE YOUR TEMPLATE" button. The Minimalist Minima Photoblog Template. Making the COMMENTS Link more User Friendly. CSS Change Post Formatting According to Author. Free CSS Navigation Menus in Blogger. Fix the Page Elements Layout Editor No Scrollbar Problem. Frame the Blog Header Image. Blogger Hacks Rounded Corner Headers for Blogger. Timestamp under the Date and Other Hacks. Add Icon to Post Titles. Many Headers In One Blog.   Summary The Rotating Post Titles with Post Preview gadget provides an at-a glance summary of your blog. All the posts are grouped by label or category and are linked to their post pages. The constantly rotating post excerpts at the top draws the attention of the reader and gets him/her more involved and eager to explore your blog. This increases the traffic and decreases the bounce rate of visitors from your blog.nara
Read more
  • 0
  • 0
  • 3925

article-image-managing-and-enhancing-multi-author-blogs-wordpress-27part-2
Packt
20 Oct 2009
8 min read
Save for later

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

Packt
20 Oct 2009
8 min read
Displaying author picture on posts Did you like the previous recipe in the first part? I hope you did! But personally, I must admit that even though displaying author information looks very cool, something is missing from the previous recipe. Can you guess what is it? It is a picture of the author, of course. Even if your author-related information is precise and complete, a picture is still essential. This is because it is the easiest, and quickest, way for a reader to recognize an author. But sadly, WordPress can't handle author pictures by default. Let's learn how to create a hack that will allow us to display the author's picture in the way that we want to. Getting ready As we'll be using author pictures in this recipe, you should start by requesting a picture of all of your authors. Although it isn't necessary, it will be really better if all of the pictures have the same width and height. A square of 80 to 110 pixels is a good standard. Also, make sure that all of your pictures have the same format, such as .jpg, .png, or .gif. How to do it Now that you have collected pictures of all of your authors, we can start to hack WordPress and insert author pictures in the posts First, you have to rename your images with the author IDs. You can also use author's last name if you prefer, but in this example I am going to use their IDs. Once you have your renamed authors' pictures, upload them to the wp-content/themes/yourtheme/images directory. Open the file single.php and add the following code within the loop: <img src="<?php bloginfo('template_url); ?>/images/<?php the_author_ID(); ?>.jpg" alt="<?php the_author(); ?>" /> Save the single.php file and you're done. Each post now displays a picture of its author! How it works The working of this code is pretty simple. You simply concatenated the result of the the_author_ID() function with the theme URL to build an absolute URL to the image. As the images are named with the author ID (for example, 1.jpg, 4.jpg, 17.jpg, and so on), the the_author_ID() function gives us the name of the picture to be displayed. You just have to add the .jpg extension. There's more... Now that you've learnt how to display the picture of the current author, you should definitely use this recipe to enhance the previous recipe. The following code will retrieve the author information, and display the author picture as we have learnt earlier: <div id="author-info"><h2>About the author: <?php the_author();?></h2><img src="<?php bloginfo('template_url); ?>/images/<?php the_author_ID(); ?>.jpg" alt="<?php the_author(); ?>" /><?php the_author_description(); ?><?php the_author();?>'s website: <a href="<?php the_author_url(); ?>"><?php the_author_url(); ?></a><br />Other posts by <?php the_author_posts_link(); ?></div><!--/author-info--> The outcome of the preceding piece of code will look similar to the following screenshot: Displaying the author's gravatar picture on posts Gravatars (which stands for Globally recognized avatars) is a popular service, that allows you to associate an avatar image to your email address. On October 18, 2007, Automattic (The company behind WordPress) acquired Gravatar. Since WordPress 2.5 the popular blogging engine is fully gravatar-compatible, which results, in the ability to include gravatars in comments. In this recipe, I'll show you how to modify the previous code to use the author gravatar instead of a personal picture. Getting ready As we're going to use Gravatars, you (and each of your authors) first need a gravatar account. Carry out the following steps to create a gravatar account and associate an image to your email address. Go to the web site http://en.gravatar.com/site/signup, and enter your email address into the text field. Gravatar will send you a confirmation via email. Check your emails and open the one received from Gravatar. Click on the link to confirm your email address. Choose a username and a Password for your account. Once your username and Password has been created successfully, you'll see a text that reads Whoops, looks like you don't have any images yet! Add an image by clicking here. Click on the given link, and choose to upload a picture from your computer's hard drive, or the Internet. Once you are done choosing and cropping (if necessary) your picture, you have to rate it. Click on G unless—except, if your avatar is meant for mature audiences only. Done! You now have your own gravatar. How to do it Open the file single.php from the theme you're using and paste the following code: $md5 = md5(get_the_author_email());$default = urlencode( 'http://www.yoursite.com/wp-content/themes/yourtheme/images/default_avatar.gif' );echo "<img src='http://www.gravatar.com/avatar.php?gravatar_id=$md5&amp;size=60&amp;default=$default' alt='' />"; How it works The first thing to do is to get an md5 sum from the author's email address. To do so, I used the php md5() function along with the get_the_author_email() function. I didn't use the_author_email() because this function directly prints the result without allowing you to manipulate it with php I then encoded the URL of a default picture that is to be shown if the author hasn't signed up to Gravatar yet. Once done, the gravatar can be displayed. To do so, visit the web site: http://www.gravatar.com/avatar.php with the following parameters: gravatar_id: The gravatar id, which is an md5 sum of the user email size: The gravatar size in pixels default:The absolute URL to an image which will be used as a default image if the author hasn't signed up to gravatar yet Adding moderation buttons to the comments A common problem with comments is spam. Sure, you can moderate comments and use the Akismet plugin. However, sometimes someone leaves a normal comment, you approve it, and then the spammer—who knows that his comments aren't being accepted by the moderator—starts to spam your blog. Even though you can do nothing against this (except moderating all of the comments), a good idea is to either add spam and delete buttons to all of the comments. This way, if you see a comment saying spam while reading your blog, then you can edit it, delete it, or mark it as spam. I got this useful tip from Joost de Valk, who blogs at www.yoast.com Getting ready The following screenshot shows normal comments without the edit, delete and spam buttons: There's nothing complicated at all with this recipe. However, you must be sure to know which kind of blog the users are allowed to edit or delete your comments. For a list of actions and user roles, see the section named Controlling what users can do, which is later in this article. How to do it Open the file functions.php and paste the following piece of code: function delete_comment_link($id){if (current_user_can('edit_post')){echo '| <a href="'.admin_url("comment.php?action=cdc&c=$id").'">del</a> ';echo '| <a href="'.admin_url("comment.php?action=cdc&dt=spam&c=$id").'">spam</a>';}} Save the file functions.php and open the file comments.php. Find the comments loop and add the following lines: <?phpedit_comment_link();delete_comment_link(get_comment_ID());?> Save the file comments.php and visit your blog. You now have three links on each of the comments to edit, to delete (del), and to mark as spam as shown in the following screenshot: How it works In this recipe we started by creating a function. This function first verifies whether the current user has the right to edit posts. If yes, then the admin URLs to mark the comment as spam or delete it are created and displayed. In the file comments.php, we have used the edit_comment_link(), which is a built-in WordPress function. Some themes include this by default. We then used the comment ID as a parameter to the delete_comment_link() function that you had created earlier.
Read more
  • 0
  • 0
  • 3768

article-image-modifying-existing-theme-drupal-6-part-2
Packt
20 Oct 2009
4 min read
Save for later

Modifying an Existing Theme in Drupal 6: Part 2

Packt
20 Oct 2009
4 min read
Adapting the CSS We've set up Tao as a subtheme of the Zen theme. As a result, the Tao theme relies upon a number of stylesheets, both in the Tao directory and in the parent theme's directory. The good news is that we do not need to concern ourselves with hacking away at all these various stylesheets, we can instead place all our changes in the tao.css file, located in the Tao theme directory. Drupal will give precedence to the styles defined in the theme's .css file, in the event of any conflicting definitions. Precedence and inheritance Where one style definition is in an imported stylesheet and another in the immediate stylesheet, the rule in the immediate stylesheet (the one that is importing the other stylesheet) takes precedence. Where repetitive definitions are in the same stylesheet, the one furthest from the top of the stylesheet takes precedence in the case of conflicts; where repetitive definitions are in the same stylesheet, nonconflicting attributes will be inherited. Setting the page dimensions For this exercise, the goal is to create a fixed width theme optimized for display settings of 1024 x 768. Accordingly, one of the most basic changes we need to make is to the page dimensions. If you look at the page.tpl.php file, you will notice that the entire page area is wrapped with a div with the id=page. Open up the tao.css file and alter it as follows. To help avoid precedence problems, place all your style definitions at the end of the stylesheet. Let's modify the selector #page. #page { width: 980px; margin: 0 auto; border-left: 4px solid #666633; border-right: 4px solid #666633; background-color: #fff;} In this case, I set page width to 980 pixels, a convenient size that works consistently across systems, and applied the margin attribute to center the page. I have also applied the border-left and border-right styles and set the background color. We also need to add a little space between the frame and the content area as well to keep the presentation readable and clean. The selector #content-area helps us here as a convenient container: #content-area { padding: 0 20px;} Formatting the new regions Let's begin by using CSS to position and format the two new regions, page top and banner. When we placed the code for the two new regions in our page.tpl.php file, we wrapped them both with divs. Page top was wrapped with the div page-top, so let's create that in our tao.css file: #page-top { margin: 0; background-color: #676734; width: 980px; height: 25px; text-align: right;} The region banner was wrapped with a div of the same name, so let's now define that selector as well: #banner { background-color: #fff; width: 980px; height: 90px; text-align: center;} Setting fonts and colors Some of the simplest CSS work is also some of the most important—setting font styles and the colors of the elements. Let's start by setting the default fonts for the site. I'm going to use body tag as follows: body { background: #000; min-width: 800px; margin: 0; padding: 0; font: 13px Arial,Helvetica,sans-serif; color: #111; line-height:1.4em;} Now, let's add various other styles to cover more specialized text, like links and titles: a, a:link, a:visited { color: #666633; text-decoration: none;}a:hover, a:focus { text-decoration: underline;}h1.title, h1.title a, h1.title a:hover{ font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: normal; color: #666633; font-size: 200%; margin: 0; line-height: normal;}h1, h1 a, h1 a:hover { font-size: 140%; color: #444; font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0.5em 0;}h2, h2 a, h2 a:hover, .block h3, .block h3 a {font-size: 122%; color: #444; font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0.5em 0;}h3 { font-size: 107%;font-weight: bold;font-family: Verdana, Arial, Helvetica, sans-serif;}h4, h5, h6 {font-weight: bold; font-family: Verdana, Arial, Helvetica, sans-serif;}#logo-title { margin: 10px 0 0 0; position: relative; background-color: #eaebcd; height: 60px; border-top: 1px solid #676734; padding-top: 10px; padding-bottom: 10px; border-bottom: 1px solid #676734;}#site-name a, #site-name a:hover { font-family: Verdana, Arial, Verdana, Sans-serif; font-weight: normal; color: #000; font-size: 176%; margin-left: 20px; padding: 0;}#site-slogan { color: #676734; margin: 0; font-size: 90%; margin-left: 20px; margin-top: 10px;}.breadcrumb {padding-top: 0; padding-bottom: 10px;padding-left: 20px;}#content-header .title { padding-left: 20px;} After you have made the changes, above, remember to go back and comment out any competing definitions that may cause inheritance problems.
Read more
  • 0
  • 0
  • 1621
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-skinners-toolkit-plone-3-theming-part-2
Packt
20 Oct 2009
4 min read
Save for later

Skinner's Toolkit for Plone 3 Theming (Part 2)

Packt
20 Oct 2009
4 min read
(For more resources on Plone, see here.) Text editors The last key piece to successfully skinning a site is to choose a text editor or CSS editor that matches your needs and plays well with Plone. We are not talking about a word processor here, like Microsoft Word or Pages; rather, a text editor is a type of program used for editing plain text files. Text editors are often provided with operating systems or software development packages, and can be used to change configuration files and programming language source code. We'll look at a few of the more popular text editors that are appropriate for Plone development and theming. TextMate TextMate is a combination of text editor and programming tool that is exclusively for the Mac, and can be found at http://macromates.com. One of the key joys of working with TextMate is that it lets you open up an entire file structure at once to make navigation between related files easier. For Plone, this is essential. Your average file structure will look something like this: Rather than opening the entire buildouts folder, or even the plonetheme.copperriver folder, generally you only want to open the structure closest to the files you need in order to keep performance snappy—in this case, mybuildout[rockaway]/src/plonetheme.copperriver/plonetheme/copperriver/: As you can see, it opens the entire project in a clean interface with an easily navigable structure. Without this feature, skinning for Plone would be much more time-consuming. TextMate also offers numerous programmer-related tools: You can open two files at once (or more), and using the diff option you can compare the files easily Subversion (svn) support Ability to search and replace in a project Regular expression search and replace (grep) Auto-indent for common actions such as pasting text Auto-completion of brackets and other characters Clipboard history Foldable code blocks Support for more than 50 languages Numerous key combinations (for example, Apple + T opens a search window that makes it easy to locate a file) Themable syntax highlight colors Visual bookmarks to jump between places in a file Copy/paste of columns of text Bundles And much, much more The Bundle feature is one of the more interesting aspects of the tool. If you look at the HTML bundle, for example, it shows a list of common actions that you might wish to perform in a given document, and on the right, the code that spawns that action, and the hot-key that activates it. There's even a Zope/Plone TextMate support bundle found at http://plone.org/products/textmate-support that was developed by some of Plone's core developers. It enhances TextMate's already existing support for Python, XML, (X)HTML, CSS, and Restructured Text by adding features aimed specifically at the modern day Zope and Plone developer. For the geeks in the audience, the bundle's features include: Doctest support (restructured text with inline Python syntax and auto-indent of python code), pdb support (for debugging), ZCML support (no more looking up directives with our handy and exhaustive snippets), and a ZPT syntax that marries the best of both worlds (XML strictness with the goodness of TextMate's HTML support). This bundle plus TextMate's other capabilities make switching to developing for Plone on a Mac a good idea any day! As well as assigning a single key equivalent to a bundle item, it is possible to assign a tab trigger to the item. This is a sequence of text that you enter in the document and follow it by pressing the tab key. This will remove the sequence entered and then execute the bundle item. TextMate is full of hot-keys and features in general, yet it's surprisingly compact. Thankfully, the documentation is thorough. TextMate is a dream for themers and programmers alike. For those who are still new at CSS, another tool might be a good place to start, but for power users, TextMate is the primary tool of choice.
Read more
  • 0
  • 0
  • 3034

article-image-adding-interactive-course-material-moodle-19-part-3
Packt
20 Oct 2009
5 min read
Save for later

Adding Interactive Course Material in Moodle 1.9: Part 3

Packt
20 Oct 2009
5 min read
  Editing a Quiz Immediately after saving the Settings page, you are taken to the Editing Quiz page. This page is divided into five tabs. Each tab enables you to edit a different aspect of the quiz. This tab... Enables you to... Quiz Add questions to the quiz. Remove questions from the quiz. Arrange the questions in order. Create page breaks between questions. Assign a point value to each question. Assign a maximum point value to the quiz. Click into the editing page for each question. Questions Create a new question. Note that you must then add the new question to the quiz under the Quiz tab (see above). Also note that every question must belong to a category. Delete a question, not just from the quiz but from your site's question bank. Move a question from one category to another category. Click into the editing page for each question. Click into the editing page for each category. Categories Arrange the list of categories in order. Nest a category under another category (they become parent and subcategories). Publish a category, so that questions in that category can be used by other courses on the site. Delete a category (you must choose a new category to move the questions in the deleted category). Import Import questions from other learning systems. Import questions that were exported from Moodle. Export Export questions from Moodle, and save them in a variety of formats that Moodle and other learning systems can understand.       Create and Edit Question Categories Every question belongs to a category. You manage question categories under the Categories tab. There will always be a Default category. But before you create new questions, you might want to check to ensure that you have an appropriate category in which to put them. The categories which you can manage are listed on this page. To Add a New Category To add a new category, first select its Parent. If you select Top, the category will be a top-level category. Or, you can select any other category to which you have access, and then the new category will be a child of the selected category. In the Category field, enter the name for the new category. In the Category Info field, enter a description of the new category. The Publish field determines whether other courses can use the questions in this category. Click the Add button. To Edit a Category Next to the category, click the icon. The Edit categories page is displayed. You can edit the Parent, Category name, Category Info, and Publish setting. When you are finished, click the Update button. Your changes are saved and you are returned to the Categories page. Managing the Proliferation of Questions and Categories As the site administrator, you might want to monitor the creation of new question categories to ensure that they are logically named, don't have a lot of overlap, and are appropriate for the purpose of your site. As these question and their categories are shared among course creators, they can be a powerful tool for collaboration. Consider using the site-wide Teachers forum to notify your teachers, and course creators of new questions and categories. Create and Manage Questions You create and manage questions under the Questions tab. The collection of questions in your site is called the Question bank. As a teacher or the course creator, you have access to some or all the questions in the question bank. When you create questions, you add them to your site's question bank. When you create a quiz, you choose questions from the question bank for the quiz. Both these functions can be done on the same Editing Quiz page. Pay attention to which part of the page you are using—the one for creating new questions or the one for drawing question from the question bank. Display Questions from the Bank You can display questions from one category at a time. To select that category, use the Category drop-down list. If a question is deleted when it is still being used by a quiz, then it is not removed from the question bank. Instead, the question is hidden. The setting Also show old questions enables you to see questions that were deleted from the category. These deleted, or hidden, or old questions appear in the list with a blue box next to them. To keep your question bank clean, and to prevent teachers from using deleted questions, you can move all the deleted questions into a category called Deleted questions. Create the category Deleted questions and then use Also show old questions to show the deleted questions. Select them, and move them into Deleted questions. Move Questions between Categories To move a question into a category, you must have access to the target category. This means that the target category must be published, so that the teachers in all the courses can see it. Select the question(s) to move, select the category, and then click the Move to>> button: Create a Question To create a new question, from the Create new question drop-down list, select the type for the next question: This brings you to the editing page for the question: After you save the question, it is added to the list of questions in that category: Question Types The following chart explains the types of questions you can create, and gives some tips for using them.  
Read more
  • 0
  • 0
  • 1909

article-image-modifying-existing-theme-drupal-6-part-1
Packt
20 Oct 2009
10 min read
Save for later

Modifying an Existing Theme in Drupal 6: Part 1

Packt
20 Oct 2009
10 min read
Setting up the workspace There are several software tools that can make your work modifying themes more efficient. Though no specific tools are required to work with Drupal themes, there are a couple of applications that you might want to consider adding to your tool kit. I work with Firefox as my primary browser, principally due to the fact that I can add into Firefox various extensions that make my life easier. The Web Developer extension, for example, is hugely helpful when dealing with CSS and related issues. I recommend the combination of Firefox and the Web Developer extension to anyone working with Drupal themes. Another extension popular with many developers is Firebug, which is very similar to the Web Developer extension, and indeed more powerful in several regards. Pick up Web Developer, Firebug, and other popular Firefox add-ons at https://addons.mozilla.org/en-US/firefox/ When it comes to working with PHP files and the various theme files, you will need an editor. The most popular application is probably Dreamweaver, from Adobe, although any editor that has syntax highlighting would work well too. I use Dreamweaver as it helps me manage multiple projects and provides a number of features that make working with code easier (particularly for designers). If you choose to use Dreamweaver, you will want to tailor the program a little bit to make it easier to work with Drupal theme files. Specifically, you should configure the application preferences to open and edit the various types of files common to PHPTemplate themes. To set this up, open Dreamweaver, then: Go to the Preferences dialogue. Open file types/editors. Add the following list of file types to Dreamweaver's open in code view field: .engine.info.module.install.theme Save the changes and exit. With these changes, your Dreamweaver application should be able to open and edit all the various PHPTemplate theme files. Previewing your work Note that, as a practical matter, previewing Drupal themes requires the use of a server. Themes are really difficult to preview (with any accuracy) without a server environment. A quick solution to this problem is the XAMPP package. XAMPP provides a one step installer containing everything you need to set up a server environment on your local machine (Apache, MySQL, PHP, phpMyAdmin, and more). Visit http://www.ApacheFriends.org to download XAMPP and you can have your own Dev Server quickly and easily. Another tool that should be on the top of your list is the Theme developer extension for the popular Drupal Devel module. Theme developer can save you untold hours of digging around trying to find the right function or template. When the module is active, all you need to do is click on an element and the Theme developer pop-up window will show you what is generating the element, along with other useful information. In the example later in this article, we will also use another feature of the Devel module, that is, the ability to automatically generate sample content for your site. You can download Theme developer as part of the Devel project at Drupal.org: http://drupal.org/project/devel Note that Theme developer only works on Drupal 6 and due to the way it functions, is only suitable for use in a development environment—you don't want this installed on a client's public site! Visit http://drupal.org/node/209561 for more information on the Theme developer aspects of the Devel module. The article includes links to a screencast showing the module in action—a good quick start and a solid help in grasping what this useful tool can do. Planning the modifications We're going to base our work on the popular Zen theme. We'll take Zen, create a new subtheme, and then modify the subtheme until we reach our final goal. Let's call our new theme "Tao". The Zen theme was chosen for this exercise because it has a great deal of flexibility. It is a good solid place to start if you wish to build a CSS-based theme. The present version of Zen even comes with a generic subtheme (named "STARTERKIT") designed specifically for themers who wish to take a basic theme and customize it. We'll use the Starterkit subtheme as the way forward in the steps that follow. The Zen theme is one of the most active theme development projects. Updated versions of the theme are released regularly. We used version 6.x-1.0-beta2 for the examples in this article. Though that version was current at the time this text was prepared, it is unlikely to be current at the time you read this. To avoid difficulties, we have placed a copy of the files used in this article in the software archive that is provided on the Packt website. Download the files used in this article at http://www.packtpub.com/files/code/5661_Code.zip. You can download the current version of Zen at http://drupal.org/project/zen. Any time you set off down the path of transforming an existing theme into something new, you need to spend some time planning. The principle here is the same as in many other areas of life: A little time spent planning at the front end of a project can pay off big in savings later. A proper dissertation on site planning and usability is beyond the scope of this article; so for our purposes let us focus on defining some loose goals and then work towards satisfying a specific wish list for the final site functionality. Our goal is to create a two-column blog-type theme with solid usability and good branding. Our hypothetical client for this project needs space for advertising and a top banner. The theme must also integrate a forum and a user comments functionality. Specific changes we want to implement include: Main navigation menu in the right column Secondary navigation mirrored at the top and bottom of each page A top banner space below top nav but above the branding area Color scheme and fonts to match brand identity Enable and integrate the Drupal blog, forum, and comments modules In order to make the example easier to follow and to avoid the need to install a variety of third-party extensions, the modifications we will make in this article will be done using only the default components—excepting only the theme itself, Zen. Arguably, were you building a site like this for deployment in the real world (rather than simply for skills development) you might wish to consider implementing one or more specialized third-party extensions to handle certain tasks. Creating a new subtheme Install the Zen theme if you have not done so before now; once that is done we're ready to create a new subtheme. First, make a copy of the directory named STARTERKIT and place the copied files into the directory sites/all/themes. Rename the directory "tao". Note that in Drupal 5.x, subthemes were kept in the same directory as the parent theme, but for Drupal 6.x this is no longer the case. Subthemes should now be placed in their own directory inside the sites/all/themes/directory. Note that the authors of Zen have chosen to vary from the default stylesheet naming. Most themes use a file named style.css for their primary CSS. In Zen, however, the file is named zen.css. We need to grab that file and incorporate it into Tao. Copy the Zen CSS (zen/zen/zen.css) file. Rename it tao.css and place it in the Tao directory (tao/tao.css). When you look in the zen/zen directory, in addition to the key zen.css file, you will note the presence of a number of other CSS files. We need not concern ourselves with the other CSS files. The styles contained in those stylesheets will remain available to us (we inherit them as Zen is our base theme) and if we need to alter them, we can override the selectors as needed via our new tao.css file. In addition to renaming the theme directory, we also need to rename any other theme-name-specific files or functions. Do the following: Rename the STARTERKIT.info file to tao.info. Edit the tao.info file to replace all occurrences of STARTERKIT with tao. Open the tao.info file and find this copy: The name and description of the theme used on the admin/build/themes page. name = Zen Themer's StarterKit description = Read the <a href="http://drupal.org/node/226507">online docs</a> on how to create a sub-theme. Replace that text with this copy: The name and description of the theme used on the admin/build/themes page. name = Tao description = A 2-column fixed-width sub-theme based on Zen. Make sure the name= and description = content is not commented out, else it will not register. Edit the template.php file to replace all occurrences of STARTERKIT with tao. Edit the theme-settings.php file to replace all occurrences of STARTERKIT with tao. Copy the file zen/layout-fixed.css and place it in the tao directory, creating tao/layout-fixed.css. Include the new layout-fixed.css by modifying the tao.info file. Change style sheets[all][] = layout.css to style sheets[all][] = layout-fixed.css. The .info file functions similar to a .ini file: It provides configuration information, in this case, for your theme. A good discussion of the options available within the .info file can be found on the Drupal.org site at: http://drupal.org/node/171205 Making the transition from Zen to Tao The process of transforming an existing theme into something new consists of a set of tasks that can categorized into three groups: Configuring the Theme Adapting the CSS Adapting the Templates & Themable Functions Configuring the theme As stated previously, the goal of this redesign is to create a blog theme with solid usability and a clean look and feel. The resulting site will need to support forums and comments and will need advertising space. Let's start by enabling the functionality we need and then we can drop in some sample contents. Technically speaking, adding sample content is not 100% necessary, but practically speaking, it is extremely useful; let's see the impact of our work with the CSS, the templates, and the themable functions. Before we begin, enable your new theme, if you have not done so already. Log in as the administrator, then go to the themes manager (Administer | Site building | Themes), and enable the theme Tao. Set it to be the default theme and save the changes. Now we're set to begin customizing this theme, first through the Drupal system's default configuration options, and then through our custom styling. Enabling Modules To meet the client's functional requirements, we need to activate several features of Drupal which, although contained in the default distro, are not by default activated. Accordingly, we need to identify the necessary modules and enable them. Let's do that now. Access the module manager screen (Administer | Site building | Modules), and enable the following modules: Blog (enables blog-type presentation of content) Contact (enables the site contact forms) Forum (enables the threaded discussion forum) Search (enables users to search the site) Save your changes and let's move on to the next step in the configuration process.
Read more
  • 0
  • 0
  • 6765

article-image-delicious-tagometer-widget
Packt
20 Oct 2009
10 min read
Save for later

Delicious Tagometer Widget

Packt
20 Oct 2009
10 min read
Background Concept Delicious was founded by Joshua Schachter in 2003 and acquired by Yahoo in 2005. This website was formerly used to run in the domain http://del.icio.us hence known as del.icio.us. Now, this domain redirects to the domain http://delicious.com. This website got redesigned in July 2008 and the Delicious 2.0 went live with new domain, design and name. Delicious is probably one of the largest social bookmarking website in the WWW world for discovering, sharing and storing the interesting and useful URL on the Internet. When saving the URL, user can enter tags for the URL which is quite useful when you’ve to search the particular URL from many bookmarks. The number of saves of a particular URL in Delicious is one of the measurements for checking popularity of that URL. Delicious Tagometer As the name specifies, Delicious Tagometer is a badge which displays the tags as well count of the users who have saved the particular URL. Tagometer gets displayed in the web page which contains the code given below: <script src="http://static.delicious.com/js/blogbadge.js"></script> This is the new URL of the Tagometer badge from the Delicious. The URL for the Tagometer used to be different in the del.icio.us domain in past. For more information on future updates, you can check http://delicious.com/help. The delicious Tagometer looks as shown: As you can easily guess, the above Tagometer is placed on a web page whose URL has not yet been saved in Delicious. Now let’s take a look at the Tagometer which is placed on a web page whose URL is saved by many users of Delicious. In the above widget, the text “bookmark this on Delicious" is the hyperlink for saving the URL in delicious. To save an URL in Delicious, you have to provide the URL and give a Title on the http://delicious.com/save page. After clicking on the “bookmark this on Delicious” hyperlink on the Delicious Tagometer widget you can see the image of the web page on delicious. The Delicious Tagometer widget also shows the list of tags which are used by the users of Delicious to save the URL. Each of these tags link to a tag specific page of Delicious. For example, an URL saved with tag JavaScript can be found on the page http://delicious.com/tag/javascript. And, the number is linked to the URL specific page on Delicious. For example, if you wish to view the users and their notes on the saves of the URL- http://digg.com, then the URL of delicious will be http://delicious.com/url/926a9b7a561a3f650ff41eef0c8ed45d The last part “926a9b7a561a3f650ff41eef0c8ed45d” is the md5 hash of the URL http://digg.com. The md5 is a one way hashing algorithm which converts a given string to a 32 character long string known as md5 digest. This hashed string can’t be reversed back into original string.  The md5 function protects and ensures data integrity of Delicious Data Feeds. Delicious data feeds are read-only web feeds containing bookmark information and other information which can be used third party websites. These feeds are available into two different format: RSS and JSON. Among the various data feeds on the Delicious, let’s look at the details of the data feed which contains summary information of a URL. According to Delicious feed information page, these data feed for URL information can be retrieved via following call, http://feeds.delicious.com/v2/json/urlinfo/{url md5} It clearly specifies summary of URL can be retrieved in the json format only from Delicious. To get the summary about a URL, You can provide the actual URL in the url parameter of the above URL. Alternatively, you can provide md5() hash of the url in the hash parameter in the above URL. Now, let’s look at feed URLs which can be used to access the summary of the http://digg.com from Delicious: http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&url=http://digg.com OR http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&hash=926a9b7a561a3f650ff41eef0c8ed45d From the above URLs, it is clear that md5 hash of the string "http://digg.com" is 926a9b7a561a3f650ff41eef0c8ed45d When JSON is used as the format of data returned form Delicious feed then you must specify the JavaScript callback function to handle the JSON data. Now, let look at the JSON data which is returned from any of the above URL of Delicious feed. displayTotalSaves([{"hash":"926a9b7a561a3f650ff41eef0c8ed45d","title":"digg", "url":"http://digg.com/","total_posts":51436,"top_tags":{"news":23581, "digg":10771,"technology":10713,"blog":8628,"web2.0":7800, "tech":6459,"social":5436,"daily":5173,"community":4477,"links":2512}}]) As you can see clearly, the above JSON data contains hash of URL, the URL itself, total no of saves in Delicious in total_posts variable. Along with them, different tags including number of times that tag is used by different users of Delicious for saving the URL  http://digg.com. If the URL is not saved in Delicious then data returned from Delicious feed will be like this : displayTotalSaves([]) Now, having understod the information returned above, let’s see how to create Delicious widget step by step. Creating Delicious Tagometer Widget Our Delicious Tagometer widget looks very similar to actual Delicious Tagometer widget but has different format and texts. In the Tagometer badge provided by delicious, there is no option for specifying a particular URL whose summary is to be displayed. It automatically displays the details of the URL of the web page containing the code. While in our custom widget, you can also specify the URL explicitly in the badge which is an optional parameter. For creating this widget, we will use JavaScript, CSS, XHTML and Delicious’s data feed in JSON format. The above image is of the Delicious widget which we’re going to make and you can see clearly that the provided URL is not yet saved on Delicious. Now, let’s look at the Custom Delicious Tagometer which we can see for a URL saved on the delicious. The above badge of delicious is displayed for the URL: http://yahoo.com. Writing Code for Delicious First of all, let’s start looking at the JavaScript code for handling the parameters-url and title of the web page, when it is not provided. If these parameters are not defined explicitly then url and title of the web page using the widget is provided for saving the bookmark. if(typeof delicious_widget_url!='undefined') delicious_widget_url=encodeURIComponent(delicious_widget_url);else delicious_widget_url=encodeURIComponent(document.location);if(typeof delicious_widget_title!='undefined') delicious_widget_title=encodeURIComponent(delicious_widget_title);else delicious_widget_title=encodeURIComponent(document.title); As can be seen from the above code, if the variable delicious_widget_url is not defined already then the URL of the current document encoded with encodeURIComponent() function is assigned to this variable. If delicious_widget_url variable is already defined then it is encoded with encodeURIComponent() function and assigned to the same variable. The typeof JavaScript operator can be used for checking the type of variable and also serves a very useful purpose of checking whether the variable or function is already defined or not. For example, the statement: typeof xyz==’function’ returns true if the function xyz is already defined. Similarly, if the variable delicious_widget_title is not defined then document.title, which contains title of current web page, is encoded with encodeURIComponent() function and assigned to the delicious_widget_title variable . Next, a variable del_rand_number is defined for handling multiple instances of the widget. var del_rand_number=Math.floor(Math.random()*1000); The Math.random() function returns random values between 0 to 1 and when multiplied by 1000 results in a random number between 1 to 1000. Since this random number is a  floating point number hence floor() function of JavaScript Math Object is used for converting it to the greatest whole number which is less than or equal to generated random number. The Math object of JavaScript has three different functions which can be used to convert a floating point number to whole number:Math.floor(float_val) – converts to greatest integer less than or equal to float_val.Math.ceil(float_val) – converts to smallest integer grater than or equal to float_val.Math.round(float_val) – converts to nearest integer. If the decimal portion of float_val is greater than or equal to .5 then the resulting integer is the next whole number otherwise resulting number is rounded to the nearest integer less than float_val. After that, now using above random number let’s define a variable which holds the “id” of the element in widget for displaying total no. of saves and tags. var del_saved_id="delicious-saved-"+del_rand_number; Now, let’s look at the initWidget() function for initializing the widget. function initWidget(){ //write the elements needed for widget writeWidgetTexts(); //now attach the stylesheet to the document var delCss=document.createElement("link"); delCss.setAttribute("rel", "stylesheet"); delCss.setAttribute("type", "text/css"); delCss.setAttribute("href", "http://yourserver.com/delicious/delicious.css"); document.getElementsByTagName("head")[0].appendChild(delCss); //now call the script of delicious var delScript = document.createElement("script"); delScript.setAttribute("type", "text/javascript"); delScript.setAttribute("src", "http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&url="+delicious_widget_url); //alert(delicious_widget_url); document.getElementsByTagName("head").item(0).appendChild(delScript); } At the start of the above code, the function writeWidgetTexts(); is called for writing the content of widget. The functions createElement() and setAttribute() are DOM manipulation function for creating a element and adding attribute to the element respectively. So, the next four statements of the above function create link element and sets various attributes for attaching CSS document to the page using widget. Once link element is created and various attribute is assigned to it the next step is to append it to the document using widget, which is done with appendChild() function in the next line of above function. getElementsByTagName() is a DOM function for accessing the document by the name of tag. Unlike getElementById() which access single element in the document, getElementsByTagName() can access multiple elements of DOM with the help of index. For example, document.getElementsByTagName("div")[0] or document.getElementsByTagName("div").item(0) refers to the first division element of the document Similarly, script element is created for getting JSON feed from Delicious. The call back JavaScript function displayTotalSaves() is used for handling JSON data returned from Delicious.
Read more
  • 0
  • 0
  • 1757
article-image-authentication-and-authorization-modx
Packt
20 Oct 2009
1 min read
Save for later

Authentication and Authorization in MODx

Packt
20 Oct 2009
1 min read
It is vital to keep this distinction in mind to be able to understand the complexities explained in this article. You will also learn how MODx allows grouping of documents, users, and permissions. Create web users Let us start by creating a web user. Web users are users who can access restricted document groups in the web site frontend; they do not have Manager access. Web users can identify themselves at login by using login forms. They are allowed to log in from the user page, but they cannot log in using the Manager interface. To create a web user, perform the following steps: Click on the Web Users menu item in the Security menu. Click on New Web User. Fill in the fields with the following information: Field Name Value Username samira Password samira123 Email Address xyz@configurelater.com    
Read more
  • 0
  • 0
  • 2941

article-image-implementing-workflow-alfresco-3
Packt
20 Oct 2009
5 min read
Save for later

Implementing Workflow in Alfresco 3

Packt
20 Oct 2009
5 min read
Workflow is the automation of a business process, during which documents are passed from one participant to another for action, according to a set of procedural rules. Every Content Management System implementation has its own workflow requirements. For some companies, workflow could be a simple approval process. For some companies, it could be a complex business process management system. Workflow provides ownership and control over the content and processes. Introduction to the Alfresco workflow process Alfresco includes two types of out of the box workflow. The first is the Simple Workflow, which is content-oriented, and the other is the Advanced Workflow, which is task-oriented. The Simple Workflow process in Alfresco involves the movement of documents through various spaces.A content item is moved or copied to a new space at which point a new workflow instance is attached, which is based on the workflow definition of the space. A workflow definition is unaware of other related workflow definitions. The Advanced Workflow process is task-oriented, where you create a task, attach documents that are to be reviewed, and assign it to appropriate reviewers. The same robust workflow capabilities are available in Document Management (DM), Records Management (RM), Web Content Management (WCM), and throughout our applications, which includes Alfresco Share. You can use the out of the box features provided by both types of workflow, or you can create your own custom advanced workflow, according to the business processes of your organization. Simple Workflow Consider a purchase order that moves through various departments for authorization and eventual purchase. To implement Simple Workflow for this in Alfresco, you will create spaces for each department and allow documents to move through various department spaces. Each department space is secured, only allowing the users of that department to edit the document and to move it to the next departmental space in the workflow process. The workflow process is so flexible that you could introduce new steps for approval into the operation without changing any code. Out of the box features Simple Workflow is implemented as an aspect that can be attached to any document in a space through the use of business rules. Workflow can also be invoked on individual content items as actions. Workflow has two steps. One is for approval while the other one is for rejection. You can refer to the upcoming image, where workflow is defined for the documents in a space called Review Space. The users belonging to the Review Space can act upon the document. If they choose to Reject, then the document moves to a space called Rejected Space. If they choose to Approve, then the document moves to a space called Approved Space. You can define the names of the spaces and the users on the spaces, according to your business requirements. The following figure gives a graphical view of the Approved Space and the Rejected Space: Define and use Simple Workflow The process to define and use Simple Workflow in Alfresco is as follows: Identify spaces and set security on those spaces Define your workflow process Add workflow to content in those spaces, accordingly Select the email template and the people to send email notifications to Test the workflow process Let us define and use a Simple Workflow process to review and approve the engineering documents on your intranet. Go to the Company Home > Intranet > Engineering Department space and create a space named ProjectA by using an existing Software Engineering Project space template. Identify spaces and security If you go to the Company Home > Intranet > Engineering Department > ProjectA > Documentation space, then you will notice the following sub-spaces: Samples: This space is for storing sample project documents. Set the security on this space in such a way that only the managers can edit the documents. Drafts: This space contains initial drafts and documents of ProjectA that are being edited. Set the security in such a way that only a few selected users (such as Engineer1, Engineer2— as shown in the upcoming image) can add or edit the documents in this space. Pending Approval: This space contains all of the documents that are under review. Set the security in such a way that only the Project Manager of ProjectA can edit these documents. Published: This space contains all of the documents that are Approved and visible to others. Nobody should edit the documents while they are in the Published space. If you need to edit a document, then you need to Retract it to the Drafts space and follow the workflow process, as shown in the following image:    Defining the workflow process Now that you have identified the spaces, the next step is to define your workflow process. We will add workflow to all of the documents in the Drafts space. When a user selects the Approve action called Submit for Approval on a document, then the document moves from the Drafts space to the Pending Approval space. We will add workflow to all of the documents in the Pending Approval space. When a user selects the Approve action called Approved on a document, then the document moves from the Pending Approval space to the Published space. Similarly, when a user selects the Reject action called Re-submit on a document, then it moves from the Pending Approval space to the Drafts space. We will add workflow to all of the documents in the Published space. When a user selects the Reject action called Retract on a document, then it moves from the Published space to the Drafts space. You can have review steps and workflow action names according to your business's requirements.
Read more
  • 0
  • 0
  • 2474

article-image-date-and-calendar-module-drupal-5-part-1
Packt
20 Oct 2009
5 min read
Save for later

Date and Calendar Module in Drupal 5: Part 1

Packt
20 Oct 2009
5 min read
Recipe 33: Understanding Date formats Drupal dates are typically stored in one of two ways. Core Drupal dates—including Node: Created Time, and Node: Updated Time—are stored as Unix timestamps. Contributed module date fields can be stored as either a timestamp or a format known as ISO. Neither style is particularly friendly to human readers, so both field types are usually formatted before users see them. This recipe offers a tour of places in Drupal where dates can be formatted and information on how to customize the formats. What's that Lucky Day?The Unix timestamp 1234567890 fell on Friday the 13th, in February, 2009. This timestamp marks 1,234,567,890 seconds since January 1, 1970. The same date/time combination would be stored in a date field in ISO format as 2009-02-13T23:31:30+00:0. ISO is an abbreviation for the International Organization for Standardization Opening the browser windows side-by-side will help you understand date formatting. In the left window, open YOURSITE.com/admin/settings/ date-time to view the settings page for date and time. In the right window, open the API page of code that defines these system date time settings at http://api.drupal.org/api/function/system_date_time_settings/5. Compare each item in the $datemedium array, for instance, with the associated Medium date format drop-down. a – am/pm D – Day, Mon through Sun d – Date, 01 to 31 (with leading zeroes) F – Month, January through December (mnemonic, F = Full name) g – Hours, 1 through 12 H – Hours, 00 through 23 i – Minutes, 00 to 59 j – Date, 1 to 31 (No leading zeroes) l – Sunday through Saturday m – Month, 01 through 12 M – Month, Jan through Dec s – Seconds, 00 through 59 (with leading zeroes) S – Month Suffix, st, nd, rd, or th. Works well with j Y – Year, Examples: 1999 or 2011 Below is the list of codes for many commonly used date and time formats. A more comprehensive list appears at http://us.php.net/date. Explore Drupal places where these codes may be used. The first four locations in the table below are available in the Drupal administrative interface. The last three involve editing files on the server—these edits are completely optional. Location Details CCK field setup Custom Input formats admin/content/types/story/add_field   After the field widget is specified admin/content/types/<CONTENTTYPE>/fields/field_<FIELDNAME> Near the top of the page.   Near the bottom of the page:   Formatting Fields in Views. admin/build/views/<VIEW_NAME>/edit CCK Date fields are set via the Options drop-down in the Fields fieldset.   Custom date formats for core fields, such as Node: Created Time are set via handler and options from elements.   Default Date and Time settings admin/settings/date-time Set the default time zone, Short, Medium, and Long date formats, and the first day of the week.   Post Settings This may be one of the harder-to-find settings in Drupal, enabling the Post settings to be turned-off for specified content types. (An example of a post setting would be: Submitted by admin on Sun, 10/12/2008 - 4:55pm. The setting is found on the right-hand side of this URL: admin/build/themes/settings Use the following mouse click trail to get to this URL: Administer | Site Building | Themes | Configure (Click on the Configure tab at the top of the page. If you click on the Configure link in the Operations column, you will still need to click the Configure tab at the top to get to the global settings.)   Variable overrides in settings.php You may override variables at the bottom of the /sites/default/settings.php file. Remove the appropriate pound signs to enable the $conf array, and add a setting as shown below. Note that this is a quick way to modify the post settings format, which draws from the medium date variable. $conf = array( #   'site_name' => 'My Drupal site', #   'theme_default' => 'minnelli', #   'anonymous' => 'Visitor', 'date_format_medium' => 'l F d, Y'  ); *.tpl.php files Examples: node-story.tpl.php <?php print format_date($node->created, 'custom', 'F Y'); ?> comment.tpl.php <?php echo t('On ') . format_date($comment->timestamp,   'custom'  , 'F jS, Y'); ?> <?php echo theme('username',   $comment) . t(' says:'); ?> template.php Redefine $variables['submitted'] Example from blommor01 theme:   $vars['submitted'] =  t('!user - <abbr class="created"   title="!microdate">!date</abbr>', array(    '!user' => theme('username', $vars['node']),    '!date' => format_date($vars['node']->created),    '!microdate' => format_date($vars['node']->   created,'custom', "Y-m-dTH:i:sO")   )); Recipe notes Note that when using the PHP date codes, additional characters may be added, including commas, spaces, and letters. In the template.php example, a backslash was used to show that the letter 'T' will be printed, rather than the formatted return values. Below are more examples of added characters: F j, Y, g:i a // August 27, 2010, 5:16 pmm.d.y // 08.27.10 You may occasionally find that an online date converter comes in handy. http://www.timestampconverterer.com/ (this URL includes the word "converter" followed by another "er"). http://www.coryking.com/date-converter.php
Read more
  • 0
  • 0
  • 2719
article-image-debugging-rest-web-services
Packt
20 Oct 2009
13 min read
Save for later

Debugging REST Web Services

Packt
20 Oct 2009
13 min read
(For more resources on this subject, see here.) Message tracing The first symptom that you will notice when you are running into problems is that the client would not behave the way you want it to behave. As an example, there would be no output, or the wrong output. Since the outcome of running a REST client depends on the request that you send over the wire and the response that you receive over the wire, one of the first things is to capture the messages and verify that those are in the correct expected format. REST Services and clients interact using messages, usually in pairs of request and response. So if there are problems, they are caused by errors in the messages being exchanged. Sometimes the user only has control over a REST client and does not have access to the implementation details of the service. Sometimes the user will implement the REST service for others to consume the service. Sometimes the Web browser can act as a client. Sometimes a PHP application on a server can act as a REST client. Irrespective of where the client is and where the service is, you can use message capturing tools to capture messages and try to figure out the problem. Thanks to the fact that the service and client use messages to interact with each other, we can always use a message capturing tool in the middle to capture messages. It is not that we must run the message capturing tool on the same machine where the client is running or the service is running; the message capturing tool can be run on either machine, or it can be run on a third machine. The following figure illustrates how the message interaction would look with a message capturing tool in place. If the REST client is a Web browser and we want to capture the request and response involved in a message interaction, we would have to point the Web browser to message capturing tool and let the tool send the request to the service on behalf of the Web browser. Then, since it is the tool that sent the request to the service, the service would respond to the tool. The message capturing tool in turn would send the response it received from the service to the Web browser. In this scenario, the tool in the middle would gain access to both the request and response. Hence it can reveal those messages for us to have a look. When you are not seeing the client to work, here is the list of things that you might need to look for: If the client sends a message If you are able to receive a response from a service If the request message sent by the client is in the correct format, including HTTP headers If the response sent by the server is in the correct format, including the HTTP headers In order to check for the above, you would require a message-capturing tool to trace the messages. There are multiple tools that you can use to capture the messages that are sent from the client to the service and vice versa. Wireshark (http://www.wireshark.org/) is one such tool that can be used to capture any network traffic. It is an open-source tool and is available under the GNU General Public License version 2. However this tool can be a bit complicated if you are looking for a simple tool. Apache TCPMon (http://ws.apache.org/commons/tcpmon/) is another tool that is designed to trace web services messages. This is a Java based tool that can be used with web services to capture the messages. Because TCPMon is a message capturing tool, it can be used to intercept messages sent between client and service, and as explained earlier, can be run on the client machine, the server machine or on a third independent machine. The only catch is that you need Java installed in your system to run this tool. You can also find a C-based implementation of a similar tool with Apache Axis2/C (http://ws.apache.org/axis2/c). However, that tool does not have a graphical user interface. There is a set of steps that you need to follow, which are more or less the same across all of these tools, in order to prepare the tool for capturing messages. Define the target host name Define the target port number Define the listen port number Target host name is the name of the host machine on which the service is running. As an example, if we want to debug the request sent to the Yahoo spelling suggestion service, hosted at http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion, the host name would be search.yahooapis.com. We can either use the name of the host or we can use the IP address of the host because the tools are capable of dealing with both formats in place of the host name. As an example, if the service is hosted on the local machine, we could either use localhost or 127.0.0.1 in place of the host name. Target port number is the port number on which the service hosting web server is listening; usually this is 80. As an example, for the Yahoo spelling suggestion service, hosted at http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion, the target port number is 80. Note that, when the service URL does not mention any number, we can always use the default number. If it was running on a port other than port 80, we can find the port number followed by the host name and preceded with character ':'. As an example, if we have our web server running on port 8080 on the local machine, we would have service URL similar to http://localhost:8080/rest/04/library/book.php. Here, the host name is localhost and the target port is 8080. Listen port is the port on which the tool will be listening to capture the messages from the client before sending it to the service. For an example, say that we want to use port 9090 as our listen port to capture the messages while using the Yahoo spelling suggestion service. Under normal circumstances, we will be using a URL similar to the following with the web browser to send the request to the service. http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion?appid=YahooDemo&query=apocalipto When we want to send this request through the message capturing tool and since we decided to make the tools listen port to be 9090 with the tool in the middle and assuming that the tool is running on the local machine, we would now use the following URL with the web browser in place of the original URL. http://localhost:9090/WebSearchService/V1/spellingSuggestion?appid=YahooDemo&query=apocalipto Note that we are not sending this request directly to search.yahooapis.com, but rather to the tool listening on port 9090 on local host. Once the tool receives the request, it will capture the request, forward that to the target host, receive the response and forward that response to the web browser. The following figure shows the Apache TCPMon tool. You can see localhost being used as the target host, 80 being the target port number and 9090 being the listening port number. Once you fill in these fields you can see a new tab being added in the tool showing the messages being captured. Once you click on the Add button, you will see a new pane as shown in the next figure where it will show the messages and pass the messages to and from the client and service. Before you can capture the messages, there is one more step. That is to change the client code to point to the port number 9090, since our monitoring tool is now listening on that port. Originally, we were using port 80 $url = 'http://localhost:80/rest/04/library/book.php'; or just $url = 'http://localhost/rest/04/library/book.php'; because the default port number used by a web server is port 80, and the client was directly talking to the service. However, with the tool in place, we are going to make the client talk to the tool listening on port 9090. The tool in turn will talk to the service. Note that in this sample we have all three parties, the client, the service, and the tool running on the same machine. So we will keep using localhost as our host name. Now we are going to change the service endpoint address used by the client to contain port 9090. This will make sure that the client will be talking to the tool. $url = 'http://localhost:9090/rest/04/library/book.php'; As you can see, the tool has captured the request and the response. The request appears at the top and the response at the bottom. The request is a GET request to the resource located at /rest/04/library/book.php. The response is a success response, with HTTP 200 OK code. And after the HTTP headers, the response body, which is in XML follows. As mentioned earlier, the first step in debugging is to verify if the client has sent a request and if the service responded. In the above example, we have both the request and response in place. If both were missing then we need to check what is wrong on either side. If the client request was missing, you can check for the following in the code. Are you using the correct URL in client Have you written the request to the wire in the client? Usually this is done by the function curl_exec when using Curl If the response was missing, you can check for the following. Are you connected to the network? Because your service can be hosted on a remote machine Have you written a response from the service? That is, basically, have you returned the correct string value from the service? In PHP wire, using the echo function to write the required response to the wire usually does this. If you are using a PHP framework, you may have to use the framework specific mechanisms to do this. As an example, if you are using the Zend_Rest_Server class, you have to use handle() method to make sure that the response is sent to the client. Here is a sample error scenario. As you can see, the response is 404 not found. And if you look at the request, you see that there is a typo in the request. We have missed 'k' from our resource URL, hence we have sent the request to /rest/04/library/boo.php, which does not exist, whereas the correct resource URL is /rest/04/library/book.php. Next let us look at the Yahoo search example that was discussed earlier to identify some advanced concepts. We want to capture the request sent by the web browser and the response sent by the server for the request. http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion?appid=YahooDemo&ampquery=apocalipto. As discussed earlier, the target host name is search.yahooapis.com. The target port number is 80. Let's use 9091 as the listen. Let us use the web browser to send the request through the tool so that we can capture the request and response. Since the tool is listening on port 9091, we would use the following URL with the web browser. http://localhost:9091/WebSearchService/V1/spellingSuggestion?appid=YahooDemo&ampquery=apocalipto When you use the above URL with the web browser, the web browser would send the request to the tool and the tool will get the response from the service and forward that to the web browser. We can see that the web browser gets the response. However, if we have a look at the TCPMon tool's captured messages, we see that the service has sent some binary data instead of XML data even though the Web browser is displaying the response in XML format. So what went wrong? In fact, nothing is wrong. The service sent the data in binary format because the web browser requested that format. If you look closely at the request sent you will see the following. GET /WebSearchService/V1/spellingSuggestion?appid=YahooDemo&query=apocalipto HTTP/1.1Host: search.yahooapis.com:9091User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5Accept-Language: en-us,en;q=0.7,zh-cn;q=0.3Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Connection: keep-alive In the request, the web browser has used the HTTP header. Accept-Encoding: gzip,deflate This tells the service that the web browser can handle data that comes in gzip compressed format. Hence the service sends the data compressed to the web browser. Obviously, it is not possible to look into the XML messages and debug them if the response is compressed. Hence we should ideally capture the messages in XML format. To do this, we can modify the request message on the TCPMon pane itself and resend the message. First remove the line Accept-Encoding: gzip,deflate Then click on the Resend button. Once we click on the Resend button, we will get the response in XML format. Errors in building XML While forming XML as request payload or response payload, we can run into errors through simple mistakes. Some would be easy to spot but some are not. Most of the XML errors could be avoided by following a simple rule of thumb-each opening XML tag should have an equivalent closing tag. That is the common mistake that can happen while building XML payloads. In the above diagram, if you look carefully in the circle, the ending tag for the book element is missing. A new starting tag for a new book is started before the first book is closed. This would cause the XML parsing on the client side to fail. In this case I am using the Library system sample and here is the PHP source code causing the problem. echo "<books>";while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { echo "<book>"; foreach ($line as $key => $col_value) { echo "<$key>$col_value</$key>"; } //echo "</book>";}echo "</books>"; Here I have intentionally commented out printing the closing tag to demonstrate the error scenario. However, while writing this code, I could have missed that as well, causing the system to be buggy. While looking for XML related errors, you can use the manual technique that we just used. Look for missing tags. If the process looks complicated and you cannot seem to find any XML errors in the response or request that you are trying to debug, you can copy the XML captured with the tool and run it through an XML validator tool. For example, you can use an online tool such as http://www.w3schools.com/XML/xml_validator.asp. You can also check if the XML file is well formed using an XML parser
Read more
  • 0
  • 0
  • 5013

article-image-working-drupal-audio-flash-part-1
Packt
20 Oct 2009
7 min read
Save for later

Working with Drupal Audio in Flash (part 1)

Packt
20 Oct 2009
7 min read
Within the past five years, there has been a major change in the type of content found on the World Wide Web. In just a few short years, content has evolved from being primarily text and images, into a multimedia experience! Drupal contributors have put much effort in making this integration with multimedia as easy as possible. However, one issue still remains: in order to present multimedia to your users, you cannot rely on Drupal alone. You must have another application layer to present that media. This is most typically a Flash application that allows the user to listen or watch that media from within their web browser. This article explores how to use Drupal to manage a list of audio nodes and also builds a Flash application to play that music. When it comes to multimedia, Flash is the portal of choice for playing audio on a web sites. Integrating audio in Drupal is surprisingly easy, thanks to the contribution of the Audio module. This module allows you to upload audio tracks to your Drupal website (typically in MP3 format), by creating an Audio node. It also comes with a very basic audio player that will play those audio tracks in the node that was created. To start, let's download and enable the Audio module along with the Token, Views, and getID3 modules, which are required for the Audio module. The modules that you will need to download and install are as follows: Audio—http://www.drupal.org/project/audio Views—http://www.drupal.org/project/views Token—http://www.drupal.org/project/token getID3—http://www.drupal.org/project/getid3 At the time of writing this article, the Audio module was still considered "unstable". Because of this, I would recommend downloading the development version until a stable release has been made. It is also recommended to use the development or "unstable" versions for testing purposes only. Once we have downloaded these modules and placed them in our site's modules folder, we can enable the Audio module by first navigating to the Administer | Modules section, and then enabling the checkboxes in the Audio group as follows: After you have enabled these modules, you will probably notice an error at the top of the Administrator section that says the following: This error is shown because we have not yet installed the necessary PHP library to extract the ID3 information from our audio files. The ID3 information is the track information that is embedded within each audio file, and can save us a lot of time from having to manually provide that information when attaching each audio file to our Audio nodes. So, our next step will be to install the getID3 library so that we can utilize this great feature. Installing the getID3 library The getID3 library is a very useful PHP library that will automatically extract audio information (called ID3) from any given audio track. We can install this useful utility by going to http://sourceforge.net/project/showfiles.php?group_id=55859, which is the getID3 library URL at SourceForge.net. Once we have done this, we should see the following: We can download this library by clicking on the Download link on the first row, which is the main release. This will then take us to a new page, where we can download the ZIP package for the latest release. We can download this package by clicking on the latest ZIP link, which at the time of writing this article was getid3-1.7.9.zip Once this package has finished downloading, we then need to make sure that we place the extracted library on the server where the getID3 module can use it. The default location for the getID3 module, for this library, is within our site's modules/getid3 directory. Within this directory, we will need to create another directory called getid3, and then place the getid3 directory from the downloaded package into this directory. To verify that we have installed the library correctly, we should have the getid3.php at the following location: Our next task is to remove the demos folder from within the getid3 library, so that we do not present any unnecessary security holes in our system. Once this library is in the correct spot, and the demos folder has been removed, we can refresh our Drupal Administrator section and see that the error has disappeared. If it hasn't, then verify that your getID3 library is in the correct location and try again. Now that we have the getID3 library installed, we are ready to set up the Audio content type. Setting up the Audio content type When we installed the Audio module, it automatically created an Audio content type that we can now use to add audio to our Drupal web site. But before we add any audio to our web site, let's take a few minutes to set up the Audio content type to the way we want it. We will do so by navigating to Administer | Content Types, and then clicking on the edit link, next to the Audio content type. Our goal here is to set up the Audio content type so that the default fields make sense to the Audio content type. Drupal adds the Body field to all new content types, which doesn't make much sense when creating an Audio content. We can easily change this by simply expanding the Submission form settings. We can then replace the Body label with Description, since it is easily understood when adding new Audio tracks to our system. We will save this content type by clicking on the Save content type button at the bottom of the page. Now, we are ready to start adding audio content to our Drupal web site. Creating an Audio node We will add audio content by going to Create Content, and then clicking on Audio, where we should then see the following on the page: You will probably notice that the Title of this form has already been filled out with some strange looking text (as shown in the previous screenshot). This text is a series of tags, which are used to represent track information that is extracted using the getID3 module that we installed earlier. Once this ID3 information is extracted, these tags will be replaced with the Title and Artist of that track, and then combined to form the title of this node. This will save a lot of time because we do not have to manually provide this information when submitting a new audio track to our site. We can now upload any audio track by clicking on the Browse button next to the Add a new audio file field. After it adds the file to the field, we can submit this audio track to Drupal by clicking on the Save button at the bottom of the page, which will then show you something like the following screenshot: After this node has been added, you will notice that there is a player already provided to play the audio track. Although this player is really cool, there are some key differences between the player provided by the Audio module and the player that we will create later in this article. How our player will be different (and better) The main difference between the player that is provided by the Audio module and the player that we are getting ready to build is how it determines which file to play. In the default player, it uses flash variables passed to the player to determine which file to play. This type of player-web site interaction places the burden on Drupal to provide the file that needs to be played. In a way, the default player is passive, where it does nothing unless someone tells it to do something. The player that we will be building is different because instead of Drupal telling our player what to play, we will take an active approach and query Drupal for the file we wish to play. This has several benefits, such as that the file path does not have to be exposed to the public in order for it to be played. So, let's create our custom player!
Read more
  • 0
  • 0
  • 2640
Modal Close icon
Modal Close icon