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 - Web Development

1797 Articles
article-image-installing-typo3-extensions
Packt
30 Apr 2010
2 min read
Save for later

Installing TYPO3 Extensions

Packt
30 Apr 2010
2 min read
TYPO3 is one of the most functional and powerful content management systems (CMS). Offering both functionality and expansiveness, TYPO3 is a relevant competitor for commercial solutions. One of the advantages of using TYPO3 is that this CMS has expandability possibilities that are called "extensions". Using these extensions, you can extend the TYPO3 functionality. You can manage shops, galleries, forums, or even a small community portal. You can download extensions from the TYPO3 extension repository (TER): http://typo3.org/extensions. *.t3x is the file format used for extension files. This package is partly compressed using GZIP and it contains the necessary files for the extension (SQL dump, tables, functions, templates, image resources, and so on). This site is a recommended easy way to search for appropriate and suitable extensions. Also, you can find an overview of the extension functionality and additional documentation. For easy extension installation, use its import through Extension Manager. In the extensions section, http://typo3.org/extensions, you'll find the following: New and updated: the latest updated or recently added extensions from the last 20 days—as per the claim on the repository. Popular: a list of the most downloaded extensions on TER. Full list: a complete list of extensions sorted by alphabet. Search: search the form to find an appropriate extension you need. A Search form is also provided in the section New and updated. All the extensions are sorted in groups according to their status: Reviewed extensions: extensions that are secure. These extensions don't affect the normal operation of the system and are qualitative. Alfa: early stage of extension development. Beta: early stage of extension development but operates partly. Stable: stable extension that can be used to provide page functionality. Test: test extension. These kinds of extensions are usually without functionality or are used for concept examples. Obsolete: extensions that are included in the TYPO3 core or are associated with other extensions. For our new shop, we need an eCommerce extension that provides product catalogue and functionality of a shopping cart. You can type shop or commerce in the search area and get a few versions of online shop extensions and those extensions that provide extra functionality to basic extensions. Note the most popular and downloaded online shop extensions: Shop System (tt_products) by Franz Holzinger Webformat Shop System (extendedshop) by Mauro Lorenzutti Commerce (commerce) by Ingo Schmitt, Volker Graubaum, and Thomas Hempel
Read more
  • 0
  • 0
  • 1806

article-image-scripty2-action
Packt
30 Apr 2010
13 min read
Save for later

Scripty2 in Action

Packt
30 Apr 2010
13 min read
(For more resources on Scripty2, see here.) Introduction to Scripty2 Some years ago the web started to see, with great amazement, the born of many JavaScript libraries. Most of them really helped us developers in working with JavasScript code, making life easier, and coding more fun and efective. Some names that usually come to our minds are jQuery, MooTools, dojo, prototype, and surely many, many others. Among these, surely we can remember one called script.aculo.us. It's not only about the cool name, but the great features it brings along with it. Now Thomas Fuchs, the developer behind script.aculo.us, is announcing a newer version. This time called Scripty2, and most interesting of all, this is a full rewrite, every line of code is new, with a big emphasis on making things better, faster and yet easy to use. The three parts in which Scripty2 is divided is: Core Fx Ui We are going to take a quick glance to Fx and Ui, so you can see some of their impressive features. First steps, downloading and placing the necessary code. In order to download the library we need to go to http://scripty2.com/ here we will see an image just like the next one: Clicking on it will result in the file being downloaded, and when the download finishes, we will be able to unzip it. Inside there are three more folders, and the necessary license documents. These folders are: dist → we can find inside this folder the files we will need for the article. doc → the documentation for the library, equal to the online one, but we can check it while offline. However, it's advisable to check the online documentation when possible, as it will be more up to date. src → here we can find the source files for the library, each part of the library being on a separate file. For the Scripty2 library to work, we will also need to included the prototype library, which is also included in the package. But we have another option, that's to include a file called prototype.s2.min.js. This file includes both libraries in it. Summarizing it, if we want to use the Scripty2 libray we have 2 options, to include both libraries separately or simply include prototype.s2.min.js: <script type="text/javascript" src="js/prototype.js"></script> <script type="text/javascript" src="js/s2.js"></script> Note that we are including the prototype-one first, as Scripty2 needs it. The second option, and the one we are going to follow in this article is: <script type="text/javascript" src="js/prototype.s2.min.js"></script> Now, let's take a look at what will be our base structure, first we will have a index.html file, with this code in it: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xml_lang="es-ES" lang="es-ES" ><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><title>Scripty2</title><link rel="stylesheet" href="css/reset.css" type="text/css" /><link rel="stylesheet" href="css/styles.css" type="text/css" /> </head><body> <script type="text/javascript" src="js/prototype.s2.min.js"></script> </body></html> Note that we have our JavaScript file placed at the end of the code, this is usually better for performance. This JavaScript file is located in a folder called js. We have also included two css files, one styles.css, which is empty for now. And the other one is reset.css . I like to use Eric Meyer's css reset which you can find it here:http://meyerweb.com/eric/tools/css/reset/. And that's all we need for now. We are ready to go, we will start with the UI part. Scripty2 UI The Scripty2 includes some very interesting UI controls, like accordion, tabs, autocompleter and many others. I think we could start with the accordion one, as it will make a nice example. Accordion For this we will need to add some code to our index.html file, a good start would be something like this: <body> <div id="tabs_panel"> <ul> <li><a href="#tab1">Sample tab</a></li> <li><a href="#tab2">Another tab</a></li> <li><a href="#tab3">And another one</a></li> </ul> <div id="tab1">1.- This will be the content for the first tab.</div> <div id="tab2">2.- And here we can find the content for the second one.</div> <div id="tab3">3.- Of course we are adding some content to the third one.</div></div> What have we done here? Just three things: First we have created a tabs_panel div, inside which we will place the necessary code for tabs. It will be our container. Next we have placed three div elements, with a link element inside each one, targeting a div. Inside each link, we find the title for the tab. Finally we have placed the final divs, with the ids corresponding to these ones that where being targeted by the previous links. It will be in these divs that we will place the content for each tab. Once we have this code in place we need something more to do the work, as this alone won't do anything. We need to make the necessary Scripty2 function call: ... <div id="tab3">3.- Of course we are adding some content to the third one.</div> </div> <script type="text/javascript" src="./js/prototype.s2.min.js"></script><script type="text/javascript"> new S2.UI.Tabs('tabs_panel');</script> Easy, isn't it? We just need to add this call new S2.UI.Tabs('tabs_panel'); which targets our previously created div. Would this be enough? Let's take a look: It seems nothing has happened, but that's far from true; if we check our page using Firebug, we will see something like the next image: Want to learn more about Firebug? Check this Packt article: http://www.packtpub.com/article/installation-and-getting-started-with-firebug. As we can see in the image, a whole bunch of css classes have been added to our quite simple html code. These classes are responsible for the tabs to work, does that mean that we have to create all of them? Well, not really. Luckily for us, we can use jQuery UI themes for this. Yes, that's it, just go to this url: http://jqueryui.com/themeroller/ And download your favourite one, from the gallery panel: For example, I'm going to download the Hot sneaks one: Once downloaded, we will be able to find the styles we need, inside the packaged file. If we unzip the file we will see these folders: css development-bundle js index.html Opening the css folder we will see a folder called hot-sneaks, or the name of the theme you have downloaded. We will copy the entire folder into our own css folder. Thus we will have this structure: css hot-sneaks reset.css styles.css Inside the hot-sneaks folder there's a file called jquery-ui-1.8.custom.css , we need to link this file in our index.html one, we will add these modifications: … <title>Scripty2</title> <link rel="stylesheet" href="css/reset.css" type="text/css" /> <link rel="stylesheet" href="css/hot-sneaks/jquery-ui-1.8.custom.css" type="text/css" /> <link rel="stylesheet" href="css/styles.css" type="text/css" /> ... But before taking a look at the result of these changes, we still need to do some modifications, this time in our own styles.css file: body{ padding: 10px; }#tabs_panel{ width:350px; font-size: 12px;} And we are done! Our site will look mostly like this: In the image, we can see the three possible states of the tabs: Normal tab Active tab Hover tab It was easy to achieve, isn't it? Next example will be a text autocompleter, stay with us! Text Autocompleter In this example, we are going to use another of the Scripty2 nice feature, this time to build a text autocompleter. This can be used to enhance site search, and it's pretty easy to achieve, thanks to Scripty2. First we need to add the necessary markup in our index.html file: … <div id="tab3">3.- Of course we are adding some content to the third one.</div> </div> <br/><br/> <div id="text_autocompleter"> <input type="text" name="demo" /> </div>... Not much added here, just another container div, and an input, so we can write in it. We now need our JavasCript code to make this work: new S2.UI.Tabs('tabs_panel'); var favourite = [ 'PHP', 'Ruby', 'Python', '.NET', 'JavaScript', 'CSS', 'HTML', 'Java' ]; new S2.UI.Autocompleter('text_autocompleter', { choices: favourite }); </script> … First what we need to do is to create an array of possible values, and then we call the Autocompleter method, with two parameters, first the div we are targetting, and then the array of values. Also we are going to modify our styles.css file, just to add some styling to our text_autocompleter div: ...#tabs_panel, #text_autocompleter{ width:350px; ... If we check our page after these changes, it will be looking this: If we try to enter some text, like a p in the example, we will see how options appear in the box under the input. If we do click on the option, the input box will be filled: Just after we select our desired option the suggestions panel will disappear, as it will do if we click outside the input box. Note that if the theme we are using lacks the ui-helper-hidden class, the suggestions panel won't dissapear. But don't worry, solving this is as easy as adding this class to our styles.css file: .ui-helper-hidden{    visibility: hidden;    } And we are done, now lets see an example about the accordion control. Accordion This is quite similar to the tabs example, quite easy too, first, as always, we are going to add some html markup to our index.html file: <div id="accordion"> <h3><a href="#">Sample tab</a></h3> <div> 1.- This will be the content for the first tab. </div> <h3><a href="#">Another tab</a></h3> <div> 2.- And here we can find the content for the second one. </div> <h3><a href="#">And another one</a></h3> <div> 3.- Of course we are adding some content to the third one. </div> </div> Good, this will be enough for now. We have a container div, where we are placing the necessary elements, each h3 element, with links inside, will be the headings, and the divs will be the contents for each tab. Let's add some styles in our styles.css file: #tabs_panel, #text_autocompleter, #accordion{ width:350px; font-size: 12px;}#accordion h3 a{ padding-left: 30px; } I've placed the necessary changes in bold. Now to the JavaScript code, we will add this in our index.html file: … new S2.UI.Accordion('accordion'); </script> ... The first parameter will be the id of our container div, for now, we don't need anything more. How does all this look like? Just take a look: Good, clicking on each one of the headings will result in closing the current tab and opening the clicked one. But, what if we want to be able to open each clicked tab, but without closing the others? Well, thanks to Scripty2 we can also achieve that. We only need to make some small modifications to the JavaScript call: …new S2.UI.Accordion('accordion', { multiple: true }); </script> … As we see, the second parameter for our accordion function can receive some options, this time we are selecting multiple to true. This way our accordion tabs won't close: In the previous image we can see all our tabs open, but we have some more options, let's see them. The first one will help us define our prefered header selector. As our code is now we are using h3 elements: <h3><a href="#">Sample tab</a></h3> <div> 1.- This will be the content for the first tab.</div>   But what if we wanted to use h1 elements? Well, it won't be very hard, just a tiny add to our JavaScript code: new S2.UI.Accordion('accordion', { multiple: true, headerSelector: 'h1' }); The last option we are going to see is the icons one, by default, this option will use these values: icons: { header:'ui-icon-triangle-1-e',headerSelected: 'ui-icon-triangle-1-s' } Where do these icons come from? Well, these little icons are from the theme we downloaded, and we have plenty of them to use. If you open the theme package, the one we downloaded at the start of the article, and we click on the index.html file, we will be able to see a demo of all styles included in the package. More or less at the bottom we will see a group of tiny icons:   If we hover over these little icons, its name will appear, and that's what we can use to change our options. So in our index.html file, we could change our JavaScript code just like this: new S2.UI.Accordion('accordion', { multiple: true, headerSelector: 'h1', icons: { header: 'ui-icon-circle-plus', headerSelected: 'ui-icon-circle-minus' } }); We define one option for the headers, and other for the selected one, how will this look like:   And with this option we have seen all the three available. With them we can customize our accordion as we wish. Summarizing, we have found that the Scripty2 library includes some very useful UI controllers. We have seen some of them, but there are many others, such as: Buttons → Scripty2 helps us in creating good looking buttons. Not only normal buttons, but also buttons that behave as checkboxes, or even radio buttons. Dialog → There are also some functions in the Scripty2 library that will help us in creating modal dialog boxes, with the contents we want. Slider → If at anytime we are in need of creating a slider, be it for moving the contents of a div, for creating an image gallery or for creating an interesting price filter, it is pretty easy with Scripty2. Progress bar → This one is pretty interesting, as will help us in the task of developing an animated progress bar, very nice! Now we will be taking a look at another interesting part of the library, the FX one.
Read more
  • 0
  • 0
  • 4615

