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

How-To Tutorials - CMS & E-Commerce

830 Articles
article-image-adding-flash-your-wordpress-theme
Packt
24 Dec 2009
11 min read
Save for later

Adding Flash to your WordPress Theme

Packt
24 Dec 2009
11 min read
Adobe Flash—it's come quite a long way since my first experience with it as a Macromedia product (version 2 in 1997). Yet still, it does not adhere to W3C standards, requires a plugin to view, and above all, is a pretty pricey proprietary product. So why is everyone so hot on using it? Love it or hate it, Flash is here to stay. It does have a few advantages that we'll take a quick look at. The Flash player plugin does boast the highest saturation rate around (way above other media player plugins) and it now readily accommodates audio and video, as video sites such as You Tube take advantage of it. It's pretty easy to add and upgrade for all major browsers. The price may seem prohibitive at first, but after the initial purchase, additional upgrades are reasonably priced. Plus, many third-party software companies offer very cheap authoring tools that allow you to create animations and author content using the Flash player format. (In most cases, no one needs to know you're using the $50 version of Swish and not the $800 Flash CS3 to create your content.) Above all, it can do so much more than just playing video and audio (like most plugins). You can create seriously rich and interactive content, even entire applications with it, and the best part is, no matter what you create with it, it is going to look and work exactly the same on all browsers and platforms. These are just a few of the reasons why so many developers chose to build content and applications for the Flash player. Oh, and did I mention you can easily make awesome, visually slick, audio-filled stuff with it? Yeah, that's why your client wants you to put it in their site. Flash in your theme A commonly requested use of Flash is usually in the form of a snazzy header within the theme of the site, the idea being that various relevant and/or random photographs or designs load into the header with some supercool animation (and possibly audio) every time a page loads or a section changes. I'm going to assume if you're using anything that requires the Flash player, you're pretty comfortable with generating content for it. So, we're not going to focus on any Flash timeline tricks or ActionScripting. We'll simply cover getting your Flash content into your WordPress theme. For the most part, you can simply take the HTML object embed code that Flash (or other third-party tools) will generate for you and paste it into the header area of your WordPress index.php or header.php template file. Handling users without Flash, older versions of Flash, and IE6 users While the previous method is extremely clean and simple, it doesn't help all of your site's users in dealing with Flash. What about users who don't have Flash installed or have an older version that won't support your content? What about IE users who have the Active X restrain? You'll want your site and theme to gracefully handle users who do not have Flash (if you've used the overlay method, they'll simply see the CSS background image and probably not know anything is wrong!) or an older version of Flash that doesn't support the content you wish to display. This method lets you add in a line of text or a static image as an alternative, so people who don't have the plugin/correct version installed are either served up alternative content and they're none-the-wiser, or served up content that nicely explains that they need the plugin and directs them towards getting it. Most importantly, this method also nicely handles IE's ActiveX restrictions. Is the ActiveX restriction still around? In 2006, the IE browser upped its security, so users had to validate content that shows up in the Flash player (or any player) via Microsoft's ActiveX controls). Your Flash content starts to play, but there's a "grey outline" around the player area which may or may not mess up your design. If your content is interactive, then people will need to click to activate it. This is annoying, but the main workaround involved "injecting" controls and players via JavaScript. Essentially, you need to include your Flash content via a JavaScript include file. As of April 2008, this restriction was reverted, but only if your user has updated their browser; chances are, if they intent on still using IE6 or 7, they haven't done this update. Regardless of whether you are concerned about ActiveX restrictions, using JavaScript to help you instantiate your Flash will greatly add to the ease of embedding content. It will also make sure that users of all versions or who need to install Flash are handled either by directing them to the proper Flash installation and/or letting them see an alternative version of the content. swfObject For a while, I used this standard swfObject method that was detailed in this great SitePoint article: http://www.sitepoint.com/article/activex-activationissue-ie. A similar, robust version of this JavaScript is located on Google Code's AJAX API http://code.google.com/p/swfobject/wiki/hosted_library. You can download the script (it's very small) or you can link directly to the swfObject AJAX API URL: <script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> Downloaded or linked to the Google Code CDN, be sure to place this below your wp_head or any wp_enqueue_script calls in your < head > tags in your header.php template file or other head template file. Adding a SWF to the template using swfObject If you'd like to use the swfObject.js file and method, you can read the full documentation here: http://code.google.com/p/swfobject/wiki/documentation. But essentially, we're going to use the dynamic publishing option to include our SWF file. Using the SWF file included in this book's code packet, create a new directory in your theme called flash and place the SWF file in it. Then, create a div with alternative content and a script tag that includes the following JavaScript: <script type="text/javascript">swfobject.embedSWF("myContent.swf", "myContent", "300", "120","9.0.0");</script>...<div id="myContent"><p>Alternative content</p></div>... Add this ID rule to your stylesheet (I placed it just below my other header and intHeader ID rules): #flashHold{float: right;margin-top: 12px;margin-right: 47px;} As long as you take care to make sure the div is positioned correctly, the object embed code has the correct height and width of your Flash file, and you're not accidentally overwriting any parts of the theme that contain WordPress template tags or other valuable PHP code, you're good to go. What's the Satay method?It's a cleaner way to embed your Flash movies while still supporting web standards. Drew McLellan discusses its development in detail in this article: http://www.alistapart.com/articles/flashsatay. This method was fine on its own until IE6 decided to include its ActiveX security restriction. Nowadays, a modified embed method called the "nested-objects method": http://www.alistapart.com/articles/flashembedcagematch/ is used with the swfObject JavaScript we just covered. Good developer's tip:Even if you loathe IE (as lots of us as developers tend to), it is an "industry standard" browser and you have to work with it. I've found the Microsoft's IE blog ( http://blogs.msdn.com/ie/) extremely useful in keeping tabs on IE so that I can better develop CSS-based templates for it. While you're at it, go ahead and subscribe to the RSS feeds for Firefox ( http://developer.mozilla.org/devnews/), Safari ( http://developer.apple.com/internet/safari/), and your other favorite browsers. You'll be surprised at the insight you can glean, which can be extremely handy if you ever need to debug CSS or JavaScripts for one of those browsers. jQuery Flash plugin In the past year, as I've found myself making more and more use of jQuery, I've discovered and really liked Luke Lutman's jQuery Flash plugin. There is no CDN for this and it's not bundled with WordPress, so you'll need to download it and add it to your theme's js directory: ( http://jquery.lukelutman.com/plugins/flash/). Embedding Flash files using the jQuery Flash plugin As we're leveraging jQuery already, I find Luke's Flash plugin a little easier to deal with. Load the script under the wp_head. Place a div of alternative content; just the div of alternative content and nothing else! Write the jQuery script that will replace that content or show your alternative content for old/no Flash players. Code goes here. I think you see why I liked this so much more. Passing Flash a WordPress variable So now you've popped a nice Flash header into your theme. Here's a quick trick to make it all the more impressive. If you'd like to keep track of what page, post, or category your WordPress user has clicked on and display a relevant image or animation in the header, you can pass your Flash SWF file a variable from WordPress using PHP. I've made a small and simple Flash movie that will fit right over the top-right of my internal page's header. I'd like my Flash header to display some extra text when the viewer selects a different "column" (a.k.a. category). In this case, the animation will play and display OpenSource Magazine: On The New Web underneath the open source logo when the user selects the On The New Web category. More fun with CSSIf you look at the final theme package available from this title's URL on the Packt Publishing site, I've included the original ooflash-sample. FLA file. You'll notice the FLA has a standard white background. If you look at my header.php file, you'll notice that I've set my wmode parameter to transparent. This way, my animation is working with my CSS background. Rather than beef up my SWF's file size with another open source logo, I simply animate over it! Even if my animation "hangs" or never loads, the user's perception and experience of the page is not hampered. You can also use this trick as a "cheater's preloader". In your stylesheet, assign the div that holds your Flash object embed tags, a background image of an animated preloading GIF or some other image that indicates the user should expect something to load. The user will see this background image until your Flash file starts to play and covers it up. My favorite site to get and create custom loading GIFs is http://www.ajaxload.info/.   In your Flash authoring program, set up a series of animations or images that will load or play based on a variable set in the root timeline called catName. You'll pass this variable to your ActionScript. In my FLA example, if the catName variable does not equal On The New Web, then the main animation will play, but if the variable returns On The New Web, then the visibility of the movie clip containing the words OpenSource Magazine: On The New Web will be set to "true". Now, let's get our PHP variable into our SWF file. In your object embed code where your swfs are called, be sure to add the following code: If you plan on using the Satay embed method, your object embed will look like this: ...<script type="text/javascript">var flashvars = {catName: "<?echo single_cat_title('');?>"};swfobject.embedSWF("<?php bloginfo('template_directory');?>/flash/ooflash-sample.swf", "flashHold", "338", "150","8.0.0","expressInstall.swf", flashvars);</script>... If you'd like to use jQuery Flash, your jQuery will look like this: ...<script type="text/javascript">jQuery(document).ready(function(){jQuery('#flashHold').flash({src: '<?php bloginfo('template_directory');?>/flash/ooflash-sample.swf',width: 338,height: 150,flashvars: { catName: '<?echo single_cat_title('');?>' }},{ version: 8 });});</script>... Be sure to place the full path to your SWF file in the src and value parameters for the embed tags or jQuery src. Store your Flash file inside your themes directory and link to it directly, that is, src="/mythemename/flas'); template tag. This will ensure that your SWF file loads properly. Using this method every time someone loads a page or clicks on a link on your site that is within the On The New Web category, PHP will render the template tag as myswfname.swf?catName=On The New Web, or whatever the $single_cat_title(""); for that page is. So your Flash file's ActionScript is going to look for a variable called catName in the_root or _level0, and based on that value, do whatever you told it to do—call a function, go to a frame and animate; you can even name it. For extra credit, you can play around with the other template tag variables such as the_author_meta or the_date(), for example, and load up special animations, images, or call functions based on them.
Read more
  • 0
  • 2
  • 6542