article-image-using-aspnet-master-pages-your-mcms-applications
Packt
29 Apr 2010
6 min read
Save for later

Using ASP.NET Master Pages in your MCMS Applications

Packt
29 Apr 2010
6 min read
Overview and Benefits of Master Pages A master page includes common markup and one or more content placeholders. From this master page, new content pages can be created, which include content controls that are linked to the content placeholders in the master page. This provides an ideal way to separate common site branding, navigation, etc., from the actual content pages, and can significantly decrease duplication and markup errors. Master pages make working with template files a lot easier than before. You can add common markup and shared controls such as headers, footers, and navigation bars to master pages. Once a master page has been built, you can create MCMS template files based upon it. The template files will immediately adopt the look and feel defined in the master template. You can also mark certain regions of the master page to be customizable by introducing content placeholders (note that these are controls designed specifically for master pages and are not to be confused with MCMS placeholder controls). The space marked by content placeholders provides areas where you could add individual template markup as well as MCMS placeholder controls, as shown in the following diagram: Although at first glance both master pages and MCMS templates offer a way to standardize the look and feel of a site, their similarities end there. Don’t be mistaken into thinking that master pages take over the role of MCMS templates completely. A key difference between the two is that the use of master pages is reserved solely for site developers to ensure that template files created have a common look and feel. You can’t create a master page and expect authors to use it to create postings. In fact, master pages work alongside template files and offer a number of benefits to MCMS developers. Avoids duplication in MCMS Template files: Often MCMS templates contain common page layout code (usually an HTML table) along with navigation bars, headers, and footers (usually web user controls). This code has to be copied and pasted into each new template file after it is created or abstracted into user controls. In addition a change in the layout of this common code has to be applied to all template files. So, for example, an MCMS application with ten template files will duplicate this markup ten times. By placing this markup within a master page, this duplication can be removed. Separation of site-wide markup from template markup: One of the biggest drawbacks to MCMS is that the task of developing templates cannot be easily separated. It is a common requirement to separate the tasks of defining site branding, layout, and the development of controls such as navigation (performed by webmasters and programmers) from the task of designing template layouts (performed by business users). While master pages and Visual Studio 2005 do not address this completely due to MCMS’s inherent architecture, they offer a substantial improvement in this area. Avoids issues with MCMS Template File Visual Studio templates: The MCMS Project Item Templates have a number of issues, and do not fully embrace the Visual Studio 2005 project system. Although any web form can be MCMS ‘enabled’, master pages offer a more seamless development experience with less manual tweaks required. Visual Studio 2005 Designer support: One of the common problems with using user controls within template files in Visual Studio .NET is that the template design view doesn't provide an adequate experience for template developers. Visual Studio 2005 offers an improved design-view experience including rendering of user control content, and this is especially valuable when working with master pages. Experience of Master Pages: Just as MCMS is a great way to learn ASP.NET, MCMS SP2 is a great way to learn ASP.NET 2.0! In addition, master pages are a fundamental building block of future Web Content Management offerings from Microsoft. MCMS placeholder controls in the master page will work, but are not officially supported. As we will see in this article, master pages provide an ideal way to separate common site branding, navigation, etc., from the actual content pages, and can significantly decrease duplication and markup errors. The TropicalGreen Web Site Tropical Green is the fictitious gardening society upon which the article’s sample website is based. In the book, Building Websites with Microsoft Content Management Server from Packt Publishing (ISBN 1-904811-16-7), we built the Tropical Green website from scratch using ASP.NET 1.x. In this article series, we will attempt to rebuild parts of the website using MCMS SP2 and ASP.NET 2.0. While the code will be rewritten from the ground-up, we won’t start with a blank database. Instead, we’ll take a shortcut and import the TropicalGreen database objects from the TropicalGreen.sdo file available from the support section on Packt Publishing’s website (http://www.packtpub.com/support). Importing the TropicalGreen Site Deployment Object File Before we begin, let’s populate the database by importing objects using the Site Deployment Manager. Download the TropicalGreen.sdo file. Open Site Manager and log in with an MCMS administrator account. From the menu, select File | Package | Import…. In the Site Deployment Import dialog, click on the Browse… button. Navigate to the TropicalGreen_Final.sdo file downloaded earlier. In the Container Rules tab, set the following: Property Value When Adding Containers Use package container rights When Replacing Containers Keep destination container rights In the Rights Group tab, set the following: Property Value Select how Rights Groups are imported Import User Rights Groups Click on Import. The import confirmation dialog appears. Click on Continue. Creating a New MCMS Web Application To get started, let’s create a new MCMS web application using the project templates we created in the previous article. From Visual Studio, from the File Menu, choose New | Web Site. In the New Web Site dialog, select the MCMS SP2 Web Application icon in the My Templates section. Select HTTP in the Location list box. Enter http://localhost/TropicalGreen in the Location textbox, and click on OK. Our MCMS web application is created and opened in Visual Studio 2005.
Read more
  • 0
  • 0
  • 1606
Visually different images

article-image-django-debugging-overview
Packt
28 Apr 2010
9 min read
Save for later

Django Debugging Overview

Packt
28 Apr 2010
9 min read
Django debug settings Django has a number of settings that control the collection and presentation of debug information. The primary one is named DEBUG; it broadly controls whether the server operates in development (if DEBUG is True) or production mode. In development mode, the end-user is expected to be a site developer. Thus, if an error arises during processing of a request, it is useful to include specific technical information about the error in the response sent to the web browser. This is not useful in production mode, when the user is expected to be simply a general site user. This section describes three Django settings that are useful for debugging during development. Additional settings are used during production to control what errors should be reported, and where error reports should be sent. These additional settings will be discussed in the section on handling problems in production. The DEBUG and TEMPLATE_DEBUG settings DEBUG is the main debug setting. One of the most obvious effects of setting this to True is that Django will generate fancy error page responses in the case of serious code problems, such as exceptions raised during processing of a request. If TEMPLATE_DEBUG is also True, and the exception raised is related to a template error, then the fancy error page will also include information about where in the template the error occurred. The default value for both of these settings is False, but the settings.py file created by manage.py startproject turns both of them on by including these lines at the top of the file: DEBUG = True TEMPLATE_DEBUG = DEBUG Note that setting TEMPLATE_DEBUG to True when DEBUG is False isn't useful. The additional information collected with TEMPLATE_DEBUG turned on will never be displayed if the fancy error pages, controlled by the DEBUG setting, are not displayed. Similarly, setting TEMPLATE_DEBUG to False when DEBUG is True isn't very useful. In this case, for template errors, the fancy debug page will be lacking helpful information. Thus, it makes sense to keep these settings tied to each other, as previously shown. Details on the fancy error pages and when they are generated will be covered in the next section. Besides generating these special pages, turning DEBUG on has several other effects. Specifically, when DEBUG is on: A record is kept of all queries sent to the database. Details of what is recorded and how to access it will be covered in a subsequent section. For the MySQL database backend, warnings issued by the database will be turned into Python Exceptions. These MySQL warnings may indicate a serious problem, but a warning (which only results in a message printed to stderr) may pass unnoticed. Since most development is done with DEBUG turned on, raising exceptions for MySQL warnings then ensures that the developer is aware of the possible issue. The admin application performs extensive validation of the configuration of all registered models and raises an ImproperlyConfigured exception on the first attempt to access any admin page if an error is found in the configuration. This extensive validation is fairly expensive and not something you'd generally want done during production server start-up, when the admin configuration likely has not changed since the last start-up. When running with DEBUG on, though, it is possible that the admin configuration has changed, and thus it is useful and worth the cost to do the explicit validation and provide a specific error message about what is wrong if a problem is detected. Finally, there are several places in Django code where an error will occur while DEBUG is on, and the generated response will contain specific information about the cause of the error, whereas when DEBUG is off the generated response will be a generic error page. The TEMPLATE_STRING_IF_INVALID setting A third setting that can be useful for debugging during development is TEMPLATE_STRING_IF_INVALID. The default value for this setting is the empty string. This setting is used to control what gets inserted into a template in place of a reference to an invalid (for example, non-existent in the template context) variable. The default value of an empty string results in nothing visible taking the place of such invalid references, which can make them hard to notice. Setting TEMPLATE_STRING_IF_INVALID to some value can make tracking down such invalid references easier. However, some code that ships with Django (the admin application, in particular), relies on the default behavior of invalid references being replaced with an empty string. Running code like this with a non-empty TEMPLATE_STRING_IF_INVALID setting can produce unexpected results, so this setting is only useful when you are specifically trying to track down something like a misspelled template variable in code that always ensures that variables, even empty ones, are set in the template context. Debug error pages With DEBUG on, Django generates fancy debug error pages in two circumstances: When a django.http.Http404 exception is raised When any other exception is raised and not handled by the regular view processing code In the latter case, the debug page contains a tremendous amount of information about the error, the request that caused it, and the environment at the time it occurred. The debug pages for Http404 exceptions are considerably simpler. To see examples of the Http404 debug pages, consider the survey_detail view def survey_detail(request, pk): survey = get_object_or_404(Survey, pk=pk) today = datetime.date.today() if survey.closes < today: return display_completed_survey(request, survey) elif survey.opens > today: raise Http404 else: return display_active_survey(request, survey) There are two cases where this view may raise an Http404 exception: when the requested survey is not found in the database, and when it is found but has not yet opened. Thus, we can see the debug 404 page by attempting to access the survey detail for a survey that does not exist, say survey number 24. The result will be as follows: Notice there is a message in the middle of the page that describes the cause of the page not found response: No Survey matches the given query. This message was generated automatically by the get_object_or_404 function. By contrast, the bare raise Http404 in the case where the survey is found but not yet open does not look like it will have any descriptive message. To confirm this, add a survey that has an opens date in the future, and try to access its detail page. The result will be something like the following: That is not a very helpful debug page, since it lacks any information about what was being searched for and why it could not be displayed. To make this page more useful, include a message when raising the Http404 exception. For example: raise Http404("%s does not open until %s; it is only %s" % (survey.title, survey.opens, today)) Then an attempt to access this page will be a little more helpful: Note that the error message supplied with the Http404 exception is only displayed on the debug 404 page; it would not appear on a standard 404 page. So you can make such messages as descriptive as you like and not worry that they will leak private or sensitive information to general users. Another thing to note is that a debug 404 page is only generated when an Http404 exception is raised. If you manually construct an HttpResponse with a 404 status code, it will be returned, not the debug 404 page. Consider this code: return HttpResponse("%s does not open until %s; it is only %s" % (survey.title, survey.opens, today), status=404) If that code were used in place of the raise Http404 variant, then the browser will simply display the passed message: Without the prominent Page not found message and distinctive error page formatting, this page isn't even obviously an error report. Note also that some browsers by default will replace the server-provided content with a supposedly "friendly" error page that tends to be even less informative. Thus, it is both easier and more useful to use the Http404 exception instead of manually building HttpResponse objects with status code 404. A final example of the debug 404 page that is very useful is the one that is generated when URL resolution fails. For example, if we add an extra space before the survey number in the URL, the debug 404 page generated will be as follows: The message on this page includes all of the information necessary to figure out why URL resolution failed. It includes the current URL, the name of the base URLConf used for resolution, and all patterns that were tried, in order, for matching. If you do any significant amount of Django application programming, it's highly likely that at some time this page will appear and you will be convinced that one of the listed patterns should match the given URL. You would be wrong. Do not waste energy trying to figure out how Django could be so broken. Rather, trust the error message, and focus your energies on figuring out why the pattern you think should match doesn't in fact match. Look carefully at each element of the pattern and compare it to the actual element in the current URL: there will be something that doesn't match. In this case, you might think the third listed pattern should match the current URL. The first element in the pattern is the capture of the primary key value, and the actual URL value does contain a number that could be a primary key. However, the capture is done using the pattern d+. An attempt to match this against the actual URL characters—a space followed by 2—fails because d only matches numeric digits and the space character is not a numeric digit. There will always be something like this to explain why the URL resolution failed. For now, we will leave the subject of debug pages and learn about accessing the history of database queries that is maintained when DEBUG is on.
Read more
  • 0
  • 0
  • 2148

article-image-form-validation-codeigniter-17
Packt
26 Apr 2010
8 min read
Save for later

Form Validation with Codeigniter 1.7

Packt
26 Apr 2010
8 min read
Form validation is an important part of any application. Take a look at your favorite web application, notice that there are many forms in these web apps, and it is important that they be secure. It is also important that you have rules that should be adhered to; this also helps to keep a layer of security. In this article by Adam Griffiths, author of CodeIgniter 1.7 Professional Development, you will: Learn how the form validation process works Build a contact form Apply validation rules to the form's input fields Use callbacks to create your own rules We will cover database interaction seperately. (Read more interesting articles on CodeIgniter 1.7 Professional Development here.) Why should I validate my forms? The answer to this question is simple: security. If you simply left your forms bare, with no validation, and then stored this information directly in a database, you are liable to attack. People can simply place in some SQL code and can see a dump of a part or all of your database. By using form validation and creating rules, you will disallow most, if not all, of these practices from occurring. By having set validation rules you can limit the types of data being allowed in your forms. Best of all, the Form Validation Library makes it easy to re-populate your form fields and to show individual errors for each field, making the overall end user experience better; which can mean a lot in an environment with many forms. Even if you are building a contact form, it is a good idea to validate your forms to stop people abusing your form. Using the Form Validation Library In this article, we'll go over a Contact Form and how to use the Form Validation Library methods for validation. The form validation process The Form Validation processes are different for the developers and for users. Read on to see how the user interacts with the forms, as well as how the developer will create the forms. The user's process A form is displayed to the user, who then fills it in and submits it. The Form Validation Library then checks the form against any rules that the developer has set. If an error occurs the library returns these errors and they are shown against the form with the fields re-populated. This process proceeds until a valid form is submitted. The development process You create a form, along with a dynamic value from a form helper function—this will re-populate the data if needed. You will also display individual or global errors in the form view file. You set validation rules, which must be adhered to. Then you check to see if the validation process has been run, and if it has not, you load the form view file. Contact form We validate the form data using the Form Validation Library to complete tasks such as checking for empty fields, validating the e-mail, and then send the e-mail off. All of the code shown should be in the index() function of your email controller. Loading the assets We need to load two libraries for our contact form: the Form Validation Library and the Email class. We can do this in one line, by passing an array to the load->library function. $this->load->library(array('email', 'form_validation')); We also need to load two helpers: the email helper and the form helper. We will do this in the same way as we loaded the two libraries in the previous line of code. $this->load->helper(array('email', 'form')); Setting the rules The next step in using the Form Validation Library is to set the rules for the form. These rules are set and must be adhered to. The way we set rules is by using the set_rules() function of the Form Validation Library. We use the function as follows: $this->form_validation-> set_rules('field_name', 'human_name', 'rules'); As you can see, the function accepts three parameters. The first is the name of the form field that you wish to set the rule for. The second parameter is the name that you wish to be assigned to this, for humans to read. The final parameter is where you pass any validation rules. List of validation rules The following rules are readily available for use: required matches[field_name] min_length[x] max_length[x] exact_length[x] alpha alpha_numeric alpha_dash numeric integer is_natural is_natural_no_zero valid_email valid_emails valid_ip valid_base64 As you can see, some of these rules have a single parameter. The rule matches[] will return TRUE if the field matches the field name passed to it. The min_length[], max_length[], and exact_length[] rules will take an integer as a parameter and check if the minimum length, maximum length respectively, or exact length matches the rule. The rules with no parameters are pretty much self-explanatory. You are able to use more than one rule, simply separate rules with a vertical bar '|' and they will cascade. These rules can also be called as discrete functions. You may also use any native PHP function that accepts one parameter as a rule. $this->form_validation->required($string);$this->form_validation->is_array($string); // native PHP // function as a rule Prepping data We can also use various prepping functions to prep the data before we apply rules to it. Here's a list of the prepping rules that we can perform: xss_clean prep_for_form prep_url strip_image_tags encode_php_tags The first function listed is xss_clean. This basically strips out any code and unwanted characters, and replaces them with HTML entities. The function prep_for_form will convert special characters so that HTML data can be shown in a form without breaking it. The function prep_url will simply add http:// to a URL, if it is missing. The function strip_image_tags will remove image tags, leaving the RAW image URL. The function encode_php_tags will convert PHP tags into entities. You may also use any native PHP function that accepts one parameter as a rule. The rules Now that we know how to set rules and what the rules we can use are, we can go ahead and set the rules necessary for our form. All fields should be required, and the e-mail field should be validated to ensure that the e-mail address is correctly formatted. We also want to run all of the data through the XSS filter. $this->form_validation-> set_rules('name', 'Name', 'required|xss_clean');$this->form_validation-> set_rules('email', 'Email Address', 'required|valid_email|xss_clean');$this->form_validation-> set_rules('subject', 'Subject', 'required|xss_clean');$this->form_validation->set_rules('message', 'Message', 'required|xss_clean'); Check the validation process Instead of checking one of the form field's POST value to check if the form has been submitted, we simply check to see if the Form Validation Library has run. We do this by using the following code: if($this->form_validation->run() === FALSE){ // load the contact form}else // send the email} It's fairly simple: if the Form Validation Library hasn't processed a form, we display the form to the user; if the library has processed a form and there are no errors, we'll send the e-mail off. Sending the email As you'll notice, everything is the same as how we got the field data earlier. $name = $this->input->post('name');$email = $this->input->post('email');$subject = $this->input->post('subject');$message = $this->input->post('message'); $this->email->from($email, $name);$this->email->to('[email protected]'); $this->email->subject($subject);$this->email->message($message); $this->email->send(); Final controller code Here is the entirety of our controller code: <?phpclass Email extends Controller{function Email(){parent::Controller();} // function Email()function index(){$this->load->library(array('email', 'form_validation'));$this->load->helper(array('email', 'form'));$this->form_validation->set_rules('name', 'Name', 'required|xss_clean');$this->form_validation->set_rules('email', 'Email Address','required|valid_email|xss_clean');$this->form_validation->set_rules('subject', 'Subject', 'required|xss_clean');$this->form_validation->set_rules('message', 'Message', 'required|xss_clean');if($this->form_validation->run() == FALSE){$this->load->view('email'); // load the contact form}else{$name = $this->input->post('name');$email = $this->input->post('email');$subject = $this->input->post('subject');$message = $this->input->post('message');$this->email->from($email, $name);$this->email->to('[email protected]');$this->email->subject($subject);$this->email->message($message);$this->email->send();}} // function index()} // class Email extends Controller?>
Read more
  • 0
  • 0
  • 3486

article-image-flash-video-encoding-skinning-and-components-wordpress
Packt
26 Apr 2010
6 min read
Save for later

Flash Video Encoding, Skinning and Components in Wordpress

Packt
26 Apr 2010
6 min read
Encoding with the Adobe Media Encoder If you have a video file, such as an MOV or MP4 file that you want to display as a SWF on the Web, simply encode (or compress) the video file into an FLV. With Flash CS4, you use the Adobe Media Encoder to do this. It can be accessed directly or through Flash's import video function. If you are using an earlier version of Flash, encoding is still possible, and the process is similar. Getting ready Make sure that you have a video file that is compatible with the Adobe Media Encoder. If you do not have a file to use, by all means, use the short.mov file. This file is a clip of the full length summer.mp4 file from www.archive.org that is listed on that website as being in the Public Domain. Use the MOV file because it is a short file, so the time it takes the encoder to render the video will be shorter. This is good for the purposes of learning and practicing. Also, do not worry if you cannot hear any of the sounds. There is nothing wrong with the speakers on your computer. This file does not have audio. How to do it... Open the Adobe Media Encoder: Click on the Add button. Navigate to the file you want to encode, such as short.move, and click on Choose/OK. It is now listed in the queue: Click on the down arrow under Format to select into which file format you will encode the video. Choose FLV | F4V if not already selected. Click on the down arrow under Preset to choose one of the preset export setting options. The default of FLV - Same As Source (Flash 8 and Higher) is generally fine. If you have fewer standard video needs, make a different choice based on your needs. Also, there is an option to Edit Export Settings as well as a Settings button if you want to make your own decisions. See the Edit Export Settings section for more on that. Click on the file name under Output File to select the destination of your encoded file. You can also change the file name. Click on Start Queue, and the encoding process will begin. If you are encoding a long video, you might want to go take a walk or get a cup of tea. For short.mov, just sit tight. It should only take a minute or two to encode. Once encoding is complete, the FLV is saved in the location you chose under the Output File section. There is also a check mark under the encoder's Status section. Now, you can do what you want with the file. For instance, you can take it into Flash and import it into an SWF. How it works... The Adobe Media Encoder encodes the selected video file into the FLV format. It is similar to taking a Photoshop file or a TIFF and compressing either of them into a JPG. The process is simply more involved because the data is more complex. There's more... The Adobe Media Encoder has many options and capabilities. Among these is a wealth of export settings that can be edited to suit your needs. Also available to you is the ability to not only encode multiple files in one sitting but also to duplicate and remove files in your queue. Edit Export Settings With your file selected in the encoder, click on the Settings button. This gives you the Export Settings dialog box: As you can see, it has a lot of options. Only some of the myriad of options will be discussed below. At the top left of the dialog box are two buttons: Source and Output. Source shows the video file you have selected. Output shows a preview of the encoded version of the file. On the bottom/middle left of the Export Settings dialog box, you can address the timeline. You are able to clip the movie if you want to export only part of it; and you can set up cue points. To clip the movie, do the following: Drag the playback head back and forth to manually preview the movie. This helps you find the section you want to keep. Drag the in and out point triangles back and forth to isolate the section you want to keep. The triangle on the left is the in point, and the one on the right is the out point. Everything between the two triangles will be encoded. The timer keeps track of time in milliseconds. The right side of the dialog box allows you to change the desired file format; save your own preset with the button that looks like a computer disk circa 1996. You can also change the file name of the encoded video and choose if you are exporting only video, only audio, or both. The Summary section gives you just that, a summary of your choices thus far. The bottom right section gives you options for putting on a blur filter under the Filter tab and changing the format as applicable under the Format tab. The Video tab lets you choose which Codec to use to encode the video. On2 VP6 is usually the best choice. Stick with that one. It is more advanced, gives better quality, and allows you to encode an Alpha Channel if you have one to encode. Alpha Channels, areas of transparency in video (i.e., green screen), cannot be set up in Flash. They must be set up in a video editing program such as Premiere Pro or Final Cut Pro. The encoder can only honor them, not generate them. If you need to resize your video, check the box for Resize Video, and change the values as needed. If you want to constrain the proportions of your video, leave the chain whole. Frame rate can also be changed here. Generally, it is in your best interest to leave the video set to the same frame rate it was shot in. Same as source is a good choice. For Bitrate Settings, the defaults are usually pretty good. If you want higher quality and can take the additional file size, you can change Encoding Passes to Two. For Advanced Settings, you can change overall quality by selecting either Quality for Speed, Good, or Best. It all depends on your needs. For Audio, if you have it incorporated into your video file, choose Stereo. It sounds better. The only reason to go with Mono is if you have little sound, if it is a video of a talking head, or if your file size needs to be as small as possible. For Bitrate Settings for audio, 128 kb per second is good. Again, only turn this lower if the audio is overly simple, not important, or your file size dictates it. Faster bitrate/higher number gives you better quality sound. When you are finished making changes, click on OK. This gets you back to the encoder. Proceed from here as needed.
Read more
  • 0
  • 0
  • 1493
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 €14.99/month. Cancel anytime
article-image-database-interaction-codeigniter-17
Packt
26 Apr 2010
4 min read
Save for later