article-image-dynamic-menus-wordpress
Packt
07 Dec 2009
5 min read
Save for later

Dynamic Menus in WordPress

Packt
07 Dec 2009
5 min read
This is the nice thing about WordPress—it's all "dynamic". Once you install WordPress and design a great theme for it, anyone with the right level of administrative capability can log into the Administration Panel and add, edit, or delete content and menu items. But generally, when people ask for "dynamic menus", what they really want are those appearing and disappearing drop-down menus which, I believe, they like because it quickly gives a site a very "busy" feel. I must add my own disclaimer—I don't like dropdowns. Before you get on to my case, I will say it's not that they're "wrong" or "bad"; they just don't meet my own aesthetic standards and I personally find them non-user friendly. I'd prefer to see a menu system that, if subsections are required, displays them somewhere consistently on the page, either by having a vertical navigation expand to display subsections underneath, or showing additional subjections in a set location on the page if a horizontal menu is used. I like to be able to look around and say, "OK, I'm in the New Items | Cool Drink section and I can also check out Red Dinksand Retro Dinks within this section". Having to constantly go back up to the menu and drop-down the options to remind myself of what's available and what my next move might be, is annoying. Still haven't convinced you not to use drop-downs? OK, read on. Drop-down menus So you're going to use dropdowns. Again it's not "wrong"; however, I would strongly caution you to help your client take a look at their target users before implementing them. If there's a good chance that most users are going to use the latest browsers that support the current JavaScript, CSS, and Flash standards, and everyone has great mobility and is "mouse-ready", then there's really no problem in going for it. If it becomes apparent that any percentage of the site's target users will be using older browsers or have disabilities that prevent them from using a mouse and will limit them to tabbing through content, you must consider not using drop-down menus. I was especially negative about drop-down menus as, until recently, they required bulky JavaScripting or the use of Flash, which does not make clean, semantic, and SEO-friendly (or accessible) XHTML. Enter the Suckerfish method developed by Patrick Griffiths and Dan Webb. This method is wonderful because it takes valid, semantically accurate, unordered lists (WordPress' favorite!), and using almost pure CSS, creates dropdowns. The drop-down menus are not tab accessible, but they will simply display as a single, clear unordered list to older browsers that don't support the required CSS. IE6, as per usual, poses a problem or two for us, so there is some minimal DOM JavaScripting needed to compensate and achieve the correct effect in that browser. If you haven't heard of or worked with the Suckerfish method, I'm going to recommend you to go online (right now!) and read Dan and Patrick's article in detail (http://alistapart.com/articles/dropdowns). More recently, Patrick and Dan have revisited this method with "Son-of-a-Suckerfish", which offers multiple levels and an even further pared down DOM JavaScript. Check it out at http://www.htmldog.com/articles/suckerfish/dropdowns/. I also suggest you play around with the sample code provided in these articles so that you understand exactly how it works. Go on, and read it. When you get back, I'll review how to apply this method to your WordPress theme. DIY SuckerFish menus in WordPress All done? Great! As you can see, the essential part of this effect is getting your menu items to show up as unordered lists with sub unordered lists. Once you do that, the rest of the magic can be easily handled by finessing the CSS that Patrick and Dan suggest into your theme's CSS and placing the DOM script in your theme's header tag(s), in your header.php and/or index.php template files. Seriously, that's it! The really good news is that WordPress already outputs your content's pages and their subpages using unordered lists. Right-click on the page links in Firefox to View Selected Source and check that the DOM inspector shows us that the menu is, in fact, being displayed using an unordered list. Now you can go into your WordPress Administration panel and add as many pages and subpages as you'd like (Administration | Page | Add New). You'll use the Page Parent tab on the right to assign your subpages to their parent. If you installed the pageMash plugin, it's even easier! You can drag-and-drop your created pages into any configuration you'd like. Just be sure to hit the Update button when you're done. Once you've added subpages to a page, you'll be able to use the DOM Source of Selection viewer to see that your menu is displayed with unordered lists and sublists.
Read more
  • 0
  • 0
  • 2809

article-image-apache-myfaces-trinidad-12-web-application-groundwork-part-2
Packt
30 Nov 2009
3 min read
Save for later

Apache MyFaces Trinidad 1.2 Web Application Groundwork: Part 2

Packt
30 Nov 2009
3 min read
Deployment Deployment is very easy because with Seam-gen, we also inherit the deployment mechanism (already run during the project setup, earlier) provided by the Ant build process of Seam-gen. However, a few notes regarding the specific deployment of a Trinidad and Facelet web application in contrast with Seam-gen are discussed in more detail in the upcoming topics. The following screenshot shows the referenced libraries within the Eclipse IDE: Trinidad-specific and Facelet-related changes to the project files First of all, the lib directory lacks the Trinidad JAR files and the Facelet JAR: jsf-facelets-1.1.14.jar trinidad-api-1.2.9.jar trinidad-impl-1.2.9.jar So above JAR files must be added to the lib directory while others, such as the RichFaces JARs, should be removed as we want to achieve a clean setup of a single component library. A mix-up should be avoided to keep away from integration problems. The following screenshot shows the contents of the lib directory inside Eclipse (part I only shows files not referenced by the Eclipse project): Most importantly, we need to update the file deployed-jars.list, as it is looked at by the build process to provide the application server with the required JAR files. So we reduce this list file to a more minimal Trinidad-specific version: antlr-runtime.jar commons-beanutils.jar commons-digester.jar core.jar drools-compiler.jar drools-core.jar janino.jar jboss-el.jar jboss-seam.jar jboss-seam-*.jar jbpm-jpdl.jar jsf-facelets-1.1.14.jar mvel14.jar trinidad-api-1.2.10.jar trinidad-impl-1.2.10.jar The following screenshot shows the contents of the lib directory inside Eclipse (part II only shows files not referenced by the Eclipse project): Next, in the resources directory we must add a provider for Seam's conversation mechanism to support Seam conversations in Trinidad dialogs. Its file name must follow the Trinidad naming convention for this provider type, and it must be located below resources in META-INF/services: File name: org.apache.myfaces.trinidad.PageFlowScopeProvider Contents: It must contain the name and package path of the provider class, for example, trinidad.SeamPageFlowScopeProviderImpl This class is created as an implementation of Trinidad's abstract class PageFlowScopeProvider that can be easily done with Eclipse's comfortable class creation wizard. There are further simplifications: The org.jboss.seam.ui.richfaces package in the resources directory is required for Seam's support of RichFaces, but is obsolete for us and should thus be deleted In the WEB-INF directory, we can carry out the following activities: We can add a folder for Facelet composition components We can simplify the components.xml file by getting rid of persistence declarations such as persistence:managed-persistence-context, persistence:entity-manager-factory, and drools:rule-base declarations (the security we only leave is the one for the identity object) The faces-config must be adapted to suit the Trinidad renderer as described earlier The pages.xml becomes even simpler as we practically avoid it altogether using the dialog framework as described in the navigation section earlier We must modify the web.xml to suit Trinidad's requirements We must add three additional files, namely the trinidad-config.xml, the trinidad-skins.xml, and a taglib.xml to declare the Facelet composition components The *-dev-ds.xml and *-prod-ds.xml files may be emptied of any specific data because no database-backing is used in our test project
Read more
  • 0
  • 0
  • 924
Visually different images

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

Navigating Your Site using CodeIgniter 1.7: Part 2

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

article-image-customizing-headers-and-footers-ms-office-live-small-business
Packt
30 Nov 2009
13 min read
Save for later

Customizing Headers and Footers with MS Office Live Small Business

Packt
30 Nov 2009
13 min read
Although a website is just a collection of web pages, the collection is not random. A central theme ties the web pages together with common elements such as branding, logo, layout, and formatting. On really large websites, the interweaving of these elements can be quite complex. Each of Google's websites, for example, has its distinct identity and yet you can identify it as a "Google website". It takes a small army of designers and illustrators to achieve such a "Similar But Distinct" identity. But it's fairly easy to establish a unifying theme for the web pages of a small website, such as yours. And you can do it all by yourself; a common header and footer is all that's usually necessary. Naturally, it would make immense sense if you could design a template for headers and footers once and use it on all of your web pages. A template isn't all that revolutionary a concept. You've probably built a template in your word processor for your letterhead or for a boilerplate, for example. Many widely-used applications save you the trouble of repetitive formatting by allowing you to make templates. Therefore, it shouldn't come as a great surprise to you that you can build page templates in Office Live Small Business as well. A web page template in Office Live Small Business has two components: information and design. The information component consists of the text and images that are specific to your website, such as your company name, logo, slogan, copyright notice, and so on. The design component deals with choosing the right font, colors, background pictures, and other such visual elements. Once you configure the necessary settings, you'll have a shell, so to say, which will appear around the content on your web pages. Choosing a title for your website A website's title is usually the name of the business it represents. My little company is called Acxede, for example. Therefore, it's logical that my site's title mimics my company's name. Now, there's only so much real estate available on a web page for the title. Because Acxede happens to be a short name, it can fit into most page layouts. But if your business is incorporated as Anthony Donaldson's Vacuum Cleaner Sales, Service, and Rentals Incorporated, this scheme of things breaks down. What do you do then? A good rule of thumb is to echo whatever name is on your business card. Unless your business card is the size of a postcard, you'd have shortened the name to something like Anthony Donaldson Inc. Use that as your site's title. People often want to set their domain name as their site's title. Because my company is called Acxede, it would, of course, be terrific to have acxede.com as my domain name. And I do. Unfortunately, not everyone is that lucky. More likely than not, the domain name you want is already taken. Let's say that you're Sam and you own a deli called, naturally, Sam's Deli. Everyone just calls it "Sam's". It wouldn't be unreasonable for you to want the domain name sams.com. The trouble is that Sam's Publishing has already snapped it up. Okay, so how about samsdeli.com? Nope. Another Sam owns it. So you're forced to settle for a domain name that doesn't echo the name of your business; something like samsfreshfood.com, perhaps. Nevertheless, your website's title should still say "Sam's Deli" because that's the name of your business, no matter what domain name you ultimately settle on. Now that you know more about setting a website's title than you ever wanted to, let's get around to doing the honors. Time for action – setting the site title Pull down the Design Site menu from the Page Manager toolbar and select Design site. A new window opens, displaying the Microsoft Office Live Small Business Web Design Tool web page with Site Designer as the active tab. Click on the Header button on the ribbon. The Customize Header dialog opens. Replace the text Welcome to my site in the gray box in the Site Title section with your site's title. I'm going to set it as The Office Live Guide for the site that I'm building—this article's companion site. Pull down the select options for the font face just above the title. You'll see a choice of seven fonts: Arial, Courier New, Georgia, Tahoma, Times New Roman, Trebuchet MS, and Verdana. Why only seven? After all, Microsoft Word seems to have a hundred. The reason is that in the Web's architecture, the task of displaying a given font is delegated to your browser. Not every browser can display every font. If a browser can't display a font that you've specified, it displays one that it thinks is right. Such a substitution might distort your web page. But these seven fonts are, more or less, the least common denominator; most browsers support them. Therefore, the chances of your web pages being distorted are quite slim if you choose one of these seven. So which of these seven should you choose? Follow this two step process: If one of the fonts in the list looks like the font on your letterhead or the sign above your office, choose that one. Not even close? Choose either Georgia or Verdana. Most fonts, such as Arial or Times New Roman, came to computer displays from the world of print. They were designed to look good on paper. Making a font look good on paper is relatively easy because text is printed on paper in very high resolution. On a monitor, however, pixels of resolution are at a premium. Besides, the resolution can vary from monitor to monitor. Therefore, text will look better onscreen if you use fonts that are designed specifically for monitors rather than using fonts that are grandfathered from the print world. Georgia and Verdana are designed specifically for monitors and so they're the ideal candidates for the text on your web pages. Set the font you've chosen. I've set it to Georgia. Next, pull down the adjacent select options for the font size. You'll see a choice of seven font sizes. They're conveniently numbered from 1 to 7. Size 1 is the smallest and size 7 is the largest. For some inexplicable reason, people often choose a size that's either too big or too small. I recommend size 5 for the title. That's just about right for most websites built with Office Live Small Business. One thing you've got to remember, though, is that: Thou shalt use Georgia or Verdana in size 5 for your site's title is not the eleventh commandment. I've suggested these settings because, in my experience, they are just about right for most websites built with Office Live Small Business. They make the header appear proportionate to the text on the web pages. But, they may not be right for your site if its title or slogan is either too long or too short. Come back and experiment with the font face or size of the header elements if your pages look out-of-whack after you finish building your website. Set the font size you've chosen. I've set it to 5. Although you can choose a color for the title. The choice of color depends on other layout options as well. Although you can make the title bold, italicize it, or underline it, you'd do well by avoiding the temptation. Depending on a combination of factors such as the font face, font size, and resolution of a visitor's monitor, these special effects can make the text quite difficult to read. The last thing you want to do is to inadvertently make the title of your site unreadable. Your Customize Header dialog should now look something like this: Keep the window open; you might as well set a slogan for your website while you're there. What just happened? You just took the first baby steps towards building your website! Agreed, all you did was set the site title—not exactly the kind of stuff that you'd write home about, but it's a fine start nevertheless. Your site's title and slogan, which you'll set in the following section, play an important role in helping people find your site from search engines. Choosing a slogan for your website An Office Live Small Business website's slogan is really just its tagline; so I'll use the terms interchangeably. Successful businesses use catchy taglines to reinforce their brands. What comes to mind when you hear "Just do it!"? Nike. How about "Don't Leave Home Without It"? American Express. And "Eat Fresh"? Subway, of course. See? People subconsciously associate taglines with brands or products. Come to think of it, the whole point of building your website is to reinforce your brand. Naturally, a good tagline will go a long way towards achieving your goal. While a tagline sounds like a no-brainer, not every business has one. If you don't, you're not alone. After all, you can't spend a few million dollars to come up with one the way Nike, American Express, and Subway probably did. But if you happen to have one, it's a good idea to immortalize it on your website. And if you don't, now's the time to scratch the creative side of your brain and think of one. But don't despair if you can't. You may be able to substitute a description of your business for the tagline with good effect. If you've shortened Anthony Donaldson's Vacuum Cleaner Sales, Service, and Rentals Incorporated, to Anthony Donaldson Inc., your tagline can be Vacuum Cleaner Sales, Service, and Rentals, or something to that effect. It may not be as potent as Nike's tagline, but at least it tells people what Anthony Donaldson does for a living. Time for action – setting the site slogan Replace the text Add your site slogan here! in the gray box in the Site Slogan section with your site slogan. I'm going to set it to Build your own website in a day! Pull down the select options for the font face just above the title and set it to the font you've chosen. I'm setting it to Georgia again. Next, pull down the adjacent select options for the font size and set it to 4. Why 4? I didn't pull the number 4 out of a hat. I chose it because size 4 is a size smaller than size 5, the size of my site's title. If your Site Title is set to a size other than five, choose one size smaller than the size of your site's title. As with the Site Title, don't select a color for your Site Slogan. And stay away from the B, I, and U buttons as well. Your Customize Header dialog should now look something like this: Click the OK button at the bottom of the Customize Header dialog. It closes and you arrive back at the Site Designer. Click the View button in Site Designer. You'll be using the View button, and the Save button next to it, quite often. When I want you to click the Save button, I'll simply tell you to save your work. If I want you to click the View button, I'll tell you to preview your website. Whenever I refer to these buttons, directly or indirectly, you now know where to find them. A pop-up message asks you whether you want to save your changes. Click OK. A preview of your site comes up in a new browser window. Notice that the site now displays the new title and slogan, as shown in the following screenshot: After you've admired your handiwork long enough, close the preview window and return to Site Designer. What just happened? You added a slogan to go along with your site's title. Why so much fuss about simply setting the title and slogan? In a word: findability. Findability? I didn't make that word up, by the way. Honest! Well-known web usability expert Jakob Nielsen did. A site is findable if it's easy to find; that is, it appears near the top of search engine results when a person searches for relevant terms. You can find great advice about building usable websites on Mr. Nielsen's website at http://www.useit.com Search engines attach considerable importance to the title of a web page. It tells them what the page is all about. But that's not the only thing they look at. They also try to determine whether the text on the web page has anything to do with its title. Because the slogan appears on every page with the title, a strong correlation between the two and their correlation with the text on your web pages will determine your web page's ranking in search results. To put it mildly, if your site's title and slogan stink, so will its ranking in the search results! Therefore, don't take these settings lightly. If you don't put enough thought behind them, you risk relegating your web pages to obscurity. Have a go hero – experiment with the site title and site slogan Although I handed down the edicts on setting the font face and the font size for the Site Title and the Site Slogan, by no means are my recommendations cast in stone. Although following my recommendations will save you a good deal of time and heartache, you'll do a disservice to yourself if you don't experiment on your own. Depending on how long your Site Title or Site Slogan is, you might find a better combination of these settings if you try out a few variations. Here are a few suggestions: If you've set your font to Georgia, you might want to try Verdana. How about Georgia for the Site Title and Verdana for the Site Slogan? Or vice-versa? Although I've recommended that you set the font size for your Site Slogan a size smaller than the font size for your Site Title, you might want to try a font size two sizes smaller than the size for your Site Title, especially if you've set different fonts for the title and the slogan. Verdana is a wide font. If your site title or slogan has several wide letters like W and M, Verdana may not be the right choice. You might want to try a similar but narrower font, such as Arial. Try out a few variations and settle on one that you like the best. You might want to get an opinion from a friend or a co-worker. And remember, you can come back and play with these settings any time. Pop quiz 1 Which of the following attributes make your website more "findable"? Your site's header Your site's title Your site's font setting Your site's slogan The answer to this quiz is given at the end of this article.
Read more
  • 0
  • 0
  • 1476

article-image-apache-myfaces-trinidad-12-web-application-groundwork-part-1
Packt
30 Nov 2009
8 min read
Save for later

Apache MyFaces Trinidad 1.2 Web Application Groundwork: Part 1

Packt
30 Nov 2009
8 min read
Navigation Navigation deals with all aspects of the user to moving from one part of an application to another. This includes the following means that the application must support, to allow the user moving to a certain functionality that is available through various kinds of links: Support of movement invocation through mouse clicks on tree nodes or keyboard shortcuts on such nodes, for example, menu items such as tr:commandNavigationItem, tr:commandLink, and s:link Support of movement invocation through mouse-clicks on buttons or keyboard shortcuts on such controls, for example, tr:commandButton, s:button, and s:link Support of movement invocation through mouse-clicks on hyper links or keyboard shortcuts on such links, for example, tr:commandLink, and s:link Support of movement invocation through mouse-clicks on icon links or buttons, or keyboard shortcuts on such links or buttons, for example, tr:image, tr:icon, and so on Further support for other variations of similar means of direct manipulation, for example, select boxes or radio buttons that cause a form to change in a way that encompasses moving to another page with more or other fields The following Image shows various means of navigation that all have to be considered (tree links, button clicks, selections and so on): To keep such navigation as simple, and yet as effective as technically possible, we move away from the Struts-inspired JSF way of declaring the navigation by means of XML files, something also kept up by Seam. We take advantage of Trinidad's dialog framework. It allows navigation on the pure Java side so that Seam's pages.xml can concentrate on the general navigation aspects such as exception handling or security/authorization. Following advantages can be observed in such an approach: Navigation declarations are kept simple and manageable thanks to a small pages.xml and yet no *.page.xml files are needed. Navigation occurs only in two areas—the XHTML and the application-specific Seam component controllers. Navigation always works the same way—first the model is set up and made available to the view by the controller, then the controller navigates to the view using the dialog framework. Finally, when the view is left, it is either closed (click on X), cancelled (click on Cancel), or accepted (click on OK) which is followed by post processing such as selecting and passing a value on to another object. You can access all the required sources, tools or plugins, and the sample project setup here. Thus, for instance, the login dialog is a real programmatic Trinidad dialog as it is called the following way: @Begin(join=true)public void doLogin(javax.faces.event.ActionEvent event){FacesContext jsfCtx = FacesContext.getCurrentInstance();// Create the dialog UIViewRootViewHandler viewHandler = jsfCtx.getApplication().getViewHandler();UIViewRoot dialog = viewHandler.createView(jsfCtx, "/login.xhtml");RequestContext trCtx = RequestContext.getCurrentInstance();trCtx.launchDialog(dialog,null, event.getComponent(),false, null);} Whereby the XHTML does not use the standard Trinidad dialog command features, but passes control to above action listener: <tr:form><tr:commandLink id="loginCommandLink" text="Login"actionListener="#{controller.doLogin}"rendered="#{not identity.loggedIn}" blocking="true"/></tr:form> The only occurrences of login.xhtml in pages.xml are in the general declaration of pages.xml and in the general error handling, but no other navigation of login.xhtml needs to be declared: <pages xsi:schemaLocation="http://jboss.com/products/seam/pageshttp://jboss.com/products/seam/pages-2.0.xsd"login-view-id="/login.xhtml">...<exception class="org.jboss.seam.security.NotLoggedInException"><redirect view-id="/login.xhtml"><message>Please log in first</message></redirect></exception> Finally, the dialog is closed, which is again done in a programmatic way for Trinidad dialogs: public void closeDialog(){Identity id = (Identity)Contexts.lookupInStatefulContexts(org.jboss.seam.security.identity");id.login();RequestContext trCtx = RequestContext.getCurrentInstance();trCtx.returnFromDialog(null,null);} This time, we do not need to deal with an event and close it by the simpler JSF action reference: <div class="actionButtons"><tr:commandButton text="Login" action="#{controller.closeDialog}" /></div> To understand the dialog logic behind above processes let us take a look at the general principles of the dialog framework that Trinidad provides. Trinidad's Dialog Framework The Apache MyFaces Trinidad Dialog Framework is an inheritance that stems back from the days of Oracle's ADF and UIX frameworks. It was the main way to navigate across dialogs, moving from page to page, from popup dialog to main browser dialog window, and so on. It offers a declarative way that works by using the conventional pages declarations as known from the pure JSF side, also in combination with Seam's pages.xml. Furthermore, it allows navigation in a purely programmatic manner as can be seen in the preceding examples. Nowadays, the dialog framework provided with Trinidad still counts as an alternative to the usual approach based in declaring pages and referencing them from within the application. Moreover, its uniform approach of dealing with both kinds of navigation, popup windows, and main browser windows remains as yet another attractive characteristic. For both reasons, we want to take advantage of this technique and concentrate on the purely programmatic side. For the declarative, please refer to http://myfaces.apache.org/trinidad/devguide/dialogs.html. Programmatically creating a dialog To create a dialog only the invocation of a method called launchDialog is required. It is a method provided by Trinidad's RequestContext object: public abstract void launchDialog(UIViewRoot dialogRoot,java.util.Map dialogParameters, UIComponent source, boolean useWindow, Map windowProperties); So the developer needs to provide the following parameters: A JSF component tree (the UIViewRoot dialogRoot) Some objects to pass to the dialog, see the upcoming sub section A JSF component from which the dialog is initiated and which receives a Trinidad ReturnEvent when the dialog to be shown is finished (closed) A Boolean flag to set the display type, popup, or main window The size of the pop-up window that is only required if the display type is a pop-up window which is set by putting integer objects into this map with keys width and height for window width and height respectively In above example, we can see that: ViewHandler viewHandler = jsfCtx.getApplication().getViewHandler();UIViewRoot dialog = viewHandler.createView(jsfCtx, "/login.xhtml");RequestContext trCtx = RequestContext.getCurrentInstance();trCtx.launchDialog(dialog,null, event.getComponent(), false, null); The JSF view handler is applied to create the new component tree based on the current JSF Faces context and the specific page to be shown in the dialog, which is the usual way. Next, in the actual call of the launchDialog method, we can see the purely programmatic approach without passing any objects to the dialog to be launched. Furthermore, we can see that because it is inside an action event listener of a commandLink, the dialog activity is linked with that link component. In other words, once the dialog is finished, a ReturnEvent is raised and handled by a respective return event listener on that component. Providing the data flow from dialog to dialog There are two alternatives to pass objects to a dialog and back: Using Trinidad's page flow scope Using Seam's scopes The first way is sort of built-in to Trinidad dialogs because above dialogParameters is a map of parameters that is going to populate a newly created pageFlowScope map solely created for the upcoming dialog. This map also includes all the objects that stem from the currently available pageFlowScope. One could also think of it as a nested scope because once the dialog is finished, this map is not available anymore; therefore, any modifications to this newly nested scope will not be preserved once the dialog is closed. The second way would be consistent with the rest of the web application is if the other parts use such important Seam scopes as conversation. Generally, it is more advisable to prefer one of both and avoid a mixture. In this article we take advantage of page flow scopes as Trinidad is in the foreground. Returning from a dialog Once the dialog is cancelled, or the activity accepted and finished, the application must link to Trinidad's standard closing process which is calling the returnFromDialog method of RequestContext. For example, the closeWindow needs to apply Trinidad's RequestContext: RequestContext trCtx = RequestContext.getCurrentInstance();trCtx.returnFromDialog(null,null); This is a special case because the returnFromDialog method's signature is defined as follows: public abstract void returnFromDialog(Object returnValue, Map<Object,Object> returnParameters); Generally, while invoking the returnFromDialog method, one provides return objects as dialog results, that is, for instance the result of a selection. Therefore, it is perfectly normal to return a single object as returnValue while returnParameters may remain null. In any case, the ReturnEvent object provides two methods to access such dialog results: public Object getReturnValue(): This method yields the object that has been passed as the first parameter of the invocation of returnFromDialog public Map<Object, Object> getReturnParameters(): This method yields the map that has been passed as the second parameter of the invocation of returnFromDialog In the case of our simple closeDialog method, no parameters are passed back as Seam's login procedure does it all for us, and we do not need to pass anything back as it is saved by Seam in its identity object. In the following section, we will see the specific example which is in our web sample application.
Read more
  • 0
  • 0
  • 1545
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $15.99/month. Cancel anytime
article-image-drag-and-drop-yui-part-2
Packt
30 Nov 2009
12 min read
Save for later

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

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

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

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

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

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

Navigating Your Site using CodeIgniter 1.7: Part 1

Packt
30 Nov 2009
10 min read
MVC:Model-View-Controller What's MVC all about? For sure at this time you are very curious about this. In short, MVC is an architectural pattern, a way of structuring our application. system application models views controllers As you can see there is a folder for each of the words (MVC); let's see what we can put into them: Models: The models represent our application data, be it in databases, in XML files or anywhere else. Also, interaction with databases is carried here. For example, models will allow us to fetch, modify, insert, and remove data from our database. All actions that require our application to talk to our database must be put in a model. Views: Files placed here are responsible for showing our data to the visitors to our site, or users of our application. No programming logic, no insert or update queries must be run here, though data access may occur in these files. They are here only to show the results of the other two. So we fetch the data in the model, and show it in the view. Now, what if we need to process the data, for example, putting it into an array? Then we do it in the controller; let's see how. Controllers: These act as a nexus between models and views, and programming logic occurs here. Take a look at this little diagram, in the left column we can see a "classical" way of doing things (a little outdated right now). We have a PHP file with SQL queries and HTML code in the same file and embedded into the HTML PHP logic. It may seem, at first glance, that this way it is easier and faster to program. But in this case the code gets messed faster and becomes cluttered with SQL queries, HTML, and PHP logic. Look at the right-side column—we have SQL queries in the Model, HTML and other graphic elements in the View, and PHP logic in the Controller. Doesn't that seem organized? The Controller calls and fetches data from the Model. It then loads the data and passes it to the Views, and sends the results to the user. Once we start working with this pattern we will feel how easy it is; it will keep our projects organized. If we need to come back to our project months after finishing it we will appreciate having made it in a structured fashion. No more of—Oh my God where did I put that query, where is that include file?—they will be in the model and the controller respectively. But, what happens if we want to put our queries in the controller? Well, CodeIgniter allows us to do so (though it is not recommended; if you can avoid, it is better to do so). Other frameworks force you to keep a particular structure, but with CI you can do programming in the way you want. Although it is recommended to keep to the structure, there will be times when we will need to do things the other way. With this structure we can accomplish two important things: Loose Coupling: Coupling is the degree by which the components of a system rely on each other. The less the components depend on each other, the more reusable and flexible the system becomes. Component Singularity: Singularity is the degree by which components have a narrow focus. In CI, each class and its functions are highly autonomous in order to allow maximum usefulness. But how does all this work? Now that we have seen how CI is structured, maybe you are asking yourself—how are the files in those three folders (models, views, controllers) working together? To answer this question we have another diagram, here it is: As you can see it's similar to the previous one, and a little summarized (but with a wider scope of things, this is how the MVC pattern works), but this time we can see some new elements, and if you look at it closely you will be able to distinguish the flow of data. Let's explain it, first of all there is a browser call to your site, then the index.php file in the root folder is called (because we removed it from the URL, using the .htaccess file, we don't see it). This file acts as a router and calls the controllers, as and when they are needed. The controllers, as they are called, come into action. Now, two things can happen: There is no need to fetch data from the database—in this case only the View is called, and loaded by the Controller. Then it is returned to the Browser for you or your visitors to see. There is the need to fetch some data from the database—in this case theController calls the Model, which in turn makes a query to the database. The database returns data to the Model, and the Model to the Controller. The Controller modifies the data in every necessary way. Then it loads the View, passing all necessary data to it, and the View is created and returned to the Browser again. Do not get confused with the first case; there will be times when you will need to create static pages. CI doesn't differentiate between static and dynamic pages. On those occasions simply don't create the Models. Now, return to our sample site to see how all this applies to it. Remember when we put the URL as http://127.0.0.1/codeigniter, CI's welcome screen appeared in our browser. Now try this URL http://127.0.0.1/codeigniter/welcome. You can also try using this URLhttp://127.0.0.1/codeigniter/index.php/welcome. In both cases the welcome screen appears in the browser. You maybe wondering, how CI knows, if you put http://127.0.0.1/codeigniter/, that it has to load the welcome controller. Don't worry, we will see that in a moment; for now, we will go on with our example: http://127.0.0.1/codeigniter/index.php/welcome A request coming to your web site's root is intercepted by the index.php file, which acts as a router. That is, it calls a controller—welcome controller—which then returns a view, just as in the previous diagram. But how does the controller do that? We are going to see how in the welcome controller. The welcome controller As we know the welcome controller is the default controller, configured in the routes.php file of the config directory and the code is at ./application/controllers/welcome.php. Here's what it says: <?php class Welcome extends Controller { function Welcome() { parent::Controller(); } function index() { $this->load->view('welcome_message'); } } /* End of file welcome.php */ /* Location: ./system/application/controllers/welcome.php */ From the second line you'll learn that this file is a class. Every controller inherits from an original Controller class, hence extends Controller. The next three lines make the constructor function. Within the class there are two functions or methods—Welcome() and index(). Though it is not necessary, naming controllers the same way as for tables is a good practice. For example, if I have a projects table I will create a projects controller. You can name your controllers the way you want, but naming them like the tables they represent keeps things organized. Also, getting used to this won't harm you, as other frameworks are stricter about this. Notice that CI uses the older PHP 4 convention for naming constructor functions, which is also acceptable by PHP 5—it doesn't require you to use PHP 5 and is happy with either version of the language. The constructor function is used to set up the class each time you instantiate it. We can obviate this and the controller will still work, and if we use it, it won't do any harm. Inside it we can put instructions to load other libraries or models, or definitions of class variables. So far the only thing inside the constructor is the parent::Controller(); statement. This is just a way of making sure that you inherit the functionality of the Controller class. If you want to understand the parent CI Controller class in detail, you can look at the file /www/CI_system/libraries/controller.php. One of the reassuring things about CI is that all the code is there for you to inspect, though you don't often need to. Working with views Let's go back to the incoming request for a moment. The router needs to know which controller and which function within that controller should handle the request. By default the index function is called if the function is not specified. So, when we put http://127.0.0.1/codeigniter/welcome/, the index function is called. If no error is shown, this function simply loads the view, ('welcome_message') using CI's loader function ($this->load->view). At this stage, it doesn't do anything cool with the view, such as passing dynamic information to it. That comes in later. The ('welcome_message') it wants to load, is in the views folder that you have just installed at /www/codeigniter/application/views/welcome_message.php. This particular view is only a simple HTML page, but it is saved as a PHP file because most views have PHP code in them (no point in doing all this if we're only going to serve up plain old static HTML). Here's the (slightly shortened) code for the view: <html> <head> <title>Welcome to CodeIgniter</title> <style type="text/css"> body { background-color: #fff; margin: 40px; font-family: Lucida Grande, Verdana, Sans-serif; font-size: 14px; color: #4F5155; } . . . . . more style information here . . . . </style> </head> <body> <h1>Welcome to CodeIgniter!</h1> <p>The page you are looking at is being generated dynamically by CodeIgniter. </p> <p>If you would like to edit this page you'll find it located at: </p> <code>system/application/views/welcome_message.php</code> <p>The corresponding controller for this page is found at:</p> <code>system/application/controllers/welcome.php</code> <p>If you are exploring CodeIgniter for the very first time, you should start by reading the <a href="user_guide/">User Guide</a>. </p> <p><br />Page rendered in {elapsed_time} seconds</p> </body> </html> As you can see, it consists entirely of HTML, with an embedded CSS stylesheet. In this simple example, the controller hasn't passed any variables to the view. Curious about—&ltp> &ltbr/> Page rendered in {elapsed_time} seconds </p>? Take a look at: http://codeigniter.com/user_guide/libraries/benchmark.html. You can name the views the way you want, and don't put the .php extension for them. You will have to specify the extension when loading them, for example: $this->load->view('welcome_message.html');
Read more
  • 0
  • 0
  • 2341

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

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

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

Freebies and Downloads in Drupal 6: Part1

Packt
27 Nov 2009
6 min read
Free content is a fantastic way of building customer loyalty. Depending on the content that you provide, you can also keep your brand in front of people. For example, a simple tastefully-done screen saver or desktop background can be used to always keep your logo on your customers' desktop. Of course, you need to make sure that the free content is of the highest possible quality to ensure that the customers will actually use the content. Many visitors want to print content or save it to their computers for later use when they are not online or are not working on their computers. We will build PDF files automatically, to give your visitors this convenience. If you allow visitors to download content from your site, you need to be careful that your site security is solid, so that an unscrupulous user cannot download content that you don't want them to have access to. We will discuss how to protect your content in this article. Adding downloads and PDFs to the web site In this section, we will discuss how to add downloads and PDFs to the web site. Controlling how files are downloaded Good Eatin' Goal: Ensure that Drupal has full control over any files that are uploaded, so that we can specify who can download the files. Additional modules needed: None Basic steps Drupal allows you to set downloads to either Public or Private. The public setting does not have any additional download security. The private setting allows Drupal to secure and manage the downloaded files. You can control this functionality using the File system settings, which are available by selecting Site configuration and then File system, from the Administer menu, as shown in the following screenshot: Because we want Drupal to provide additional security for the downloaded files, we will select the Private setting and then save the configuration. You can also control where the files are stored on the web site, and also specify a temporary location to be used while files are being transferred. In most cases, the defaults are acceptable. However, you may need to customize the directories depending on how your server and site are configured. If you are using the private download method, the File system path should not be accessible via a web browser. To ensure that a directory is not available via a web browser, you should choose a folder that is not located within the Drupal installation. It should also not be located within your root web folder. On most systems, the root web folder is named htdocs. If you are unsure what your root web folder is, ask your webhost. Some hosting companies do not allow you to create folders outside the root web folder. If this is the case, you can contact your host to see if they can make an exception, or you will have to use the public download method. Allowing files to be uploaded to the web site Good Eatin' Goal: Allow authorized users to upload a file to the web site. Additional modules needed: Upload (core).   Basic steps In order to allow a user to download a file, you must first upload files to the web site. We will create a downloads page that stores all of the files that have been uploaded.   Begin by activating the Upload module, which is a part of the core Drupal distribution. {literal} We can now customize the permissions for the Upload module by clicking on User management and then on Permission. The available permissions are shown in the following screenshot: It is a good idea to give only authenticated users the ability to view and download files. This will provide an additional incentive for visitors to register on your web site. We can now build a new page for our uploaded files by clicking on Create content and then on Page. The basic information for the page is shown below: To add a file to the page, expand the File attachments section. The section appears as follows: You can now Browse for the file to be uploaded, and then once you have selected it, click Attach. After a file has been attached, it will be listed on the form as shown below: After you save the new page, users with the appropriate permissions will be able to download the file by clicking on the link. You can also add links within the text of a page. Sending the correct file types to a user Good Eatin' Goal: Ensure that the correct file type is sent to the browser so that the visitor's computer can accurately determine how to handle it. Additional modules needed: File MIME (http://drupal.org/project/filemime). Basic steps As you add files to your site for download, it is important to make sure that a visitor's browser knows how to display the file. With web sites, this is done by setting the MIME type for the file. Some common MIME types are: text/html: A standard web page text/csv: A comma-delimited file text/plain: Plain text with no formatting audio/mpeg: Audio mpeg1 and mpeg2 files audio/mp4: Audio mp4 files image/jpeg: JPEG encoded image files image/gif: GIF encoded images application/pdf: A PDF document application/javascript: A script file written in Javascript A full list of how Drupal handles each file type can be found at: http://api.drupal.org/api/function/file_get_mimetype. The File MIME module automatically detects the type of file based on the file extension, and sets the appropriate MIME type, which is returned to the browser. To use the File MIME module, carry out the following steps:   Download, install, and activate the File MIME module. Configure the module by selecting Site configuration and then File MIME, from the Administer menu. The module allows you to specify the location of the mime.types file, which is installed along with your web server. The Apache web server installs this file in the same directory as where your httpd.conf file is installed. You can also add additional mappings for specific file types. For example, you may want .CSV files to be treated as Microsoft Excel files if you know that a significant number of your users are running Windows-based machines and want to download .CSV files into Excel. You can do this by adding the following line to the settings, as shown in the preceding screenshot: application/vnd.ms-excel csv xls. After the module has been properly configured, the module will automatically set the correct MIME types each time that a file is downloaded.
Read more
  • 0
  • 0
  • 781

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

Freebies and Downloads in Drupal 6: Part 2

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

article-image-social-networks-and-extending-user-profile-drupal-part-1
Packt
27 Nov 2009
5 min read
Save for later

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

Packt
27 Nov 2009
5 min read
The term "social network" means different things to different people. However, the starting point of any network is the individuals within it. A user profile provides a place for site members to describe themselves, and for other site members to find out about them. In this article, we will examine how to create a user profile that is aligned with the goals of your site. Identifying the Goals of Your Profile User profiles can be used for a range of purposes. On one end of the spectrum, a profile can be used to store basic information about the user. On the other end of the spectrum, a user profile can be a place for a user to craft and share an online identity. As you create the functionality behind your user profile page, you should know the type of profile you want to create for your users. Drupal ships with a core Profile module. This module is a great starting point, and for many sites will provide all of the functionality needed. If, however, you want a more detailed profile, you will probably need to take the next step: building a node-based profile. This involves creating a content type that stores profile information. Node-based profiles offer several practical advantages; these nodes can be extended using CCK fields, and they can be categorized using a taxonomy. In Drupal 6, user profiles become nodes through using the Content Profile module. The most suitable approach to user profiles will be determined by the goals of your site. Using Drupal's core Profile module provides some simple options that will be easy to set up and use. Extending profiles via the Content Profile module allows for a more detailed profile, but requires more time to set up. In this article, we will begin by describing how to set up profiles using the core Profile module. Then we will look at how to use the Content Profile module. Using the Core Profile Module To use the core profile module, click on the Administer | Site building | Modules link, or navigate to admin/build/modules. In the Core – optional section, enable the Profile module. Click the Save configuration button to submit the form and save the settings. Once the Profile module has been enabled, you can see a user's profile information by navigating to http://example.com/user/UID, where UID is the user's ID number on the site. To see your own user profile, navigate to http://example.com/user when logged in, or click the My Account link. The default user profile page exposes some useful functionality. First, it shows the user's profile, and secondly, it provides the Edit tab that allows a user to edit their profile. The Edit tab will only be visible to the owner of the profile, or to administrative users with elevated permissions. Other modules can add tabs to the core Profile page. As shown in the preceding screenshot by Item 1, the core Tracker module adds a Track tab; this tab gives an overview of all of the posts to which this user has participated. As shown in the preceding screenshot by item, the Contact tab has been added by the core Contact module. The Contact module allows users to contact one another via the site. Customizing the Core Profile The first step in customizing the user profile requires us to plan what we want the profile to show. By default, Drupal only requires users to create a username and provide an email address. From a user privacy perspective, this is great. However, for a teacher trying to track multiple students across multiple classes, this can be less than useful. For this sample profile, we will add two fields using the core Profile module: a last name, and a birthday. The admin features for the core profile module are accessible via the Administer | User Management | Profiles link, or you can navigate to admin/user/profile. As seen in the preceding screenshot, the core profile module offers the following possibilities for customization: single-line textfield—adds a single line of text; useful for names or other types of brief information. multi-line text field—adds a larger textarea field; useful for narrative-type profile information. checkbox—adds a checkbox; useful for Yes/No options. list selection—allows the site admin to create a set of options; the user can then select from these pre-defined options. Functionally, this is similar to a controlled vocabulary created using the core Taxonomy module. freeform list—adds a field where the user can enter a comma-separated list. Functionally, this is similar to a tag-based vocabulary created using the core Taxonomy module. URL—allows users to enter a URL; this is useful for allowing users to add a link to their personal blog. date—adds a date field. In our example profile—adding a last name and a birthday—our last name will be a single-line textfield; our birthday will be a date field.
Read more
  • 0
  • 0
  • 1908
article-image-social-networks-and-extending-user-profile-drupal-part-2
Packt
27 Nov 2009
8 min read
Save for later

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

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

article-image-managing-images-and-videos-joomla-15-part-1
Packt
19 Nov 2009
9 min read
Save for later

Managing Images and Videos in Joomla! 1.5: Part 1

Packt
19 Nov 2009
9 min read
Media Manager As its name suggests, the Media Manager is the place to keep track of and organize all your media files within folders and subfolders. You can use it to upload files, delete old material, or create new folders. Accessing and using the Media Manager The interface within the Media Manager is graphical and similar to other file explorer programs you will have definitely used within a Windows environment. Like any of the sections of the administration control panel, you can access the Media Manager either by: Clicking Site | Media Manager from the top menu Clicking the Media Manager icon on the Control Panel You can switch your view of the files within the Media Manager to suit your preference, as both provide the same level of functionality: Click Thumbnail View to see small graphic versions of your files, handy when you want to find an image Click Detail View to see the names of your files along with the dimensions and sizes The following screenshot illustrates the use of the thumbnail view: The Folders section to the left of the Media Manager interface displays the site folders. Click one to open and reveal any subfolders within it. Within your site there will most likely be a subfolder within the images folder called stories, that is, images | stories. This is generally where the site images will have been placed and is where the Image Upload button defaults to when you add an image to an Article. You can also create new folders in here to store additional media. Using the Party People website, we have created a new article and now need to add an image that doesn't fit in with the established folder structure. Creating a new subfolder It may be that after adding a new Section and/or Category, none of the existing image folder structures apply. Here we'll create a new subfolder called glassware to accommodate the new material: Navigate to the Media Manager through the top menu or by clicking the Media Manager icon on the home page of the Control Panel. Click on the stories folder in the Media Manager. Note that the Media Manager opens directly into the images folder (this is set in the Global Configuration area and can be changed if necessary). Type in glassware as the name of the new folder and click the Create Folder button. The new subfolder will appear instantly. Now that we have the new glassware subfolder we can upload a new image to store in it using the Upload File tool. A note on copyright While you may have your own images and videos to use on your website, if you are considering using another artist's material and content, always ensure you have copyright permission or the license to do so in order to avoid breach of any copyright laws. You should refer to your local authority for full details. Many website developers and owners regularly purchase and use stock photography, illustrations, and videos. If you choose to purchase any material for your site, ensure you are purchasing it with the right license, as there may be restrictions on its use even after paying for the material. This may, in fact, be a license fee and not a transfer of complete ownership. Sites such as http://www.istockphoto.com/license.php have a page dedicated to licensing agreements around purchasing their material. What you should know about image and video files Have you ever visited a website where a large image takes forever to download? Or the video takes forever to start playing? Chances are that you gave up and left the site. While it doesn't happen quite so much now, take care to avoid this wherever possible. As a general rule, the larger the file size, the longer it takes to download into the browser, and not all users of your website may have fast download speeds. To ensure your images are downloaded as quickly as possible, ensure your files are formatted and compressed into as low a resolution version as possible (without losing the quality) and the dimensions of the videos displayed kept to minimum viewing sizes. There is a trade-off between quality of the image and download speed; compromise is the key here. Audio, video, and animation files can be referred to collectively as multimedia, especially when they are combined within a project. Choosing the best image file format Images come in a variety of file formats and some are smaller in size than others. There are other image file formats, but the following are often used within websites: .jpg files are great for highly detailed images such as photographs. As a result, their file size is generally bigger due to the amount of information they require to present the detail. .gif files are suited to images requiring less detail, such as drawings or diagrams, and are smaller in file size as a result. .png files are similar to .gif files, as they are also low resolution images. They often have a transparent background so you can place them over a colored background and the color will appear behind the image. Remember the following when applying images to your website: Use images with a purpose—to enhance or illustrate your content. Keep file sizes as small as possible. Consider a .gif rather than a .jpg if the image isn't a particularly detailed one. Use photo editing software to reduce the resolution of your image to 72dpi for fastest download time. Anything higher is pointless, as computer monitors only present a certain number of colors and drop the excess. If you don't have access to software such as Photoshop, there are a number of free possibilities. One is a program called GIMP (http://www.gimp.org). It's a free program that allows you to retouch photos and create and edit images. The website has tutorials as well. Adding and managing images Having covered editing and adding text to an article, updating and/or adding new images or other media to your articles is easy too. In this section, we'll work on adding and deleting images and cover some general information on how they can work best for your site. Uploading a new image The File Upload tool within the Media Manager makes it easy to move your images from your computer into your website folders. Select the new glassware subfolder within the Folders structure. This places us in that folder. Click the Browse button under the Upload File section. Navigate to the image file in the pop-up window and click Open. Click the Start Upload button back in the Media Manager. Now we have an image within the glassware folder, it's ready to be used within anarticle. Note that the following screenshot presents the Details View. Deleting an image You might find that as your website consumes more space on the server, you may have to delete some image files. However, be careful doing this, as you don't get a warning! Ensure your site does not require the image anymore, as you will end up with a blank area with a red square in it where the image should be, and that looks unprofessional. Using Thumbnail View within the Media Manager, select the checkbox under the image thumbnail or next to the filename. Click the red "x" icon next to it in order to immediately delete that file, as shown in the following screenshot. You can also use the Delete button in the contextual toolbar at the top right. Updating a Simple Image Gallery Rather than a single image, you might have an article with a Simple Image Gallery embedded within it that presents a selection of thumbnail images to the browser through the article. The gallery plugin parameters can be accessed through the Extensions | Plugins menu along the top of the administration interface. The following screenshot is an example of how one looks on the Party People website. Using the Party People website, we'll update this New Balloons in Stock Now! gallery applying the Balloons folder we made earlier. However, remember that the authors of this plugin recommend only 16 to 20 images per gallery. Navigate to the Media Manager and to the balloons folder. Upload the additional images to the balloons folder using the File Upload tool as outlined in the Uploading a file section of this article. Delete any outdated images, if necessary, by selecting them and clicking the Delete button, as outlined in the Deleting a File section of this article. To display the new images from a different folder in the article, we will need to access the article through which the gallery is presented: Navigate to the Article Manager and open the article containing the gallery of images. You will see something like the following code within the Article's text editor: {gallery}galleryNameIsHere{/gallery} Change this to balloons as in the folder where the balloon images are kept. The following screenshot illustrates the code snippet where you should change the folder name. Apply your changes and review them before going live. Changing the Simple Image Gallery's dimensions If the dimensions of the image gallery, such as the height and width, need to be changed, there are the following steps: Navigate to the Extensions menu using the global menu at the top of the screen. Select Plugin Manager from the drop-down list and navigate through the list until you see the Simple Image Gallery Plugin link in the list. To make this quicker, use the Select Type filter and choose Content. Ensure this plugin is enabled in the Plugin Manager. Click the link to view the parameters for this plug-in; change them as you like. Note that your developer may have changed the name of the module when it was installed. >> Continue Reading Managing Images and Videos in Joomla! 1.5: Part 2 [ 1 | 2 ]  
Read more
  • 0
  • 0
  • 1356