Database Interaction with Codeigniter 1.7

Packt
26 Apr 2010
4 min read
(Read more interesting articles on CodeIgniter 1.7 Professional Development here.) Loading the library Loading the Database library is slightly different from loading other libraries. This is because it is large and resides in a different folder, unlike the other libraries. $this->load->database(); Performing simple queries Let's dive straight in by starting with the simple stuff. CodeIgniter gives us a function that we can pass a SQL Query to, and the query will be run on the database. Here's how it works: $this->db->query('PUT YOUR SQL HERE'); This function is incredibly simple to use; you simply use this function in place of any native PHP functions you would use to run queries. This function will return TRUE or FALSE for write queries, and will return a dataset for read queries. There is another function that you can use for very simple queries; this will only return TRUE or FALSE. It won't let you cache your query or run the query timer. In most cases you won't want to use this function. $this->db->simple_query('PUT YOUR SQL HERE'); The SQL code that you pass to these functions are database-dependent. Only Active Record queries are independent of any type of Database SQL. Returning values You can assign the function $this->db->query() to a variable. You can then run a number of helper functions on the variable in order to return the data in different formats. Take the following example: $query = $this->db->query('SELECT * FROM 'users''); Return a result object In this case, returning the result will return an array of objects, or an empty array if the query failed. You would usually use this function in a foreach loop. foreach($query->result() as $row){ echo $row->username; echo $row->email;} If your query does not return a result, the CodeIgniter User Guide encourages you to check for a failure before using this function. if($query->num_rows > 0){ foreach($query->result() as $row) { echo $row->username; echo $row->email; }} Returning a result array You are also able to return the result dataset as an array. Typically, you would use this function inside a foreach loop as well. foreach($query->result_array() as $row){ echo $row['username']; echo $row['email'];} Returning a row object If your query is only expected to return a single result, you should return the row by using the following function. The row is returned as an object. if($query->num_rows() > 0){$row = $query->row();echo $row->username;echo $row->email;} You can return a specific row by passing the row number as a digit in the first parameter. $query->row(2); Returning a row array You can return a row as an array, if you prefer. The function is used in the same way as the previous example. if($query->num_rows() > 0){ $row = $query->row_array(); echo $row['username']; echo $row['email'];} You can return a numbered row by passing the digit to the first parameter, also. $query->row_array(2); Result helper functions Besides the helper function that helps to return the dataset in different ways, there are some other more generalized helper functions. Number of rows returned Used in the same way as the other helper functions, this will return the total number of rows returned from a query. Take the following example: echo $query->num_rows(); Number of fields returned Just like the previous function, this will return the number of fields returned by your query. echo $query->num_fields(); Free result This function will remove the resource ID associated with your query, and free the associated memory. PHP will usually do this by default, although when using many queries you may wish to use this to free up memory space. $query->free_result();
Read more
  • 0
  • 0
  • 1981

article-image-data-manipulation-silverlight-4-data-grid
Packt
26 Apr 2010
9 min read
Save for later

Data Manipulation in Silverlight 4 Data Grid

Packt
26 Apr 2010
9 min read
Displaying data in a customized DataGrid Displaying data is probably the most straightforward task we can ask the DataGrid to do for us. In this recipe, we'll create a collection of data and hand it over to the DataGrid for display. While the DataGrid may seem to have a rather fixed layout, there are many options available on this control that we can use to customize it. In this recipe, we'll focus on getting the data to show up in the DataGrid and customize it to our likings. Getting ready In this recipe, we'll start from an empty Silverlight application. The finished solution for this recipe can be found in the Chapter04/Datagrid_Displaying_Data_Completed folder in the code bundle that is available on the Packt website. How to do it... We'll create a collection of Book objects and display this collection in a DataGrid. However,we want to customize the DataGrid. More specifically, we want to make the DataGridfixed. In other words, we don't want the user to make any changes to the bound data or move the columns around. Also, we want to change the visual representation of the DataGrid by changing the background color of the rows. We also want the vertical column separators to be hidden and the horizontal ones to get a different color. Finally, we'll hook into the LoadingRow event, which will give us access to the values that are bound to a row and based on that value, the LoadingRow event will allow us to make changes to the visual appearance of the row. To create this DataGrid, you'll need to carry out the following steps: Start a new Silverlight solution called DatagridDisplayingData in Visual Studio. We'll start by creating the Book class. Add a new class to the Silverlight project in the solution and name this class as Book. Note that this class uses two enumerations—one for the Category and the other for the Language. These can be found in the sample code. The following is the code for the Book class: public class Book { public string Title { get; set; } public string Author { get; set; } public int PageCount { get; set; } public DateTime PurchaseDate { get; set; } public Category Category { get; set; } public string Publisher { get; set; } public Languages Language { get; set; } public string ImageName { get; set; } public bool AlreadyRead { get; set; } } In the code-behind of the generated MainPage.xaml file, we need to create a generic list of Book instances (List) and load data into this collection.This is shown in the following code: private List<Book> bookCollection; public MainPage() { InitializeComponent(); LoadBooks(); } private void LoadBooks() { bookCollection = new List<Book>(); Book b1 = new Book(); b1.Title = "Book AAA"; b1.Author = "Author AAA"; b1.Language = Languages.English; b1.PageCount = 350; b1.Publisher = "Publisher BBB"; b1.PurchaseDate = new DateTime(2009, 3, 10); b1.ImageName = "AAA.png"; b1.AlreadyRead = true; b1.Category = Category.Computing; bookCollection.Add(b1); ... } Next, we'll add a DataGrid to the MainPage.xaml file. For now, we won't add any extra properties on the DataGrid. It's advisable to add it to the page by dragging it from the toolbox, so that Visual Studio adds the correct references to the required assemblies in the project, as well as adds the namespace mapping in the XAML code. Remove the AutoGenerateColumns="False" for now so that we'll see all the properties of the Book class appear in the DataGrid. The following line of code shows a default DataGrid with its name set to BookDataGrid: <sdk:DataGrid x_Name="BookDataGrid"></sdk:DataGrid> Currently, no data is bound to the DataGrid. To make the DataGrid show the book collection, we set the ItemsSource property from the code-behind in the constructor. This is shown in the following code: public MainPage() { InitializeComponent(); LoadBooks(); BookDataGrid.ItemsSource = bookCollection; } Running the code now shows a default DataGrid that generates a column for each public property of the Book type. This happens because the AutoGenerateColumns property is True by default. Let's continue by making the DataGrid look the way we want it to look. By default, the DataGrid is user-editable, so we may want to change this feature. Setting the IsReadOnly property to True will make it impossible for a user to edit the data in the control. We can lock the display even further by setting both the CanUserResizeColumns and the CanUserReorderColumns properties to False. This will prohibit the user from resizing and reordering the columns inside the DataGrid, which are enabled by default. This is shown in the following code: <sdk:DataGrid x_Name="BookDataGrid" AutoGenerateColumns="True" CanUserReorderColumns="False" CanUserResizeColumns="False" IsReadOnly="True"> </sdk:DataGrid> The DataGrid also offers quite an impressive list of properties that we can use to change its appearance. By adding the following code, we specify alternating the background colors (the RowBackground and AlternatingRowBackground properties), column widths (the ColumnWidth property), and row heights (the RowHeight property). We also specify how the gridlines should be displayed (the GridLinesVisibility and HorizontalGridLinesBrushs properties). Finally, we specify that we also want a row header to be added (the HeadersVisibility property ). <sdk:DataGrid x_Name="BookDataGrid" AutoGenerateColumns="True" CanUserReorderColumns="False" CanUserResizeColumns="False" RowBackground="#999999" AlternatingRowBackground="#CCCCCC" ColumnWidth="90" RowHeight="30" GridLinesVisibility="Horizontal" HeadersVisibility="All" HorizontalGridLinesBrush="Blue"> </sdk:DataGrid> We can also get a hook into the loading of the rows. For this, the LoadingRow event has to be used. This event is triggered when each row gets loaded. Using this event, we can get access to a row and change its properties based on custom code. In the following code, we are specifying that if the book is a thriller, we want the row to have a red background: private void BookDataGrid_LoadingRow(object sender, DataGridRowEventArgs e) { Book loadedBook = e.Row.DataContext as Book; if (loadedBook.Category == Category.Thriller) { e.Row.Background = new SolidColorBrush(Colors.Red); //It's a thriller! e.Row.Height = 40; } else { e.Row.Background = null; } } After completing these steps, we have the DataGrid that we wanted. It displays the data (including headers), fixes the columns and makes it impossible for the user to edit the data. Also, the color of the rows and alternating rows is changed, the vertical grid lines are hidden, and a different color is applied to the horizontal grid lines. Using the LoadingRow event, we have checked whether the book being added is of the "Thriller" category, and if so, a red color is applied as the background color for the row. The result can be seen in the following screenshot: How it works... The DataGrid allows us to display the data easily, while still offering us many customization options to format the control as needed. The DataGrid is defined in the System.Windows.Controls namespace, which is located in the System.Windows.Controls.Data assembly. By default, this assembly is not referenced while creating a new Silverlight application. Therefore, the following extra references are added while dragging the control from the toolbox for the first time: System.ComponentModel.DataAnnotations System.Windows.Controls.Data System.Windows.Controls.Data.Input System.Windows.Data While compiling the application, the corresponding assemblies are added to the XAP file (as can be seen in the following screenshot, which shows the contents of the XAP file). These assemblies need to be added because while installing the Silverlight plugin, they aren't installed as a part of the CLR. This is done in order to keep the plugin size small. However, when we use them in our application, they are embedded as part of the application. This results in an increase of the download size of the XAP file. In most circumstances, this is not a problem. However, if the file size is an important requirement, then it is essential to keep an eye on this. Also, Visual Studio will include the following namespace mapping into the XAML file: From then on, we can use the control as shown in the following line of code: <sdk:DataGrid x_Name="BookDataGrid"> </sdk:DataGrid> Once the control is added on the page, we can use it in a data binding scenario. To do so, we can point the ItemsSource property to any IEnumerable implementation. Each row in the DataGrid will correspond to an object in the collection. When AutoGenerateColumns is set to True (the default), the DataGrid uses a refl ection on the type of objects bound to it. For each public property it encounters, it generates a corresponding column. Out of the box, the DataGrid includes a text column, a checkbox column, and a template column. For all the types that can't be displayed, it uses the ToString method and a text column. If we want the DataGrid to feature automatic synchronization, the collection should implement the INotifyCollectionChanged interface. If changes to the objects are to be refl ected in the DataGrid, then the objects in the collection should themselves implement the INotifyPropertyChanged interface. There's more While loading large amounts of data into the DataGrid, the performance will still be very good. This is the result of the DataGrid implementing UI virtualization, which is enabled by default. Let's assume that the DataGrid is bound to a collection of 1,000,000 items (whether or not this is useful is another question). Loading all of these items into memory would be a time-consuming task as well as a big performance hit. Due to UI virtualization, the control loads only the rows it's currently displaying. (It will actually load a few more to improve the scrolling experience.) While scrolling, a small lag appears when the control is loading the new items. Since Silverlight 3, the ListBox also features UI virtualization. Inserting, updating, and deleting data in a DataGrid The DataGrid is an outstanding control to use while working with large amounts of data at the same time. Through its Excel-like interface, not only can we easily view the data, but also add new records or update and delete existing ones. In this recipe, we'll take a look at how to build a DataGrid that supports all of the above actions on a collection of items. Getting ready This recipe builds on the code that was created in the previous recipe. To follow along with this recipe, you can keep using your code or use the starter solution located in the Chapter04/Datagrid_Editing_Data_Starter folder in the code bundle available on the Packt website. The finished solution for this recipe can be found in the Chapter04/Datagrid_Editing_Data_Completed folder.
Read more
  • 0
  • 0
  • 2019

article-image-moodle-19-theme-design-customizing-header-and-footer-part-1
Packt
23 Apr 2010
7 min read
Save for later

Moodle 1.9 Theme Design: Customizing the Header and Footer (Part 1)

Packt
23 Apr 2010
7 min read
So, let's get on with it... Important preliminary points In order to continue with the exercises in the article, you will need to understand the importance of web browser compatibility. All web browsers are different, and most of them handle HTML and Cascading Style Sheets (CSS) differently. It is not so much that one web browser is better than another or that one web browser is more accurate at rendering HTML or CSS. Rather, it's that CSS rules are often interpreted differently by software developers who designed these browsers. For web developers and designers, this can be very annoying, but an unfortunate and inevitable reality. So, to make sure that the changes that you make to Moodle's theme files are the same or similar across most of the major web browsers, you will need to install various web browsers, such as Firefox, Internet Explorer, Chrome, Opera, Safari, and so on, and make sure that you remember to test your changes. You shall learn to install the required web browsers as you work through this article. Customizing the header One of the first tasks that you will be asked to do concerning Moodle theming is to customize the main Moodle header file. Most people start by learning to change the Moodle logo for one of their own. The file that you will be editing in the first part of this article is the header.html file. For this article, you will assume the standard theme that comes with Moodle. Time for action – making a copy of the standard theme In this exercise, you will be making a copy of the standard theme so that you can make changes to it without interfering with Moodle's theming process. You need to do this because many of the Moodle themes use the standard theme as the base theme. Navigate to the folder: C:Program FilesApache Software FoundationApache 2.2htdocstheme. Right-click on the standard theme folder and choose Copy, as seen in the following screenshot: Right-click again in some empty space and choose Paste. The copied standard theme will be replicated and have the name Copy of standard, as seen below: Right-click on this folder and choose Rename to rename the folder to mytheme. What just happened? You have just made a copy of the standard theme that comes with Moodle and have relocated and renamed the theme, so you can now make some basic changes without interfering with any other themes in the theme directory. Most themes use the standard theme as the parent theme and then build upon this styled theme. So, if you were to change this theme directly, you would probably mess up most of the themes that are installed in your Moodle site. Adding your own logo Now that you have made a copy of the standard theme, you will go on and replace the Moodle logo with your own. Most oft en, your organization will have a logo that you can use; perhaps you could just copy one from their website. An important point to note here is that the logo that you use should be in the GIF or .png format. The following figure has been created with Adobe Photoshop to demonstrate that it would be best to create a very basic logo if you don't have one. Time for action – copying your logo to your mytheme directory Navigate to the location of your logo. Right-click and choose Copy. Navigate to your Moodle site's thememythemepix directory, right-click, and choose Paste. The result should resemble the following screenshot: What just happened? In this very simple exercise, you have copied the logo that you had or created and placed it in the correct directory in your new mytheme directory. This is now ready for you to use in the header.html file to display your logo. Now you will edit the main header.html file to include your new logo. The header.html file can be found in your site's thememytheme directory. Time for action – adding the logo code to your header.html file Navigate to your mytheme directory, right-click on the header.html file, and choose Open With | WordPad. Open the header.html file with your favorite text editor (WordPad, Notepad, Vim, and so on). As a Windows shortcut, you can right-click on the header.html file and choose Open With | WordPad, as seen below: Top Tip – Text editorsWe have chosen WordPad here as it retains the original markup format. Notepad, on the other hand, can be difficult to use, as it lacks some of the functionalities of WordPad. If you already use another text or HTML editor, then please use it. It's about familiarity here, so it's always best to use that with which you feel comfortable. Find the following lines of code: <?php print_container_start(true, '', 'header-home'); ?> <h1 class="headermain"><?php echo $heading ?></h1> <div class="headermenu"><?php echo $menu ?></div><?php print_container_end(); ?> Insert the following line of code: <img src="<?php echo $CFG->themewww .'/'. current_theme() ?>/pix/logo.gif" alt="Institutions Logo" /> Immediately after: <h1 class="headermain"> As shown here: <?php print_container_start(true, '', 'header-home'); ?> <h1 class="headermain"> <img src="<?php echo $CFG->themewww .'/'. current_theme() ?>/pix/logo.gif" alt="Institutions Logo" /> <?php echo $heading ?></h1> <div class="headermenu"><?php echo $menu ?></div><?php print_container_end(); ?> You can download this code from the Packt website. Save and close header.html. Open your web browser and type in the URL of your local Moodle site. Change the current theme, which should be Autumn, to your theme by navigating to Appearance | Themes | Theme Selector and choosing mytheme. You should see something similar to the following screenshot but with your own logo. What just happened? In this exercise, we have learned where a theme's header.html file is and how to open the header.html file for editing. We also learned what part of the code we should change in order to have our own logo appear on the front page of out Moodle site. Have a go hero – adding another logo Again, it's time for you to have a go yourself at changing and modifying some of the things that you have learned through this article. First, it would be a good idea if you would try to create a new logo and add it to the header.html file in your mytheme folder. This time leave the inner page header as it is. Top Tip – Two headersDuring this exercise, you may have noticed that the header.html file has two instances of the following line of code: <h1 class="headermain">. This is because Moodle loads a slightly different header depending on whether you are on the front page or any other page within the site. This means that the changes we have made will only be visible on the front page and not on any other page at the moment. Why don't you go and check this by opening your local Moodle site and clicking on the Logout link in the top right-hand corner and then clicking the Login link in the same place? This will take you to the login front page of Moodle and you will notice that your logo isn't where it is supposed to be. In most situations, we would want to have our logo on all pages within our Moodle site, so we will have to replicate the last exercise and paste our logo code in the other instance of <h1 class="headermain">.
Read more
  • 0
  • 0
  • 1499

article-image-moodle-19-theme-design-customizing-header-and-footer-part-2
Packt
23 Apr 2010
6 min read
Save for later

Moodle 1.9 Theme Design: Customizing the Header and Footer (Part 2)

Packt
23 Apr 2010
6 min read
Customizing the footer Obviously, the second thing that we are going to do after we have made changes to our Moodle header file is to carry on and change the footer.html file. The following tasks will be slightly easier than changing the header logo and title text within our Moodle site, as there is much less code and subsequently much less to change. Removing the Moodle logo The first thing that we will notice about the footer in Moodle is that it has the Moodle logo on the front page of your Moodle site and a Home button on all other pages. In addition to this, there is the login info text that shows who is logged in and a link to log out. More often than not Moodle themers will want to remove the Moodle logo so that they can give their Moodle site its own branding. So let's get stuck in with the next exercise, but don't forget that this logo credits the Moodle community. Time for action – deleting the Moodle logo Navigate to your mytheme directory and right-click on the footer.html file and choose Open With | WordPad. Find the following two lines of code: echo $loggedinas;echo $homelink; Comment out the second line using a PHP comment: echo $loggedinas;/*echo $homelink; */ Save the footer.html file and refresh your browser window. You should now see the footer without the Moodle logo. What just happened? In this exercise, we learned which parts of the PHP code in the footer.html file control where the Moodle logo appears in the Moodle footer. We also learned how to comment out the PHP code that controls the rendering of the Moodle logo so that it does not appear. You could try to put the Moodle logo back if you want. Removing the login info text and link Now that we have removed the Moodle logo, which of course is completely up to you, you might also want to remove the login info link. This link is used exactly like the one in the top right-hand corner of your Moodle site, insofar as it acts as a place where you can log in and log out and provide details of who you logged in as. The only thing to consider here is that if you decide to remove the login info link from the header.html file and also remove it from the footer, you will have no easy way of logging in or out of Moodle. So it is always wise to leave it either in the header or the footer. You might also consider the advantages of having this here as some Moodle pages such as large courses are very long. So, once the user has scrolled way down the page, he/she has a place to log out if needed. The following task is very simple and will require you to go through similar steps as the"deleting the logo" exercise. The only difference is that you will comment out a different line of code. Time for action – deleting the login info text Navigate to your mytheme directory and right-click on the footer.html file and choose Open With | WordPad (or an editor of your choice). Find the following two lines of code: echo $loggedinas;echo $homelink; Comment out the first line by using a PHP comment as shown below: /* echo $loggedinas; */ echo $homelink; Save the footer.html file and refresh your browser window. You will see the footer without the Moodle logo or the login info link. What just happened? In this task, we learned about those parts of the PHP code in the footer.html that control whether the Moodle login info text appears in the Moodle footer similar to the Moodle logo in the previous exercise. We also learned how to comment out the code that controls the rendering of the login info text so that it does not appear. Have a go hero – adding your own copyright or footer text The next thing that we are going to do in this article is to add some custom footer text where the Moodle logo and the login info text were before we removed them. It's completely up to you what to add in the next exercises. If you would like to just add some text to the footer then please do. However, as part of the following tasks we are going to add some copyright text and format it using some very basic HTML. Time for action – adding your own footer text Navigate to your mytheme directory and right-click on the footer.html file and choose Open With | WordPad. At the very top of the file, paste the following text or choose your own footer text to include: My School © 2009/10 All rights reserved. Save the footer.html and refresh your browser. You will see that your footer text is at the bottom of the page on the right-hand side. However, this text is aligned to the left as all text in a browser would be. Open the footer.html file again (if it isn't open already) and wrap the following code around the footer text that you have just added: <div align="right">My School &copy; 2009/10 All rights reserved</div> Save your footer.html file and refresh your browser. You will see that the text is now aligned to the right. What just happened? We just added some very basic footer text to our footer.html file, saved it, and viewed it in our web browser. We have demonstrated here that it is very easy to add our own text to the footer.html file. We have also added some basic HTML formatting to move the text from the left to the right-hand side of the footer. There are other ways to do so, which involve the use of CSS. For instance, we could have given the <div> tag a CSS class and used a CSS selector to align the text to the right. Have a go hero – adding your own footer logo Now try to see if you can edit the footer.html and add the same logo as you have in the header.html in to the footer. Remember that you can put the logo code anywhere outside of a PHP code block. So try to copy the header logo code and paste it into the footer.html. Finally, based on what we have learned, try to align the logo to the right as we did with the footer text.
Read more
  • 0
  • 0
  • 2563
article-image-tracking-sql-queries-request-using-django
Packt
22 Apr 2010
13 min read
Save for later

Tracking SQL Queries for a Request using Django

Packt
22 Apr 2010
13 min read
For a typical Django application, database interactions are of key importance. Ensuring that the database queries being made are correct helps to ensure that the application results are correct. Further, ensuring that the database queries produced for the application are efficient helps to make sure that the application will be able to support the desired number of concurrent users. Django provides support in this area by making the database query history available for examination. This type of access is useful to see the SQL that is issued as a result of calling a particular model method. However, it is not helpful in learning about the bigger picture of what SQL queries are made during the processing of a particular request. This section will show how to include information about the SQL queries needed for production of a page in the page itself. We will alter our existing survey application templates to include query information, and examine the query history for some of the existing survey application views. Though we are not aware of any problems with the existing views, we may learn something in the process of verifying that they issue the queries we expect. Settings for accessing query history in templates Before the query history can be accessed from a template, we need to ensure some required settings are configured properly. Three settings are needed in order for the SQL query information to be available in a template. First, the debug context processor, django.core.context_processors.debug, must be included in the TEMPLATE_CONTEXT_PROCESSORS setting. This context processor is included in the default value for TEMPLATE_CONTEXT_PROCESSORS. We have not changed that setting; therefore we do not need to do anything to enable this context processor in our project. Second, the IP address of the machine sending the request must be listed in the INTERNAL_IPS setting. This is not a setting we have used before, and it is empty by default, so we will need to add it to the settings file. When testing using the same machine as where the development server runs, setting INTERNAL_IPS to include the loopback address is sufficient: # Addresses for internal machines that can see potentially sensitive # information such as the query history for a request. INTERNAL_IPS = ('127.0.0.1', ) If you also test from other machines, you will need to include their IP addresses in this setting as well. Third and finally, DEBUG must be True in order for the SQL query history to be available in templates. When those three settings conditions are met, the SQL query history may be available in templates via a template variable named sql_queries. This variable contains a list of dictionaries. Each dictionary contains two keys: sql and time. The value for sql is the SQL query itself, and the value for time is the number of seconds the query took to execute. Note that the sql_queries context variable is set by the debug context processor. Context processors are only called during template rendering when a RequestContext is used to render the template. Up until now, we have not used RequestContexts in our survey application views, since they were not necessary for the code so far. But in order to access the query history from the template, we will need to start using RequestContexts. Therefore, in addition to modifying the templates, we will need to change the view code slightly in order to include query history in the generated pages for the survey application. SQL queries for the home page Let's start by seeing what queries are issued in order to generate the survey application home page. Recall that the home page view code is: def home(request): today = datetime.date.today() active = Survey.objects.active() completed = Survey.objects.completed().filter(closes__gte=today- datetime.timedelta(14)) upcoming = Survey.objects.upcoming().filter( opens__lte=today+datetime.timedelta(7)) return render_to_response('survey/home.html', {'active_surveys': active, 'completed_surveys': completed, 'upcoming_surveys': upcoming, }) There are three QuerySets rendered in the template, so we would expect to see that this view generates three SQL queries. In order to check that, we must first change the view to use a RequestContext: from django.template import RequestContext def home(request): today = datetime.date.today() active = Survey.objects.active() completed = Survey.objects.completed().filter(closes__gte=today- datetime.timedelta(14)) upcoming = Survey.objects.upcoming().filter( opens__lte=today+datetime.timedelta(7)) return render_to_response('survey/home.html', {'active_surveys': active, 'completed_surveys': completed, 'upcoming_surveys': upcoming,}, RequestContext(request)) The only change here is to add the RequestContext(request) as a third parameter to render_to_response, after adding an import for it earlier in the file. When we make this change, we may as well also change the render_to_response lines for the other views to use RequestContexts as well. That way when we get to the point of examining the SQL queries for each, we will not get tripped up by having forgotten to make this small change. Second, we'll need to display the information from sql_queries somewhere in our survey/home.html template. But where? We don't necessarily want this information displayed in the browser along with the genuine application data, since that could get confusing. One way to include it in the response but not have it be automatically visible on the browser page is to put it in an HTML comment. Then the browser will not display it on the page, but it can be seen by viewing the HTML source for the displayed page. As a first attempt at implementing this, we might change the top of survey/home.html to look like this: {% extends "survey/base.html" %} {% block content %} <!-- {{ sql_queries|length }} queries {% for qdict in sql_queries %} {{ qdict.sql }} ({{ qdict.time }} seconds) {% endfor %} --> This template code prints out the contents of sql_queries within an HTML comment at the very beginning of the content block supplied by survey/home. html. First, the number of queries is noted by filtering the list through the length filter. Then the code iterates through each dictionary in the sql_queries list and displays sql, followed by a note in parentheses about the time taken for each query. How well does that work? If we try it out by retrieving the survey home page (after ensuring the development server is running), and use the browser's menu item for viewing the HTML source for the page, we might see that the comment block contains something like: <!-- 1 queries SELECT `django_session`.`session_key`, `django_session`.`session_data`, `django_session`.`expire_date` FROM `django_session` WHERE (`django_ session`.`session_key` = d538f13c423c2fe1e7f8d8147b0f6887 AND `django_ session`.`expire_date` &gt; 2009-10-24 17:24:49 ) (0.001 seconds) --> Note that the exact number of queries displayed here will depend on the version of Django you are running. This result is from Django 1.1.1; later versions of Django may not show any queries displayed here. Furthermore, the history of the browser's interaction with the site will affect the queries issued. This result is from a browser that had been used to access the admin application, and the last interaction with the admin application was to log out. You may see additional queries if the browser had been used to access the admin application but the user had not logged out. Finally, the database in use can also affect the specific queries issued and their exact formatting. This result is from a MySQL database. That's not exactly what we expected. First, a minor annoyance, but 1 queries is wrong, it should be 1 query. Perhaps that wouldn't annoy you, particularly just in internal or debug information, but it would annoy me. I would change the template code that displays the query count to use correct pluralization: {% with sql_queries|length as qcount %} {{ qcount }} quer{{ qcount|pluralize:"y,ies" }} {% endwith %} Here, since the template needs to use the length result multiple times, it is first cached in the qcount variable by using a {% with %} block. Then it is displayed, and it is used as the variable input to the pluralize filter that will put the correct letters on the end of quer depending on the qcount value. Now the comment block will show 0 queries, 1 query, 2 queries, and so on. With that minor annoyance out of the way, we can concentrate on the next, larger, issue, which is that the displayed query is not a query we were expecting. Furthermore, the three queries we were expecting, to retrieve the lists of completed, active, and upcoming surveys, are nowhere to be seen. What's going on? We'll take each of these in turn. The query that is shown is accessing the django_session table. This table is used by the django.contrib.sessions application. Even though the survey application does not use this application, it is listed in our INSTALLED_APPS, since it is included in the settings.py file that startproject generates. Also, the middleware that the sessions application uses is listed in MIDDLEWARE_CLASSES. The sessions application stores the session identifier in a cookie, named sessionid by default, that is sent to the browser as soon as any application uses a session. The browser will return the cookie in all requests to the same server. If the cookie is present in a request, the session middleware will use it to retrieve the session data. This is the query we see previously listed: the session middleware is retrieving the data for the session identified by the session cookie sent by the browser. But the survey application does not use sessions, so how did the browser get a session cookie in the first place? The answer is that the admin application uses sessions, and this browser had previously been used to access the admin application. At that time, the sessionid cookie was set in a response, and the browser faithfully returns it on all subsequent requests. Thus, it seems likely that this django_session table query is due to a sessionid cookie set as a side-effect of using the admin application. Can we confirm that? If we find and delete the cookie from the browser and reload the page, we should see that this SQL query is no longer listed. Without the cookie in the request, whatever code was triggering access to the session data won't have anything to look up. And since the survey application does not use sessions, none of its responses should include a new session cookie, which would cause subsequent requests to include a session lookup. Is this reasoning correct? If we try it, we will see that the comment block changes to: <!-- 0 queries --> Thus, we seem to have confirmed, to some extent, what happened to cause a django_session table query during processing of a survey application response. We did not track down what exact code accessed the session identified by the cookie—it could have been middleware or a context processor, but we probably don't need to know the details. It's enough to keep in mind that there are other applications running in our project besides the one we are working on, and they may cause database interactions independent of our own code. If we observe behavior which looks like it might cause a problem for our code, we can investigate further, but for this particular case we will just avoid using the admin application for now, as we would like to focus attention on the queries our own code is generating. Now that we understand the query that was listed, what about the expected ones that were not listed? The missing queries are due to a combination of the lazy evaluation property of QuerySets and the exact placement of the comment block that lists the contents of sql_queries. We put the comment block at the top of the content block in the home page, to make it easy to find the SQL query information when looking at the page source. The template is rendered after the three QuerySets are created by the view, so it might seem that the comment placed at the top should show the SQL queries for the three QuerySets. However, QuerySets are lazy; simply creating a QuerySet does not immediately cause interaction with the database. Rather, sending the SQL to the database is delayed until the QuerySet results are actually accessed. For the survey home page, that does not happen until the parts of the template that loop through each QuerySet are rendered. Those parts are all below where we placed the sql_queries information, so the corresponding SQL queries had not yet been issued. The fix for this is to move the placement of the comment block to the very bottom of the content block. When we do that we should also fix two other issues with the query display. First, notice that the query displayed above has &gt; shown instead of the > symbol that would actually have been in the query sent to the database. Furthermore, if the database in use is one (such as PostgreSQL) that uses straight quotes instead of back quotes for quoting, all of the back quotes in the query would be shown as &quot;. This is due to Django's automatic escaping of HTML markup characters. This is unnecessary and hard to read in our HTML comment, so we can suppress it by sending the sql query value through the safe filter. Second, the query is very long. In order to avoid needing to scroll to the right in order to see the entire query, we can also filter the sql value through wordwrap to introduce some line breaks and make the output more readable. To make these changes, remove the added comment block from the top of the content block in the survey/home.html template and instead change the bottom of this template to be: {% endif %} <!-- {% with sql_queries|length as qcount %} {{ qcount }} quer{{ qcount|pluralize:"y,ies" }} {% endwith %} {% for qdict in sql_queries %} {{ qdict.sql|safe|wordwrap:60 }} ({{ qdict.time }} seconds) {% endfor %} --> {% endblock content %} Now, if we again reload the survey home page and view the source for the returned page, we will see the queries listed in a comment at the bottom: <!-- 3 queries SELECT `survey_survey`.`id`, `survey_survey`.`title`, `survey_survey`.`opens`, `survey_survey`.`closes` FROM `survey_survey` WHERE (`survey_survey`.`opens` <= 2009-10-25 AND `survey_survey`.`closes` >= 2009-10-25 ) (0.000 seconds) SELECT `survey_survey`.`id`, `survey_survey`.`title`, `survey_survey`.`opens`, `survey_survey`.`closes` FROM `survey_survey` WHERE (`survey_survey`.`closes` < 2009-10-25 AND `survey_survey`.`closes` >= 2009-10-11 ) (0.000 seconds) SELECT `survey_survey`.`id`, `survey_survey`.`title`, `survey_survey`.`opens`, `survey_survey`.`closes` FROM `survey_survey` WHERE (`survey_survey`.`opens` > 2009-10-25 AND `survey_survey`.`opens` <= 2009-11-01 ) (0.000 seconds) --> That is good, those look like exactly what we expect to see for queries for the home page. Now that we seem to have some working template code to show queries, we will consider packaging up this snippet so that it can easily be reused elsewhere.
Read more
  • 0
  • 0
  • 3895

article-image-django-debug-toolbar
Packt
20 Apr 2010
9 min read
Save for later

The Django Debug Toolbar

Packt
20 Apr 2010
9 min read
The debug toolbar has a far more advanced way of displaying the information than simply embedding it in HTML comments. The capabilities are best shown by example, so we will immediately proceed with installing the toolbar. Installing the Django Debug Toolbar The toolbar can be found on the Python package index site: https://pypi.python.org/pypi/django-debug-toolbar. Once installed, activating the debug toolbar in a Django project is accomplished with the addition of just a couple of settings. First, the debug toolbar middleware, debug_toolbar.middleware.DebugToolbarMiddleware, must be added to the MIDDLEWARE_CLASSES setting. The documentation for the toolbar notes that it should be placed after any other middleware that encodes the response content, so it is best to place it last in the middleware sequence. Second, the debug_toolbar application needs to be added to INSTALLED_APPS. The debug_toolbar application uses Django templates to render its information, thus it needs to be listed in INSTALLED_APPS so that its templates will be found by the application template loader. Third, the debug toolbar requires that the requesting IP address be listed in INTERNAL_IPS. Finally, the debug toolbar is displayed only when DEBUG is True. We've been running with debug turned on, so again we don't have to make any changes here. Note also that the debug toolbar allows you to customize under what conditions the debug toolbar is displayed. It's possible, then, to set things up so that the toolbar will be displayed for requesting IP addresses not in INTERNAL_IPS or when debug is not turned on, but for our purposes the default configuration is fine so we will not change anything. One thing that is not required is for the application itself to use a RequestContext in order for things such as the SQL query information to be available in the toolbar. The debug toolbar runs as middleware, and thus is not dependent on the application using a RequestContext in order for it to generate its information. Thus, the changes made to the survey views to specify RequestContexts on render_to_response calls would not have been needed if we started off first with the Django Debug Toolbar. Debug toolbar appearance Once the debug toolbar is added to the middleware and installed applications settings, we can see what it looks like by simply visiting any page in the survey application. Let's start with the home page. The returned page should now look something like this: Note this screenshot shows the appearance of the 0.8.0 version of the debug toolbar. Earlier versions looked considerably different, so if your results do not look like this you may be using a different version than 0.8.0. The version that you have will most likely be newer than what was available when this was written, and there may be additional toolbar panels or functions that are not covered here. As you can see, the debug toolbar appears on the right-hand side of the browser window. It consists of a series of panels that can be individually enabled or disabled by changing the toolbar configuration. The ones shown here are the ones that are enabled by default. Before taking a closer look at some of the individual panels, notice that the toolbar contains an option to hide it at the top. If Hide is selected, the toolbar reduces itself to a small tab-like indication to show that it is present: This can be very useful for cases where the expanded version of the toolbar obscures application content on the page. All of the information provided by the toolbar is still accessible, after clicking again on the DjDT tab; it is just out of the way for the moment. Most of the panels will provide detailed information when they are clicked. A few also provide summary information in the main toolbar display. As of debug toolbar version 0.8.0, the first panel listed, Django Version, only provides summary information. There is no more detailed information available by clicking on it. As you can see in the screenshot, Django 1.1.1 is the version in use here. Note that the current latest source version of the debug toolbar already provides more information for this panel than the 0.8.0 release. Since 0.8.0, this panel has been renamed to Versions, and can be clicked to provide more details. These additional details include version information for the toolbar itself and for any other installed Django applications that provide version information. The other three panels that show summary information are the Time, SQL, and Logging panels. Thus, we can see at a glance from the first appearance of the page that 60 milliseconds of CPU time were used to produce this page (111 milliseconds total elapsed time), that the page required four queries, which took 1.95 milliseconds, and that zero messages were logged during the request. In the following sections, we will dig into exactly what information is provided by each of the panels when clicked. We'll start first with the SQL panel, since it is one of the most interesting and provides the same information (in addition to a lot more). The SQL panel If we click on the SQL section of the debug toolbar, the page will change to: At a glance, this is a much nicer display of the SQL queries for the page than what we came up with earlier. The queries themselves are highlighted so that SQL keywords stand out, making them easier to read. Also, since they are not embedded inside an HTML comment, their content does not need to be altered in any way—there was no need to change the content of the query containing the double dash in order to avoid it causing display problems. (Now would probably be a good time to remove that added query, before we forget why we added it.) Notice also that the times listed for each query are more specific than what was available in Django's default query history. The debug toolbar replaces Django's query recording with its own, and provides timings in units of milliseconds instead of seconds. The display also includes a graphical representation of how long each query took, in the form of horizontal bars that appear above each query. This representation makes it easy to see when there are one or more queries that are much more expensive than the others. In fact, if a query takes an excessive amount of time, its bar will be colored red. In this case, there is not a great deal of difference in the query times, and none took particularly long, so all the bars are of similar length, and are colored gray. Digging deeper, some of the information we had to manually figure out earlier in this article is just a click away on this SQL query display. Specifically, the answer to the question of what line of our code triggered a particular SQL query to be issued. Each of the displayed queries has a Toggle Stacktrace option, which when clicked will show the stack trace associated with the query: Here we can see that all queries are made by the home method in the survey views. py file. Note that the toolbar filters out levels in the stack trace that are within Django itself, which explains why each of these has only one level shown. The first query is triggered by Line 61, which contains the filter call added to test what will happen if a query containing two dashes in a row was logged. The remaining queries are all attributed to Line 66, which is the last line of the render_to_response call in the home view. These queries, as we figured out earlier, are all made during the rendering of the template. (Your line numbers may vary from those shown here, depending on where in the file various functions were placed.) Finally, this SQL query display makes available information that we had not even gotten around to wanting yet. Under the Action column are links to SELECT, EXPLAIN, and PROFILE each query. Clicking on the SELECT link shows what the database returns when the query is actually executed. For example: Similarly, clicking on EXPLAIN and PROFILE displays what the database reports when asked to explain or profile the selected query, respectively. The exact display, and how to interpret the results, will differ from database to database. (In fact, the PROFILE option is not available with all databases—it happens to be supported by the database in use here, MySQL.) Interpreting the results from EXPLAIN and PROFILE is beyond the scope of what's covered here, but it is useful to know that if you ever need to dig deep into the performance characteristics of a query, the debug toolbar makes it easy to do so. We've now gotten a couple of pages deep into the SQL query display. How do we get back to the actual application page? Clicking on the circled >> at the upper-right of the main page display will return to the previous SQL query page, and the circled >> will turn into a circled X. Clicking the circled X on any panel detail page closes the details and returns to displaying the application data. Alternatively, clicking again on the panel area on the toolbar for the currently displayed panel will have the same effect as clicking on the circled symbol in the display area. Finally, if you prefer using the keyboard to the mouse, pressing Esc has the same effect as clicking the circled symbol. Now that we have completely explored the SQL panel, let's take a brief look at each of the other panels provided by the debug toolbar. The Time panel Clicking on the Time panel brings up more detailed information on where time was spent during production of the page: The total CPU time is split between user and system time, the total elapsed (wall clock) time is listed, and the number of voluntary and involuntary context switches are displayed. For a page that is taking too long to generate, these additional details about where the time is being spent can help point towards a cause. Note that the detailed information provided by this panel comes from the Python resource module. This is a Unix-specific Python module that is not available on non-Unix-type systems. Thus on Windows, for example, the debug toolbar time panel will only show summary information, and no further details will be available.
Read more
  • 0
  • 0
  • 3987

article-image-handling-invalid-survey-submissions-django
Packt
20 Apr 2010
5 min read
Save for later

Handling Invalid Survey Submissions with Django

Packt
20 Apr 2010
5 min read
What would make a survey submission invalid? The only likely error case for our QuestionVoteForm is if no answer is chosen. What happens, then, if we attempt to submit a survey with missing answers? If we try it, we see that the result is not ideal: There are at least two problems here. First, the placement of the error messages, above the survey questions, is confusing. It is hard to know what the first error message on the page is referring to, and the second error looks like it is associated with the first question. It would be better to move the error messages closer to where the selection is actually made, such as between the question and answer choice list. Second, the text of the error message is not very good for this particular form. Technically the list of answer choices is a single form field, but to a general user the word field in reference to a list of choices sounds odd. We will correct both of these errors next. Coding custom error message and placement Changing the error message is easy, since Django provides a hook for this. To override the value of the error message issued when a required field is not supplied, we can specify the message we would like as the value for the required key in an error_messages dictionary we pass as an argument in the field declaration. Thus, this new definition for the answer field in QuestionVoteForm will change the error message to Please select an answer below: class QuestionVoteForm(forms.Form): answer = forms.ModelChoiceField(widget=forms.RadioSelect, queryset=None, empty_label=None, error_messages={'required': 'Please select an answer below:'}) Changing the placement of the error message requires changing the template. Instead of using the as_p convenience method, we will try displaying the label for the answer field, errors for the answer field, and then the answer field itself, which displays the choices. The {% for %} block that displays the survey forms in the survey/active_survey.html template then becomes: {% for qform in qforms %} {{ qform.answer.label }} {{ qform.answer.errors }} {{ qform.answer }}{% endfor %} How does that work? Better than before. If we try submitting invalid forms now, we see: While the error message itself is improved, and the placement is better, the exact form of the display is not ideal. By default, the errors are shown as an HTML unordered list. We could use CSS styling to remove the bullet that is appearing (as we will eventually do for the list of choices), but Django also provides an easy way to implement custom error display, so we could try that instead. To override the error message display, we can specify an alternate error_class attribute for QuestionVoteForm, and in that class, implement a __unicode__ method that returns the error messages with our desired formatting. An initial implementation of this change to QuestionVoteForm and the new class might be: class QuestionVoteForm(forms.Form): answer = forms.ModelChoiceField(widget=forms.RadioSelect, queryset=None, empty_label=None, error_messages={'required': 'Please select an answer below:'}) def __init__(self, question, *args, **kwargs): super(QuestionVoteForm, self).__init__(*args, **kwargs) self.fields['answer'].queryset = question.answer_set.all() self.fields['answer'].label = question.question self.error_class = PlainErrorListfrom django.forms.util import ErrorListclass PlainErrorList(ErrorList): def __unicode__(self): return u'%s' % ' '.join([e for e in sefl]) The only change to QuestionVoteForm is the addition of setting its error_class attribute to PlainErrorList in its __init__ method. The PlainErrorList class is based on the django.form.util.ErrorList class and simply overrides the __unicode__ method to return the errors as a string with no special HTML formatting. The implementation here makes use of the fact that the base ErrorList class inherits from list, so iterating over the instance itself returns the individual errors in turn. These are then joined together with spaces in between, and the whole string is returned. Note that we're only expecting there to ever be one error here, but just in case we are wrong in that assumption, it is safest to code for multiple errors existing. Although our assumption may never be wrong in this case, it's possible we might decide to re-use this custom error class in other situations where the single possible error expectation doesn't hold. If we code to our assumption and simply return the first error in the list, this may result in confusing error displays in some situations where there are multiple errors, since we will have prevented reporting all but the first error. If and when we get to that point, we may also find that formatting a list of errors with just spaces intervening is not a good presentation, but we can deal with that later. First, we'd like to simply verify that our customization of the error list display is used.
Read more
  • 0
  • 0
  • 1848
article-image-customizing-kubrik-wordpress
Packt
19 Apr 2010
5 min read
Save for later

Customizing Kubrik with Wordpress

Packt
19 Apr 2010
5 min read
Getting ready The first step is to make a list of the changes that you want to make. Here's what we've come up with: Increase width to 980px Increase font sizes in sidebar Use a graphic header We've picked 980px as our target width because this size is optimized for a 1024 screen resolution and works well in a grid layout. Several CSS adjustments will be necessary to realize this modification, as well as using an image editing program (we will be using Photoshop). How to do it... To increase the page width, the first step is to determine which entries in the CSS stylesheet are controlling the width. Using Firebug to inspect the page (as seen below), we find that the selector #page has a value of 760px for the width property. And #header has a width of 758px (less because there is a 1px left margin). The .narrowcolumn selector gives the main content column a width of 450px. And #sidebar has a width of 190px. Finally, #footer has a width of 760px. So, we will increase #page and #footer to 980px. #header we will increase to 978px. Let's apply all of the additional 220px width to .narrowcolumn. Taking note of the existing 45px left margin, our new value for the width property will be 700px. That means #sidebar width will remain at 190px, but the margin-left will need to be increased from 545px to 765px. Click on Appearance | Editor. In the right-hand column, below the Templates heading, click on style.css. Scroll past the section that says /* Begin Typography & Colors */, until you get to the section that says /* Begin Structure */. Make the following changes to the stylesheet (style.css), commenting as appropriate to document your changes. #page { background-color: white; margin: 20px auto; padding: 0; width: 980px; /* increased from 760px */ border: 1px solid #959596; }#header { background-color: #73a0c5; margin: 0 0 0 1px; padding: 0; height: 200px; width: 978px; /* increased from 758px */ }.narrowcolumn { float: left; padding: 0 0 20px 45px; margin: 0px 0 0; width: 700px; /* increased from 450px */ }#sidebar {margin-left:765px; /* increaseed from 545px */padding:20px 0 10px;width:190px;}#footer { padding: 0; margin: 0 auto; width: 980px; /* increased from 760px */ clear: both; } Adjustments via Photoshop We'll also need to use an image editing program to modify the three background images that create the rounded corners: kubrikbg-ltr.jpg, kubrickheader.jpg, and kubrickfooter.jpg. In this example, we modify kubrik-ltr.jpg (the background image for #page), a 760px image. Open up the image in Photoshop, select all, copy, create a new document (with a white or transparent background), and paste (Ctrl-A, Ctrl-C, Ctrl-N, Ctrl-V). Increase the canvas size (Image | Canvas Size) to 980px, keeping the image centered on the left-hand side by clicking on the left-pointing arrow. Select one half of the image with the Rectangular Marquee Tool, cut and paste. Use the Move Tool to drag the new layer to the right-hand side of the canvas. In this case, it does not matter if you can see the transparent background or if your selection was exactly one half the image. Since the middle of the image is simply a white background, we are really only concerned with the borders on the left and right. The following screenshot shows the background image cut in half and moved over: Save for Web and Devices, exporting as a jpg. Then, replace the existing kubrikbgltr.jpg with your modified version via FTP. The steps are similar for both kubrickheader.jpg and kubrickfooter.jpg. Increase the canvas size and copy/paste from the existing image to increase the image size without stretching or distortion. The only difference is that you need to copy and paste different parts of the image in order to preserve the background gradient and/or top and bottom borders. In order to complete our theme customization, the width of .widecolumn will need to be increased from 450px to 700px (and the 150px margin should be converted to a 45px margin, the same as .narrowcolumn). Also, the kubrikwide.jpg background image will need to be modified with an image editing program to increase the size from 760px to 980px. Then, the individual post view will look as good as the homepage. By following the same steps as above, you should now be prepared to make this final customization yourself. Our next goal is to increase the sizes of the sidebar fonts. Firebug helps us to pinpoint the relevant CSS. #sidebar h2 has a font-size of 1.2em (around line 123 of style.css). Let's change this to 1.75em. #sidebar has font-size of 1em. Let's increase this to 1.25em. To use a graphic in the header, open up kubrickheader.jpg in a new Photoshop document. Use the magic wand tool to select and delete the blue gradient with rounded corners. Now, use the rounded rectangle tool to insert your own custom header area. You can apply another gradient, if desired. We choose to apply a bevel and emboss texture to our grey rectangle. Then, to paste in some photos, decreasing their opacity to 50%. In a short time, we've been able to modify Kubrik by re-writing CSS and using an image-editing program. This is the most basic technique for theme modification. Here is the result:
Read more
  • 0
  • 0
  • 991

article-image-video-blogging-wordpress
Packt
16 Apr 2010
7 min read
Save for later

Video Blogging in Wordpress

Packt
16 Apr 2010
7 min read
Introduction Video is a major component of the Web today. Luckily, WordPress makes it easy to publish and share video. In this article, we will demonstrate ways of working with video in WordPress and in Flash. You will learn how to embed an .flv file, create an .xml video sitemap, and distribute your videos to sites such as YouTube and Blip. We will also show you how to set up Free WP Tube, a free video blogging theme that allows you to run a video web log (vlog). FLV Embed (Version 1.2.1) If you want to embed .flv files, use a Flash video player, and/or publish a video sitemap, this compact plugin does all three. The homepage is http://www.channel-ai.com/blog/plugins/flv-embed/. FLV Embed uses standards compliant, valid XHTML, and JavaScript. It is based on the JW FLV Media Player, whose homepage is http://www.longtailvideo.com/players/jw-flvplayer/ FLV Embed supports Google video sitemap generation, allowing you to describe, syndicate, and distribute your video content, facilitating indexing in Google video search. If a user is missing Flash or has disabled JavaScript, he or she is provided unobtrusive and appropriate on-screen instructions to correct the problem. Getting ready When a page with video loads, the player displays either the first frame of the video or a thumbnail (referred to as a poster image). The poster image is preferable, especially when a user is choosing between many videos—the first frame of a video may not offer the most representative or compelling description. Your poster image can be a poster or any image you like. Here is an example of our finished product: You will want to think about where you will upload the video files and poster images and,how you will name them. A good place might be wp-content/uploads/video. This plugin requires that you name your poster images the same as your video files. The default image type is jpg, but you can use any valid image file format. All your images must be in the same file format. A batch resize and rename utility is a useful tool. For PC, one free option is the Fast Stone Image Resizer, which you can download at http://www.faststone.org/FSResizerDetail.htm. How to do it... In your dashboard, navigate to Plugins | Add New. Search for "FLV Embed". Click on Install, then on Activate. Visit the plugin configuration panel at Settings | FLV Embed. In the Sitemap menu, check the first box to Enable sitemap feature and automatic custom field addition. FLV Embed will now be able to create your video sitemap by automatically adding a custom field each time you use FLV Embed to insert a video. In the Poster menu, check the box to Display poster image for embedded FLV movies. For both of the fields, Path to poster directory and Path to FLV directory, we suggest you leave these blank, and instead use absolute URLs. If you do use relative (site-specific) URLs, keep in mind that a trailing slash is required. An example is /wp-content/uploads/videos/. In the Player menu, you may want to change the colors or add your site logo as a linkable watermark to the video. Review all the Settings, and click on Save Changes. To embed an FLV file, use the following shortcode in HTML view: [flv:url width height]. For example, you could insert a YouTube video at 480 by 360 (using the absolute URL) like this: [flv:http://youtube.com/watch?v=fLV3MB3DpWN 480 360] A YouTube video cannot use a poster image because the file name of a jpg cannot contain a question mark. You can also insert an FLV that you have uploaded (using the relative path) like this: [flv:http://www.wordpressandflash.com/wp-content/uploads/video/swfobject_test.swf 480 360] Once you have inserted the video, FLV Embed automatically populates the FLV custom field with two URLs, as you can see below. The first is the location of the video, and the second is the location of the poster image: To use a custom poster image, upload any image to wp-content/uploads/video, and rename it to match the filename. You can also use an absolute URL if the poster image file is in another location—the filename must still match. To configure your video XML sitemap, visit the Video Sitemap Options menu by clicking on Settings | Video Sitemap. Here, you can get or modify the feed address. Our example is http://www.wordpressandflash.com/ videofeed.xml You can also adjust additional optional settings, and if you have made any changes to the settings or content and need to rebuild the sitemap or update your custom fields, you can do that here too. How it works... The video sitemap is an extension of the XML sitemap. A video sitemap allows you to publish and syndicate online video content, including descriptive metadata to tag your content for Google Video search. Adding details, such as a title and description, makes it easier for users who are searching to find a given piece of content. Your poster image will also be included as a clickable thumbnail image. The user will be directed to your website to see the video. If FLV Embed cannot automatically generate the XML file, you can simply copy the XML file from the demo and save it to your server. Make sure to set the file permissions to write (664 or 666) by context-clicking in your FTP client and modifying the File Attributes, as seen below: Then, make the appropriate changes to the Video sitemap filename field in the Video Sitemap Options menu, directing the plugin to the XML file you have prepared, and rebuild the sitemap. Here is what your finished feed will look like: There's more... The videofeed.xml file has a simple structure. The first three tags specify encoding, styling, and the video sitemap protocol: <?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl"href="http://www.wordpressandflash.com/wp-content/plugins/flv-embed/sitemap.xsl"?><urlset > Next, a <url> tag wraps each piece of content, which includes a <loc> tag (a link to the content on your site) and a <videogt; tag. The <videogt; tag contains additional tags that specify the video location, the video player location, the poster image location, a title, and description: <url> <loc>http://www.wordpressandflash.com/flv-embed/</loc> <video:video> <video:content_loc>http://www.wordpressandflash.com/wp-content/uploads/video/swfobject_test.swf</video:content_loc> <video:player_loc allow_embed="No">http://www.wordpressandflash.com/wp-content/plugins/flv-embed/flvplayer.swf?file=/wp-content/uploads/video/swfobject_test.swf</video:player_loc> <video:thumbnail_loc>http://www.wordpressandflash.com/wp-content/uploads/videos/swfobject_test.jpg</video:thumbna il_loc> <video:title><![CDATA[FLV Embed]]></video:title> <video:description><![CDATA[FLV Embed is a great plugin thatallows you to display FLV files &#8212; and most other video formats&#8212; in a compact Flash video player. Visit the homepage at:http://www.channel-ai.com/blog/plugins/flv-embed/. Check out thevideo sitemap!Get the latest Flash Player to see this player.[Javascript required to view Flash movie, please turn it [...]]]></video:description> </video:video></url></urlset> With this info, you can manually create a .xml video feed for any site, without a plugin. Commercial use? Commercial use does require a license. A free alternative for commercial use is the Hana FLV Player, whose homepage is http://www.neox.net/w/2008/05/25/hana-flv-playerwordpress-plugin/.
Read more
  • 0
  • 0
  • 2326