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

How-To Tutorials

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

Freebies and Downloads in Drupal 6: Part 2

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

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

Freebies and Downloads in Drupal 6: Part1

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

article-image-hibernate-types
Packt
27 Nov 2009
3 min read
Save for later

Hibernate Types

Packt
27 Nov 2009
3 min read
Hibernate allows transparent persistence, which means the application is absolutely isolated from the underlying database storage format. Three players in the Hibernate scene implement this feature: Hibernate dialect, Hibernate types, and HQL. The Hibernate dialect allows us to use a range of different databases, supporting different, proprietary variants of SQL and column types. In addition, HQL allows us to query persisted objects, regardless of their relational persisted form in the database. Hibernate types are a representation of databases SQL types, provide an abstraction of the underlying database types, and prevent the application from getting involved with the actual database column types. They allow us to develop the application without worrying about the target database and the column types that the database supports. Instead, we get involved with mapping Java types to Hibernate types. The database dialect, as part of Hibernate, is responsible for transforming Java types to SQL types, based on the target database. This gives us the flexibility to change the database to one that may support different column types or SQL without changing the application code. Built-in types Hibernate includes a rich and powerful range of built-in types. These types satisfy most needs of a typical application, providing a bridge between basic Java types and common SQL types. Java types mapped with these types range from basic, simple types, such as long and int, to large and complex types, such as Blob and Clob. The following table categorizes Hibernate built-in types with corresponding Java and SQL types: Java Type Hibernate Type Name SQL Type Primitives Boolean or boolean boolean BIT true_false CHAR(1)('T'or'F') yes_no CHAR(1)('Y'or'N') Byte or byte byte TINYINT char or Character character CHAR double or Double double DOUBLE float or float float FLOAT int or Integer integer INTEGER long or Long long BIGINT short or Short short SMALLINT String java.lang.String string VARCHAR character CHAR(1) text CLOB Arbitrary Precision Numeric java.math.BigDecimal big_decimal NUMERIC Byte Array byte[] or Byte[] binary VARBINARY   Time and Date java.util.Date date DATE time TIME timestamp TIMESTAMP java.util.Calendar calendar TIMESTAMP calendar_date DATE java.sql.Date date DATE java.sql.Time time TIME java.sql.Timestamp timestamp TIMESTAMP Localization java.util.Locale locale VARCHAR java.util.TimeZone timezone java.util.Currency currency Class Names java.lang.Class class VARCHAR Any Serializable Object java.io.Serializable Serializable VARBINARY JDBC Large Objects java.sql.Blob blob BLOB java.sql.Clob clob CLOB
Read more
  • 0
  • 0
  • 3361

article-image-codeigniter-17-and-objects
Packt
27 Nov 2009
9 min read
Save for later

CodeIgniter 1.7 and Objects

Packt
27 Nov 2009
9 min read
Objects confused us, when we started using CodeIgniter. Coming to CodeIgniter through PHP 4, which is a procedural language, and not an object-oriented (OO) language. We duly looked up objects and methods, properties and inheritance, and encapsulation, but our early attempts to write CI code were plagued by the error message "Call to a member function on a non-object". We saw it so often that we were thinking of having it printed on a T-shirt. To save the world from a lot of boring T-shirts, this article covers the way in which CI uses objects, and the different ways you can write and use your own objects. Incidentally, we've used "variables/properties", and "methods/functions" interchangeably, as CI and PHP often do. You write "functions" in your controllers, for instance, when an OO purist would call them "methods". You define class "variables" when the purist would call them "properties". Object-oriented programming We assume that you have basic knowledge of OOP. You may have learned it as an afterthought to "normal" PHP 4. PHP 4 is not an OO language, though some OO functionality has been stacked on to it. PHP 5 is much better, with an underlying engine that was written from the ground up with OO in mind. You can do most of the basics in PHP 4, and CI manages to do everything it needs internally in either language. The key thing to remember—when an OO program is running, there is always one current object (but only one). Objects may call each other or hand over control to each other, in which case the current object changes, but only one of them can be current at any time. The current object defines the scope, in other words, the variables (properties) and methods (functions) that are available to the program at that moment. So it's important to know and control the current object. PHP, being a mixture of functional and OO programming, also offers the possibility where no object is current. You can start off with a functional program, call an object, let it take charge for a while, and then return control to the program. Luckily, CI takes care of this for you. The CI super-object CI works by building one super-object—it runs the entire program as one big object, in order to eliminate scoping issues. When you start CI, a complex chain of events occurs. If you set your CI installation to create a log (in /codeigniter/application/config/config.php set $config['log_threshold'] = 4; value. This will generate a log file in /www/CI_system/logs/), you'll see something like this: 1 DEBUG - 2006-10-03 08:56:39 --> Config Class Initialized2 DEBUG - 2006-10-03 08:56:39 --> No URI present. Default controllerset.3 DEBUG - 2006-10-03 08:56:39 --> Router Class Initialized4 DEBUG - 2006-10-03 08:56:39 --> Output Class Initialized5 DEBUG - 2006-10-03 08:56:39 --> Input Class Initialized6 DEBUG - 2006-10-03 08:56:39 --> Global POST and COOKIE datasanitized7 DEBUG - 2006-10-03 08:56:39 --> URI Class Initialized8 DEBUG - 2006-10-03 08:56:39 --> Language Class Initialized9 DEBUG - 2006-10-03 08:56:39 --> Loader Class Initialized10 DEBUG - 2006-10-03 08:56:39 --> Controller Class Initialized11 DEBUG - 2006-10-03 08:56:39 --> Helpers loaded: security12 DEBUG - 2006-10-03 08:56:40 --> Scripts loaded: errors13 DEBUG - 2006-10-03 08:56:40 --> Scripts loaded: boilerplate14 DEBUG - 2006-10-03 08:56:40 --> Helpers loaded: url15 DEBUG - 2006-10-03 08:56:40 --> Database Driver Class Initialized16 DEBUG - 2006-10-03 08:56:40 --> Model Class Initialized At start up, that is, each time a page request is received over the Internet—CI goes through the same procedure. You can trace the log through the CI files: The index.php file receives a page request. The URL may indicate which controller is required, if not, CI has a default controller (line 2). The index.php file makes some basic checks and calls the codeigniter.php file (codeignitercodeigniter.php). require_once BASEPATH.'codeigniter/CodeIgniter'.EXT; The codeigniter.php file instantiates the Config, Router, Input, URL, and other such, classes (see lines 1, and 3 to 9). These are called the base classes—you rarely interact directly with them, but they underlie almost everything CI does. /** ------------------------------------------------------* Instantiate the base classes* ------------------------------------------------------*/$CFG =& load_class('Config');$URI =& load_class('URI');$RTR =& load_class('Router');$OUT =& load_class('Output'); The file codeigniter.php tests to see the version of PHP it is running on, and calls Base4 or Base5 (/codeigniter/Base4.php or codeigniter/Base5.php). if (floor(phpversion()) < 5){load_class('Loader', FALSE);require(BASEPATH.'codeigniter/Base4'.EXT);}else{require(BASEPATH.'codeigniter/Base5'.EXT);} The above snippet creates an object—one which ensures that a class has only one instance. Each has a public &get_instance() function. Note the &—this is assignment by reference. So, if you assign using &get_instance() method, it assigns to the single running instance of the class. In other words, it points to the same pigeonhole. So, instead of setting up lot of new objects, you start building one super-object, which contains everything related to the framework. function &get_instance(){return CI_Base::get_instance();} A security check, /** ------------------------------------------------------* Security check* ------------------------------------------------------** None of the functions in the app controller or the* loader class can be called via the URI, nor can* controller functions that begin with an underscore*/$class = $RTR->fetch_class();$method = $RTR->fetch_method();if ( !class_exists($class)OR $method == 'controller'OR strncmp($method, '_', 1) == 0OR in_array(strtolower($method), array_map('strtolower',get_class_methods('Controller')))){show_404("{$class}/{$method}");} The file, codeigniter.php instantiates the controller that was requested, or a default controller (line 10). The new class is called $CI. $CI = new $class(); The function specified in the URL (or a default) is then called and life, as we know it, starts to wake up and happen. Depending on what you wrote in your controller, CI will initialize the classes you need, and "include" functional scripts you asked for. So, in the log, the model class is initialized (line 16). The boilerplate script, which is also shown in the log (line 13), is the one we wrote to contain standard chunks of text. It's a .php file, saved in the folder called scripts. It's not a class—just a set of functions. If you were writing pure PHP you might use include or require to bring it into the namespace—CI needs to use its own load function to bring it into the super-object. The concept of namespace or scope is crucial here. When you declare a variable, array, object, and so on, PHP holds the variable name in its memory and assigns a further block of memory to hold its contents. However, problems might arise if you define two variables with the same name. (In a complex site, this is easily done.) For this reason, PHP has several set of rules. Some of them are as listed: Each function has its own namespace or scope, and variables defined within a function are usually local to it. Outside the function, they are meaningless. You can declare global variables, which are held in a special global namespace and are available throughout the program. Objects have their own namespaces—variables exist inside the object as long as the object exists, and can only be referenced by using the object. So, $variable, global $variable, and $this->variable are three different things. Remember, $variable and global $variable can't be used in the same scope. So, inside a function you will have to decide if you want to use $variable or global $variable. Particularly before OO, this could lead to all sort of confusions—you may have too many variables in your namespace (so that conflicting names overwrite each other). You may also find that some variables are just not accessible from whatever scope you happen to be. Copying by reference You may have noticed the function &get_instance() in the previous section. This is to ensure that, as the variables change, the variables of the original class also change. As assignment by reference can be confusing, so here's a short explanation. We're all familiar with simple copying in PHP: $one = 1;$two = $one;echo $two; The previous snippet produces 1, because $two is a copy of $one. However, suppose you reassign $one: $one = 1;$two = $one;$one = 5;echo $two; This code still produces $two = 1, because changes made to $one after assigning $two have not been reflected in $two. This was a one-off assignment of the value that happened to be in variable $one at that time, to a new variable $two. Once that is done, the two variables lead separate lives (in just the same way if we alter $two, $one doesn't change). In effect, PHP creates two pigeonholes—called $one and $two. A separate value lives in each. You may, on any occasion, make the values equal, but after that each does its own work. PHP also allows copying by reference. If you add just a simple & to line 2 of the snippet as shown: $one = 1;$two =& $one;$one = 5;echo $two; The code now echoes 5, the change we made to $one is reflected in $two. Changing the = to =& in the second line means that the assignment is "by reference". It looks as if there was only one pigeonhole, which has two names ($one<.i> and $two). Whatever happens to the contents of the pigeonhole is reflected in both $one and $two, as if they were just different names for the same variables. The principle works for objects as well as simple string variables. You can copy or clone an object using the = operator in PHP 4. Or you can clone keyword in PHP, in which case you make a simple one-off new copy, which then leads an independent life. You can also assign one to the other by reference, so the two objects point to each other. Any changes made to one will also happen to the other. Again, think of them as two different names for the same thing.
Read more
  • 0
  • 0
  • 2621

article-image-device-management-zenoss-core-network-and-system-monitoring-part-1
Packt
27 Nov 2009
5 min read
Save for later

Device Management in Zenoss Core Network and System Monitoring: Part 1

Packt
27 Nov 2009
5 min read
Add Devices Though we might have, auto-discovered devices on our networks, but sometimes we don't want to add all the available devices on the network to the inventory or it may be that all our devices may not be found. To compensate for both these scenarios, Zenoss allows us to add one device at a time to the device inventory. To add a single device, select Add Device from the navigation panel. The Add Device page is divided into multiple sections for general device information, Attributes, and Relations as shown in the following screenshot. We can be as detailed as we want to be when we add the device manually. However, at a minimum, we should enter a Device Name, Device Class Path,and Discovery Protocol. The Device Name identifies the IP address or resolvable hostname, while the device class sets the monitoring properties we want our device to inherit by default. If the device is not SNMP-enabled, select None, otherwise Zenoss will not add the device.We'll continue We'll continue monitoring our Mill Race location by adding a new Linux server with the following configuration: Device Name: 192.168.1.110 Device Class: /Server/Linux Discovery Protocol: None OS Manufacturer: Ubuntu Location: /Mill Race/Second Floor System: /Development Group: /Developers/Software Testers The Add Device Options table lists the available configuration information we can set when adding a device manually Add Device Options Field Name Description IP Address Enter either an IP address or resolvable host name to identify the device. Device Class Path Select the appropriate device classifications: Ex: /Server/Linux. Discovery Protocol Choose either SNMP or None depending on whether or not you monitor the device with SNMP or not. SNMP Community Enter the community string of the device. The most common default is public.     Attributes SNMP Port The default port for SNMP communication is 161. Tag Number If the device has a tag number, such as a service tag number, enter the value. Serial Number Record the manufacturer's serial number. Production State Select the current state of the device: Ex. Production, maintenance, decommissioned. Priority Highest, high, normal, low, lowest, trivial. Rack Slot Record the physical rack location of the device. Comments Use the comments to enter device specific information, including a description, device users, or who is responsible for the device.     Relations HW Manufacturer Select a manufacturer name from the list. Ex: Cisco or Linksys. HW Product Select a product from the list. The HW Product lists gets populated based on the HW Manufacturer selection. OS Manufacturer Select a manufacturer name from the list. Ex: Microsoft or Fedora Core. OS Product Select from a product from the list. The OS Product lists gets populated based on the HW Manufacturer selection. Location Path Select the location of the device. Create a new location by typing the name in the New Location field and clicking Add. Systems Select a system organizer. Create a new system by typing the name in the New System field and clicking Add. Groups Select a group organizer. Create a new group by typing the name in the New Device Group field and clicking Add. Status Monitor Select a status monitor to define how often the device availability is monitored. The default is localhost. Create a new status monitor by typing the name in the New Status Monitor field and clicking Add. Refer to chapter 06 for configuration information. Performance Monitor Select a performance monitor to define how often device performance data is collected. The default is localhost. Create a new performance monitor by typing the name in the New Performance Monitor field. Refer to chapter 06 for configuration information. The Add Device Status page provides a hyperlink at the bottom of the page that says, "Navigate to device 192.168.1.110." If we click on the device name, the Device Status page is displayed. Device Status The Device status page displays an overview of our device and contains the same information we encountered on the Add Device page. As we look at the Device Status table for 192.168.1.110 as shown in the following screenshot, we can determine several important monitoring statistics in one glance. In our example, the device name and IP address are the same, but they do not need to be the same. If the host has multiple CNAMEs or interfaces, we can specify a name other than the name we used to find the device, via DNS resolution. We may find that we want to implement a custom naming scheme for devices. Regardless of what we name the device, Zenoss uses the IP address to monitor, not the name The Device Status table lists the number of events by severity and color code. The Device Severities table lists Zenoss's severity: Device Severities Color Severity Red Critical Orange Error Yellow Warning Blue Information Grey Debug The Device Status page also lists important statistics of the device. The Availability and Uptime values are automatically calculated, and the Production State and Priority values can be changed via the device's Edit page. We can lock the device to prevent Zenoss from removing or updating the device configuration. The Last Change, Last Collection, and the First Seen values provide a quick way to verify the modeling history of the device by listing the last time Zenoss detected a change with the device configuration and the last time the device was modeled. In the Device Status page, we also see a list of Component Types and the Status of each monitored component. As we build our monitoring solution, the components we monitor will change per device, but common components include SNMP, ipServices, Windows event logs, and syslogs If we look closely at the previous screen shot that shows the status of 192.168.1.110, we notice that the SNMP component displays an error condition. This indicates that our device does not have SNMP installed or is not configured correctly.
Read more
  • 0
  • 0
  • 4039

article-image-listening-activities-moodle-19-part-2
Packt
19 Nov 2009
6 min read
Save for later

Listening Activities in Moodle 1.9: Part 2

Packt
19 Nov 2009
6 min read
Activity 3: Investigating texts using Quiz Aim: Using quiz to investigate texts Moodle modules: Quiz Extra programs: None Ease of setup: *** As noted elsewhere, Quiz can be a useful module for practicing different language skills. This is primarily because we can build in helpful feedback and because we can allow students to spend as much time as they want practicing. There are various ways that Quiz can help students listen. Here are some examples: Listening and matching: students listen for gist information and match answers to general questions about the text. Ordering task for arranging events in a sequence. Multiple-choice for information transfer, identifying speakers' attitudes, and identifying numbers. Gap-fill tasks: Students listen to a song, poem, or other text, and fill in the missing words. It's worth thinking carefully about what sorts of words you want to blank out. Do you want to focus on grammar words (prepositions, pronouns, and conjunctions, etc.), words that are difficult to spell, or keywords (words that convey the main meaning of the text)? To exemplify each of these examples, we'll make one quiz with four different question types. You could choose to have quizzes with any number of different question types. We'll take as our listening text a story which we recorded ourselves. We could record it in a recording program like Audacity. The story is about a rather special trip to the zoo. Here is a possible transcript abridged from http://www.onlyfunnystories.com/ZooJob.asp: One day an out of work mime artist is visiting the zoo and attempts to earn some money as a street performer monkey. As soon as he starts to draw a crowd, a zoo keeper grabs him and drags him into his office. The zoo keeper explains to the mime artist that the zoo's most popular attraction, a gorilla, has died suddenly and the keeper fears that attendance at the zoo will fall off. He offers the mime artist a job to dress up as the gorilla until they can get another one. The mime artist accepts. So the next morning the mime artist puts on the gorilla suit and enters the cage before the crowd comes. He discovers that it's a great job. He can sleep all he wants, play and make fun of people and he draws bigger crowds than he ever did as a mime. However, eventually the crowds tire of him and he tires of just swinging on trees. He begins to notice that the people are paying more attention to the lion in the cage next to his. Not wanting to lose the attention of his audience, he climbs to the top of his cage, crawls across a partition, and dangles from the top to the lion's cage. Of course, this makes the lion furious, but the crowd loves it. At the end of the day the zoo keeper comes and gives the mime artist a raise for being such a good attraction. Well, this goes on for some time, the mime keeps taunting the lion, the crowds grow larger, and his salary keeps going up. Then one terrible day when he is dangling over the furious lion he slips and falls. The mime artist is terrified. The lion gathers itself and prepares to pounce. The mime artist is so scared that he begins to run round and round the cage with the lion close behind. Finally, the mime artist starts screaming and yelling, "Help me, help me!", but the lion is quick and pounces. The mime artist soon finds himself flat on his back looking up at the angry lion and the lion says, "Shut up you idiot! Do you want to get us both fired?" The questions start with general gist questions (matching). Then comes an ordering question, which requires slightly more attention to detail. The last two are multiple-choice and gap-fill questions, which get students to focus on detailed aspects of the listening text. Here's how to do it The following sections refer you to the activities and point out any major differences. Setting up the quiz Listening and matching question Use NanoGong to create sound clips which replace pictures and texts. Here are some examples of the matching questions you could set up. These are general questions which help students get the gist of the story. Question Answer How many animals are there in the story?. Three Where does this take place? The zoo Where does the zoo keeper find the mime artist? On the street How many animals are there in the cages? Two This is what your matching question might look like: Here are a few more matching questions you could consider: Match recordings to pictures. Students could hear a description of an image (painting, photo) and identify the description. The easiest way to do this would be to take some photos of similar scenes. Match individual words to sounds. Students hear the recording and decide which words they are hearing. Recording Choice A. "I hear you're coming"   B."It's over here" hear/here   hear/here Ordering question In this variation students listen to a story and then order events in sequence. We need to make sure that the sequence is not guessable without hearing the story. Here are the stages from our story that you could include in the question: The zookeeper grabs the mime artist. The zookeeper offers the mime artist a job. The gorilla lies on top of the neighboring cage. The lion tries to attack the gorilla. The lion tells the gorilla off. This is what the ordering question would look like: Multiple-choice question Multiple-choice questions are a good way of getting students to investigate texts in more detail. Here are some possible questions we could include in this activity. Question 1 According to the story, why does the mime artist accept a job as a gorilla? Answer 1 His work on the street isn't going well. Answer 2 The zookeeper has an urgent need for a gorilla. Answer 3 He always wanted to work as a gorilla in a zoo. Answer 4 The last gorilla quit the job.
Read more
  • 0
  • 0
  • 1847
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 €18.99/month. Cancel anytime
article-image-adding-sound-music-and-video-3d-game-development-microsoft-silverlight-3-part-1
Packt
19 Nov 2009
3 min read
Save for later

Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 1

Packt
19 Nov 2009
3 min read
A game needs sound, music and video. It has to offer the player attractive background music. It must also generate sounds associated with certain game events. When a spaceship shoots a laser beam, a sound must accompany this action. Reproducing videos showing high-quality previously rendered animations is a good idea during transitions between one stage and the next. Hear the UFOs coming So far, we have worked with 3D scenes showing 3D models with textures and different kinds of lights. We took advantage of C# object-oriented capabilities and we animated 3D models and moved the cameras. We have read values from many different input devices and we added physics, artificial intelligence, amazing effects, gauges, statistics, skill levels, environments, and stages. However, the game does not use the speakers at all because there is no background music and there are no in-game sounds. Thus, we have to sort this issue out. Modern games use videos to dazzle the player before starting each new stage. They use amazing sound eff ects and music custom prepared for the game by renowned artists. How can we add videos, music, and sounds in Silverlight? We can do this by taking advantage of the powerful multimedia classes offered by Silverlight 3. However, as a game uses more multimedia resources than other simpler applications, we must be careful to avoid including unnecessary resources in the files that must be downloaded before starting the application. Time for action – installing tools to manipulate videos The 3D digital artists used Blender to create an introductory video showing a high quality rendered animation for five seconds. They took advantage of Blender's animation creation features, as shown in the following screenshot: A spaceship flies in a starry universe for a few seconds. Then, the camera navigates through the stars. Your project manager wants you to add this video as an introduction to the game. However, as the video file is in AVI (Audio Video Interleave) format and Silverlight 3 does not support this format, you have to convert the video to an appropriate format. The creation of video animations for a game is very complex and requires specialist skills. We are going to simplify this process by using an existing video. First, we must download and install an additional tool that will help us in converting an existing video to the most appropriate file formats used in Silverlight 3: The necessary tools will depend on the applications the digital artists use to create the videos. However, we will be using some tools that will work fine with our examples. Download one of the following files: parceApplication's name Download link File name Description Expression Encoder 2 http://www.microsoft.com/expression/try-it/try-it-v2.aspx Encoder_Trial_en.exe It is a commercial tool, but the trial offers a free fully functional version for 30 days. This tool will enable us to encode videos to the appropriate format to use in Silverlight 3. Expression Encoder 3 http://www.microsoft.com/expression/try-it Encoder_Trial_en.exe It is the newest trial version of the aforementioned commercial tool. Run the installers and follow the steps to complete the installation wizards. If you installed Expression Encoder 2, download and install its Service Pack 1. The download link for it is http://www.microsoft.com/expression/tryit/try-it-v2.aspx#encodersp1 file name—EncoderV2SP1_en.exe. Once you have installed one of the versions of Expression Encoder, you will be able to load and encode many video files in different file formats, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 2465

article-image-making-progress-menus-and-toolbars-using-ext-js-30-part-1
Packt
19 Nov 2009
7 min read
Save for later

Making Progress with Menus and Toolbars using Ext JS 3.0: Part 1

Packt
19 Nov 2009
7 min read
Placing buttons in a toolbar You can embed different types of components in a toolbar. This topic teaches you how to build a toolbar that contains image-only, text-only and image/text buttons, a toggle button, and a combo box. How to do it Create the styles for the toolbar items: #tbar{ width:600px;}.icon-data{ background:url(img/data.png) 0 no-repeat !important;}.icon-chart{ background:url(img/pie-chart.png) 0 no-repeat !important;}.icon-table{ background:url(img/table.png) 0 no-repeat !important;} Define a data store for the combo box: Ext.onReady(function() { Ext.QuickTips.init(); var makesStore = new Ext.data.ArrayStore({ fields: ['make'], data: makes // from cars.js }); Create a toolbar and define the buttons and combo box inline: var tb = new Ext.Toolbar({ renderTo: 'tbar', items: [{ iconCls: 'icon-data', tooltip: 'Icon only button', handler:clickHandler }, '-', { text: 'Text Button' }, '-', { text: 'Image/Text Button', iconCls: 'icon-chart' }, '-', { text: 'Toggle Button', iconCls: 'icon-table', enableToggle: true, toggleHandler: toggleHandler, pressed: true }, '->', 'Make: ', { xtype: 'combo', store: makesStore, displayField: 'make', typeAhead: true, mode: 'local', triggerAction: 'all', emptyText: 'Select a make...', selectOnFocus: true, width: 135 }]}); Finally, create handlers for the push button and the toggle button: function clickHandler(btn) { Ext.Msg.alert('clickHandler', 'button pressed');}function toggleHandler(item, pressed) { Ext.Msg.alert('toggleHandler', 'toggle pressed');} How it works The buttons and the combo box are declared inline. While the standard button uses a click handler through the handler config option, the toggle button requires the toggleHandler config option.The button icons are set with the iconCls option, using the classes declared in the first step of the topic. As an example, note the use of the Toolbar.Separator instances in this fragment: }, '-', { text: 'Text Button'}, '-', { text: 'Image/Text Button', iconCls: 'icon-chart'}, '-', { Using '-' to declare a Toolbar.Separator is equivalent to using xtype: 'tbseparator'. Similarly, using '->' to declare Toolbar.Fill is equivalent to using xtype:'tbfill'. See also... The next recipe, Working with the new ButtonGroup component, explains how to use the ButtonGroup class to organize a series of related buttons Working with the new ButtonGroup component A welcome addition to Ext JS is the ability to organize buttons in groups. Here's how to create a panel with a toolbar that contains two button groups: How to do it Create the styles for the buttons: #tbar{ width:600px;}.icon-data{ background:url(img/data.png) 0 no-repeat !important;}.icon-chart{ background:url(img/pie-chart.png) 0 no-repeat !important;}.icon-table{ background:url(img/table.png) 0 no-repeat !important;}.icon-sort-asc{ background:url(img/sort-asc.png) 0 no-repeat !important;}.icon-sort-desc{ background:url(img/sort-desc.png) 0 no-repeat !important;}.icon-filter{ background:url(img/funnel.png) 0 no-repeat !important;} Define a panel that will host the toolbar: Ext.onReady(function() { var pnl = new Ext.Panel({ title: 'My Application', renderTo:'pnl-div', height: 300, width: 500, bodyStyle: 'padding:10px', autoScroll: true, Define a toolbar inline and create two button groups: tbar: [{ xtype: 'buttongroup', title: 'Data Connections', columns: 1, defaults: { scale: 'small' }, items: [{ xtype:'button', text: 'Data Sources', iconCls:'icon-data' }, { xtype: 'button', text: 'Tables', iconCls: 'icon-table' }, { xtype: 'button', text: 'Reports', iconCls: 'icon-chart' }]}, { xtype: 'buttongroup', title: 'Sort & Filter', columns: 1, defaults: { scale: 'small' }, items: [{ xtype: 'button', text: 'Sort Ascending', iconCls: 'icon-sort-asc' }, { xtype: 'button', text: 'Sort Descending', iconCls: 'icon-sort-desc' }, { xtype: 'button', text: 'Filter', iconCls: 'icon-filter' }]}] How it works Using a button group consists of adding a step to the process of adding buttons, or other items, to a toolbar. Instead of adding the items directly to the toolbar, you need to firstly define the group and then add the items to the group: tbar: [{ xtype: 'buttongroup', title: 'Data Connections', columns: 1, defaults: { scale: 'small' }, items: [{ xtype:'button', text: 'Data Sources', iconCls:'icon-data' }, { xtype: 'button', text: 'Tables', iconCls: 'icon-table' }, { xtype: 'button', text: 'Reports', iconCls: 'icon-chart' }]} See also... The next recipe, Placing buttons in a toolbar, illustrates how you can embed different types of components in a toolbar Placing menus in a toolbar In this topic, you will see how simple it is to use menus inside a toolbar. The panel's toolbar that we will build, contains a standard button and a split button, both with menus: How to do it Create the styles for the buttons: #tbar{ width:600px;}.icon-data{ background:url(img/data.png) 0 no-repeat !important;}.icon-chart{ background:url(img/pie-chart.png) 0 no-repeat !important;}.icon-table{ background:url(img/table.png) 0 no-repeat !important;} Create a click handler for the menus: Ext.onReady(function() { Ext.QuickTips.init(); var clickHandler = function(action) { alert('Menu clicked: "' + action + '"');}; Create a window to host the toolbar: var wnd = new Ext.Window({ title: 'Toolbar with menus', closable: false, height: 300, width: 500, bodyStyle: 'padding:10px', autoScroll: true, Define the window's toolbar inline, and add the buttons and their respective menus: tbar: [{ text: 'Button with menu', iconCls: 'icon-table', menu: [ { text: 'Menu 1', handler:clickHandler.createCallback('Menu 1'), iconCls: 'icon-data' }, { text: 'Menu 1', handler: clickHandler.createCallback('Menu 2'), iconCls: 'icon-data'}]}, '-',{ xtype: 'splitbutton', text: 'Split button with menu', iconCls: 'icon-chart', handler: clickHandler.createCallback('Split button with menu'), menu: [ { text: 'Menu 3', handler: clickHandler.createCallback('Menu 3'), iconCls: 'icon-data' }, { text: 'Menu 4', handler: clickHandler.createCallback('Menu 4'), iconCls: 'icon-data'}] }]}); Finally, show the window: wnd.show(); How it works This is a simple procedure. Note how the split button is declared with the xtype: 'splitbutton' config option. Also, observe how the createCallback() function is used to invoke the clickHandler() function with the correct arguments for each button. See also... The next recipe, Commonly used menu items, shows the different items that can be used in a menu Commonly used menu items To show you the different items that can be used in a menu, we will build a menu that contains radio items, a checkbox menu, a date menu, and a color menu.This is how the radio options and checkbox menu will look: The Pick a Date menu item will display a date picker, as shown in the next screenshot: The Pick a Color menu item displays a color picker, as seen here: How to do it Create a handler for the checkbox menu: Ext.onReady(function() { Ext.QuickTips.init(); var onCheckHandler = function(item, checked) { Ext.Msg.alert('Menu checked', item.text + ', checked: ' + (checked ? 'checked' : 'unchecked')); }; Define a date menu: var dateMenu = new Ext.menu.DateMenu({ handler: function(dp, date) { Ext.Msg.alert('Date picker', date); }}); Define a color menu: var colorMenu = new Ext.menu.ColorMenu({ handler: function(cm, color) { Ext.Msg.alert('Color picker', String.format('You picked {0}.', color)); }}); Create a main menu. Now add the date and color menus, as well as a few inline menus: var menu = new Ext.menu.Menu({ id: 'mainMenu', items: [{ text: 'Radio Options', menu: { items: [ '<b>Choose a Theme</b>', { text: 'Aero Glass', checked: true, group: 'theme', checkHandler: onCheckHandler }, { text: 'Vista Black', checked: false, group: 'theme', checkHandler: onCheckHandler }, { text: 'Gray Theme', checked: false, group: 'theme', checkHandler: onCheckHandler }, { text: 'Default Theme', checked: false, group: 'theme', checkHandler: onCheckHandler } ] } }, { text: 'Pick a Date', iconCls: 'calendar', menu: dateMenu }, { text: 'Pick a Color', menu: colorMenu }, { text: 'The last menu', checked: true, checkHandler: onCheckHandler }]}); Create a toolbar and add the main menu: var tb = new Ext.Toolbar({ renderTo: 'tbar', items: [{ text: 'Menu Items', menu: menu }]}); How it works After defining the date and color pickers, the main menu is built. This menu contains the pickers, as well as a few more items that are defined inline. To display checked items (see the checked: true config option) with a radio button instead of a checkbox, the menu items need to be defined using the group config option. This is how the theme selector menu is built: menu: { items: [ '<b>Choose a Theme</b>', { text: 'Aero Glass', checked: true, group: 'theme', checkHandler: onCheckHandler }, { text: 'Vista Black', checked: false, group: 'theme', checkHandler: onCheckHandler See also... The Placing buttons in a toolbar recipe (covered earlier in this article) illustrates how you can embed different types of components in a toolbar >> Continue Reading Making Progress with Menus and Toolbars using Ext JS 3.0: Part 2 [ 1 | 2 ]   If you have read this article you may be interested to view : Making Progress with Menus and Toolbars using Ext JS 3.0: Part 2 Load, Validate, and Submit Forms using Ext JS 3.0: Part 1 Load, Validate, and Submit Forms using Ext JS 3.0: Part 2 Load, Validate, and Submit Forms using Ext JS 3.0: Part 3
Read more
  • 0
  • 0
  • 2919

article-image-sticky-features-your-blog-network-wordpress-mu-28-part-1
Packt
19 Nov 2009
9 min read
Save for later

Sticky Features for your Blog Network with WordPress MU 2.8: Part 1

Packt
19 Nov 2009
9 min read
What do people mean by "sticky"? If you have ever ran a blog or web site before, you may have noticed that it's fairly easy to get a spike in traffic by submitting a good story to a few social bookmarking sites or by being lucky enough to get a link to one of your posts from a much larger site. The problem is that after a day or so, when the submissions fall off the front page, it's likely your traffic will die down to its usual levels again. Some site owners fall into the trap of chasing after the next traffic spike, using "linkbait" articles with intentionally controversial titles and content, when they should really be focusing on quality content, improving the site, and working towards sustained growth. Many bloggers submit their site to StumbleUpon.com. StumbleUpon is a web service where users can enter their interests, and be sent to a random site that will match those interests. Those users can then either give a "thumbs up" to the site they are sent to indicating that they like the site or a "thumbs down" if they don't like it. Those votes are used to improve future suggestions and increase the chances of the next site that they "Stumble Upon" being one that they are interested in. Other popular sites for increasing traffic include Technorati (a site that measures the "authority" of a blog based on how many other bloggers are linking to it), and the news/story-related sites Reddit (a general interest site with everything from politics to gadgets-related news), and Digg (a site with a focus on tech and gaming news). A sticky blog is one that doesn't just attract new visitors, it keeps them. Instead of having a visitor click through from a link on Technorati or visit by using the Stumble! feature of StumbleUpon, skim the page they land on and then leave, a sticky blog would make that visitor stay around a little longer. Ideally, visitors would read the article they were interested in and then find themselves intrigued enough to read more articles. They may comment on some articles and then keep returning to read answers to their comments. Or, they may decide to subscribe to the blog so that they can read future posts. A sticky site encourages readers to become engaged with the community, resulting in long-term increases in traffic. When new readers arrive at the site for the first time, they get involved themselves and keep coming back. They may also tell their friends or link to the site from their own sites, giving you free promotion. Letting readers and authors communicate Interesting content is vital, but one of the best ways to get people coming back to your blog network is to give them a chance to interact with the site's authors and with each other. This not only makes the readers feel valued, it also opens up a dialogue that encourages repeat visitors. Contact forms Providing visitors with a way to contact you privately is useful for several reasons. The visitor may want to discuss advertising opportunities, submit some news you may be interested in, or ask for help with a problem they have accessing part of the site. You could post your email address on the site, but this makes you vulnerable to spam attacks. A contact form is a safer way to allow your visitors to contact you. Time for action – setting up contact forms Let's set up a contact form: Download Contact Form 7 from http://wordpress.org/extend/plugins/contact-form-7/. To install, upload the contents of the archive file to /wp-content/plugins. Activate the plugin and go to the settings page (Tools | Contact Form 7). You can also access the page by clicking Settings under the plugin name, which appears on the Manage Plugins page. You can add new fields using the Generate Tag drop-down menu. Further down the admin page you will see options to set error messages (such as the message users will see if they miss out a required field, or if they try to upload a file that is too big). Once you have created the form, make a note of the tag at the top of the screen (in our case this was [contact-form 1 "Contact form 1"] ). Create a new page (Pages | Add New) called Contact Us, add a short message to the page, and then paste the contact form tag into the page. Depending on the theme you are using, you may need to add the Pages widget to your sidebar so that visitors can find the new page. Your page should look something like this: What just happened? Contact Form 7 is a powerful contact form tool that supports CAPTCHAs (via the Really Simple CAPTCHA  plugin), file uploads, drop-down menus, and more. You can define multiple contact forms and have each one submit to a different email address. This could be useful if you wish to have different people contacted for, say, advertising queries, news submissions, and tech support. You can also have a contact form submit to multiple email addresses. So, as well as having the relevant person receive a copy of each message, the site administrator could ensure they receive a copy of all messages too. You can set a prefix for each message, in addition to the subject line the visitor sets. For example, if you set the prefix to [Slayer-Form1], all emails from that contact form will have a subject line that begins with that text. You can use this to set up filters in your email application, making it easy to prioritize emails from different contact forms. Improved comments The basic WordPress MU comment feature allows readers to post their thoughts about a blog post, but it is not very good for encouraging discussion. One useful service for bloggers is IntenseDebate. This service allows for threaded discussion in comments, subscription to comments by RSS and email, and the ability to tie blog commenting in with other social networking sites and follow comments made by other blog readers. Time for action – IntenseDebate Comments Download the IntenseDebate Comments plugin from http://wordpress.org/extend/plugins/intensedebate/. You will need to sign up for an account at http://intensedebate.com/. Activate the plugin. Go to Settings | IntenseDebate. You will be presented with a login screen. Enter the account details for the account you created in step 2. Once you have logged in, click Start Importing Comments. The import process can take a very long time, even if you don't have many comments to import. Once the import process is complete, you can tweak the settings to suit your blog—although I found the default ones were a good starting point. The IntenseDebate Comments plugin has its own Comments caption, so you may want to remove the Comments header from the index.php file in your theme folder. The new comment box should look something like this: You can moderate comments using the already familiar WordPress MU interface or the dashboard on the IntenseDebate site. What just happened? IntenseDebate is a commenting system that sits on top of WordPress and WordPress MU. It is ideal for all blogs, whether they are part of a blog network, or a standalone blog. It does not replace the existing WordPress comment system; it only complements it. This means you can use IntenseDebate in conjunction with other plugins that rely on the WordPress MU comment system. Readers can comment on your blog using the IntenseDebate comment system. If they have JavaScript turned off, they will be presented with the normal WordPress comment system instead. IntenseDebate has lots of useful features that will make your users feel a greater sense of engagement with your site's authors. Those features are described below: Threaded discussions: IntenseDebate supports threaded comments. This makes it easy for readers to follow the discussions going on in the comments section. Readers can reply to the blog post itself, or reply to a specific comment, and IntenseDebate will break related comments into threads so that the discussion is easy to keep track of. Track comments or comment anonymously: Readers can comment anonymously, or, if they have an IntenseDebate profile they can log in to it and comment using it. Any comments made will be stored in the WordPress comments database and also be sent to IntenseDebate. Subscribe to comments: Readers can subscribe to comments on a particular post by email or through their favorite RSS reader. If they have an IntenseDebate account, they also have the option to send a Twitter message or "Tweet" to alert their friends that they have commented on a particular post. Reputation and voting: Another useful feature is the reputation system. Visitors can vote on comments, and comments that get a lot of negative votes will be hidden from view unless a user requests to see them. This is a handy form of "self moderation" for the community. The reputation system applies to only logged in users and gives each user an overall rating based on the quality of their comments on sites all over the Internet. Activating IntenseDebate on your users' blogs One important thing to remember is that even if you set IntenseDebate to automatically activate for your users, it won't do anything unless they set it up. Your users will still have the original WordPress MU comment system. They will be alerted to the fact that the plugin is not working for them by a message that will appear at the top of every page in their admin panel. Have a go hero – tweaking IntenseDebate IntenseDebate has so many features that there is not enough room to cover them all here. Take a look at the Extras (http://intensedebate.com/extras) page for some widgets that you may want to add to your blog. Also, check the Settings page for your blog in IntenseDebate. You can edit the moderation settings on that page. The default settings include a list of spam words that will cause comments to be flagged for moderation. Comments will also be flagged for moderation if they contain more than two URLs. You can tweak the commenting system's settings to filter by IP address, email address, key words, and profanity. You can also alter how the comments are displayed, the text displayed when people report comments, the layout, and the location of the blog's RSS feed. You may want to change that to use the FeedBurner version of the RSS feed. >> continue Reading: Sticky Features for your Blog Network with WordPress MU 2.8: Part 2
Read more
  • 0
  • 0
  • 1832

article-image-user-management-joomla-15-part-1
Packt
19 Nov 2009
4 min read
Save for later

User Management in Joomla! 1.5: Part 1

Packt
19 Nov 2009
4 min read
The big picture: Who are users? Users are people who have registered their details with you and are allocated access to certain resources and information, depending on their role within the scope of your website. They can be administrators and content editors/contributors or customers who purchase goods and services from you. This is different to a casual visitor who lands up at the frontend of your site because he/she has your website address or hopefully has found you through a search engine. You may be able to turn these casual visitors into registered users if you have something to offer them. Say you want to provide special content to only those who are genuinely interested in your services or products. Encouraging them to register allows you to collect contact information (it's best to ask only for the most relevant details, as people generally don't want to give out more than they need to) and keep in touch. Hopefully, you can convert it into an ongoing relationship with sales and benefits for your business. Generating interest in your products and services is important here and suggesting some level of exclusivity can make your customers feel privileged in terms of being privy to information not readily available to just anyone. Put simply though, users are your website visitors, content contributors, and administrators. Depending on their role, they are essentially divided into two broad groups with smaller sub-categories within them. Frontend users Frontend users do not have access to the administration interface and can only access material and information through the frontend. They can be: Registered users, authors, editors, and publishers who have privileges to edit and update information. Guests or casual visitors to your site. These visitors come to your site anonymously and unregistered. People who register their details in order to transact with you. Frontend user definitions When a user is registered with you, they are allocated to a group, as per the settings applied within the Global Configuration. They can be any one of the following: Registered Users are visitors to your site who have registered themselves in order to view certain content or transact with you. Authors can submit new content articles to the site with approval, but can't edit existing articles. A publisher or someone higher must approve these submissions. Editors can submit and edit new content articles. A publisher or someone higher must also approve these entries. Publishers  can submit new content articles, edit existing articles, and publish the articles. None of these user groups have access to the administration interface, and can only edit or add material from the frontend. Administration users Administration users can edit and update the content of your site by logging into the administration control panel and are those who: Have Administrator Manager or Super Administrator access. Each of these roles has specific access. For example, the Manager profile does not have access to the User Manager section. Have various levels of access within the administration control panel, the highest level being Super Administrator. Editing the frontend Login Form From the frontend of your website, the Login Form allows users to access content that is potentially specialized and only visible to them, or to transact with you if you're running an e-commerce site. You can also customize your Login Form by adding text and a link to create new accounts. Lost usernames and passwords The Forgot your password and Forgot your username links are important not only for users to fi nd their password or username again, but also to help you to manage users. Rather than unnecessarily creating a new account if they have lost their login details, having an e-mail prompt sent to reset their details is a more efficient approach. Clicking the link for either will generate a request to enter an e-mail address. A confi rmation e-mail will be sent with a verification token or string of characters which allows the user to enter and reset their password. Alternatively, their username will be emailed to them.      
Read more
  • 0
  • 0
  • 6522
article-image-plotting-data-using-matplotlib-part-2
Packt
19 Nov 2009
15 min read
Save for later

Plotting data using Matplotlib: Part 2

Packt
19 Nov 2009
15 min read
Plotting data from a CSV file A common format to export and distribute datasets is the Comma-Separated Values (CSV) format. For example, spreadsheet applications allow us to export a CSV from a working sheet, and some databases also allow for CSV data export. Additionally, it's a common format to distribute datasets on the Web. In this example, we'll be plotting the evolution of the world's population divided by continents, between 1950 and 2050 (of course they are predictions), using a new type of graph: bars stacked. Using the data available at http://www.xist.org/earth/pop_continent.aspx (that fetches data from the official UN data at http://esa.un.org/unpp/index.asp), we have prepared the following CSV file: Continent,1950,1975,2000,2010,2025,2050Africa,227270,418765,819462,1033043,1400184,1998466Asia,1402887,2379374,3698296,4166741,4772523,5231485Europe,547460,676207,726568,732759,729264,691048Latin America,167307,323323,521228,588649,669533,729184Northern America,171615,242360,318654,351659,397522,448464Oceania,12807,21286,31160,35838,42507,51338 In the first line, we can find the header with a description of what the data in the columns represent. The other lines contain the continent's name and its population (in thousands) for the given years. In the first line, we can find the header with a description of what the data in the columns represent. The other lines contain the continent's name and its population (in thousands) for the given years. There are several ways to parse a CSV file, for example: NumPy's loadtxt() (what we are going to use here) Matplotlib's mlab.csv2rec() The csv module (in the standard library) but we decided to go with loadtxt() because it's very powerful (and it's what Matplotlib is standardizing on). Let's look at how we can plot it then: # for file opening made easierfrom __future__ import with_statement We need this because we will use the with statement to read the file. # numpyimport numpy as np NumPy is used to load the CSV and for its useful array data type. # matplotlib plotting moduleimport matplotlib.pyplot as plt# matplotlib colormap moduleimport matplotlib.cm as cm# needed for formatting Y axisfrom matplotlib.ticker import FuncFormatter# Matplotlib font managerimport matplotlib.font_manager as font_manager In addition to the classic pyplot module, we need other Matplotlib submodules: cm (color map): Considering the way we're going to prepare the plot, we need to specify the color map of the graphical elements FuncFormatter: We will use this to change the way the Y-axis labels are displayed font_manager: We want to have a legend with a smaller font, and font_manager allows us to do that def billions(x, pos): """Formatter for Y axis, values are in billions""" return '%1.fbn' % (x*1e-6) This is the function that we will use to format the Y-axis labels. Our data is in thousands. Therefore, by dividing it by one million, we obtain values in the order of billions. The function is called at every label to draw, passing the label value and the position. # bar widthwidth = .8 As said earlier, we will plot bars, and here we defi ne their width. The following is the parsing code. We know that it's a bit hard to follow (the data preparation code is usually the hardest one) but we will show how powerful it is. # open CSV filewith open('population.csv') as f: The function we're going to use, NumPy loadtxt(), is able to receive either a filename or a file descriptor, as in this case. We have to open the file here because we have to strip the header line from the rest of the file and set up the data parsing structures. # read the first line, splitting the yearsyears = map(int, f.readline().split(',')[1:]) Here we read the first line, the header, and extract the years. We do that by calling the split() function and then mapping the int() function to the resulting list, from the second element onwards (as the first one is a string). # we prepare the dtype for exacting data; it's made of:# <1 string field> <len(years) integers fields>dtype = [('continents', 'S16')] + [('', np.int32)]*len(years) NumPy is flexible enough to allow us to define new data types. Here, we are creating one ad hoc for our data lines: a string (of maximum 16 characters) and as many integers as the length of years list. Also note how the fi rst element has a name, continents, while the last integers have none: we will need this in a bit. # we load the file, setting the delimiter and the dtype abovey = np.loadtxt(f, delimiter=',', dtype=dtype) With the new data type, we can actually call loadtxt(). Here is the description of the parameters: f: This is the file descriptor. Please note that it now contains all the lines except the first one (we've read above) which contains the headers, so no data is lost. delimiter: By default, loadtxt() expects the delimiter to be spaces, but since we are parsing a CSV file, the separator is comma. dtype: This is the data type that is used to apply to the text we read. By default, loadtxt() tries to match against float values # "map" the resulting structure to be easily accessible:# the first column (made of string) is called 'continents'# the remaining values are added to 'data' sub-matrix# where the real data arey = y.view(np.dtype([('continents', 'S16'), ('data', np.int32, len(years))])) Here we're using a trick: we view the resulting data structure as made up of two parts, continents and data. It's similar to the dtype that we defined earlier, but with an important difference. Now, the integer's values are mapped to a field name, data. This results in the column continents with all the continents names,and the matrix data that contains the year's values for each row of the file. data = y['data']continents = y['continents'] We can separate the data and the continents part into two variables for easier usage in the code. # prepare the bottom arraybottom = np.zeros(len(years)) We prepare an array of zeros of the same length as years. As said earlier, we plot stacked bars, so each dataset is plot over the previous ones, thus we need to know where the bars below finish. The bottom array keeps track of this, containing the height of bars already plotted. # for each line in datafor i in range(len(data)): Now that we have our information in data, we can loop over it. # create the bars for each element, on top of the previous barsbt = plt.bar(range(len(data[i])), data[i], width=width, color=cm.hsv(32*i), label=continents[i], bottom=bottom) and create the stacked bars. Some important notes: We select the the i-th row of data, and plot a bar according to its element's size (data[i]) with the chosen width. As the bars are generated in different loops, their colors would be all the same. To avoid this, we use a color map (in this case hsv), selecting a different color at each iteration, so the sub-bars will have different colors. We label each bar set with the relative continent's name (useful for the legend) As we have said, they are stacked bars. In fact, every iteration adds a piece of the global bars. To do so, we need to know where to start drawing the bar from (the lower limit) and bottom does this. It contains the value where to start drowing the current bar. # update the bottom arraybottom += data[i] We update the bottom array. By adding the current data line, we know what the bottom line will be to plot the next bars on top of it. # label the X ticks with yearsplt.xticks(np.arange(len(years))+width/2, [int(year) for year in years]) We then add the tick's labels, the years elements, right in the middle of the bar. # some information on the plotplt.xlabel('Years')plt.ylabel('Population (in billions)')plt.title('World Population: 1950 - 2050 (predictions)') Add some information to the graph. # draw a legend, with a smaller fontplt.legend(loc='upper left', prop=font_manager.FontProperties(size=7)) We now draw a legend in the upper-left position with a small font (to better fit the empty space). # apply the custom function as Y axis formatterplt.gca().yaxis.set_major_formatter(FuncFormatter(billions) Finally, we change the Y-axis label formatter, to use the custom formatting function that we defined earlier. The result is the next screenshot where we can see the composition of the world population divided by continents: In the preceding screenshot, the whole bar represents the total world population, and the sections in each bar tell us about how much a continent contributes to it. Also observe how the custom color map works: from bottom to top, we have represented Africa in red, Asia in orange, Europe in light green, Latin America in green, Northern America in light blue, and Oceania in blue (barely visible as the top of the bars). Plotting extrapolated data using curve fitting While plotting the CSV values, we have seen that there were some columns representing predictions of the world population in the coming years. We'd like to show how to obtain such predictions using the mathematical process of extrapolation with the help of curve fitting. Curve fitting is the process of constructing a curve (a mathematical function) that better fits to a series of data points. This process is related to other two concepts: interpolation: A method of constructing new data points within the range of a known set of points extrapolation: A method of constructing new data points outside a known set of points The results of extrapolation are subject to a greater degree of uncertainty and are influenced a lot by the fitting function that is used. So it works this way: First, a known set of measures is passed to the curve fitting procedure that computes a function to approximate these values With this function, we can compute additional values that are not present in the original dataset Let's first approach curve fitting with a simple example: # Numpy and Matplotlibimport numpy as npimport matplotlib.pyplot as plt These are the classic imports. # the known points setdata = [[2,2],[5,0],[9,5],[11,4],[12,7],[13,11],[17,12]] This is the data we will use for curve fitting. They are the points on a plane (so each has a X and a Y component) # we extract the X and Y components from previous pointsx, y = zip(*data) We aggregate the X and Y components in two distinct lists. # plot the data points with a black crossplt.plot(x, y, 'kx') Then plot the original dataset as a black cross on the Matplotlib image. # we want a bit more data and more fine grained for# the fitting functionsx2 = np.arange(min(x)-1, max(x)+1, .01) We prepare a new array for the X values because we wish to have a wider set of values (one unit on the right and one on to the left of the original list) and a fine grain to plot the fitting function nicely. # lines styles for the polynomialsstyles = [':', '-.', '--'] To differentiate better between the polynomial lines, we now define their styles list. # getting style and count one at timefor d, style in enumerate(styles): Then we loop over that list by also considering the item count. # degree of the polynomialdeg = d + 1 We define the actual polynomial degree. # calculate the coefficients of the fitting polynomialc = np.polyfit(x, y, deg) Then compute the coefficients of the fitting polynomial whose general format is: c[0]*x**deg + c[1]*x**(deg – 1) + ... + c[deg]# we evaluate the fitting function against x2y2 = np.polyval(c, x2) Here, we generate the new values by evaluating the fitting polynomial against the x2 array. # and then we plot itplt.plot(x2, y2, label="deg=%d" % deg, linestyle=style) Then we plot the resulting function, adding a label that indicates the degree of the polynomial and using a different style for each line. # show the legendplt.legend(loc='upper left') We then show the legend, and the final result is shown in the next screenshot: Here, the polynomial with degree=1 is drawn as a dotted blue line, the one with degree=2 is a dash-dot green line, and the one with degree=3 is a dashed red line. We can see that the higher the degree, the better is the fit of the function against the data. Let's now revert to our main intention, trying to provide an extrapolation for population data. First a note: we take the values for 2010 as real data and not predictions (well, we are quite near to that year) else we have very few values to create a realistic extrapolation. Let's see the code: # for file opening made easierfrom __future__ import with_statement# numpyimport numpy as np# matplotlib plotting moduleimport matplotlib.pyplot as plt# matplotlib colormap moduleimport matplotlib.cm as cm# Matplotlib font managerimport matplotlib.font_manager as font_manager# bar widthwidth = .8# open CSV filewith open('population.csv') as f: # read the first line, splitting the years years = map(int, f.readline().split(',')[1:]) # we prepare the dtype for exacting data; it's made of: # <1 string field> <6 integers fields> dtype = [('continents', 'S16')] + [('', np.int32)]*len(years) # we load the file, setting the delimiter and the dtype above y = np.loadtxt(f, delimiter=',', dtype=dtype) # "map" the resulting structure to be easily accessible: # the first column (made of string) is called 'continents' # the remaining values are added to 'data' sub-matrix # where the real data are y = y.view(np.dtype([('continents', 'S16'), ('data', np.int32, len(years))]))# extract fieldsdata = y['data']continents = y['continents'] This is the same code that is used for the CSV example (reported here for completeness). x = years[:-2]x2 = years[-2:] We are dividing the years into two groups: before and after 2010. This translates to split the last two elements of the years list. What we are going to do here is prepare the plot in two phases: First, we plot the data we consider certain values After this, we plot the data from the UN predictions next to our extrapolations # prepare the bottom arrayb1 = np.zeros(len(years)-2) We prepare the array (made of zeros) for the bottom argument of bar(). # for each line in datafor i in range(len(data)): # select all the data except the last 2 values d = data[i][:-2] For each data line, we extract the information we need, so we remove the last two values. # create bars for each element, on top of the previous barsbt = plt.bar(range(len(d)), d, width=width, color=cm.hsv(32*(i)), label=continents[i], bottom=b1)# update the bottom arrayb1 += d Then we plot the bar, and update the bottom array. # prepare the bottom arrayb2_1, b2_2 = np.zeros(2), np.zeros(2) We need two arrays because we will display two bars for the same year—one from the CSV and the other from our fitting function. # for each line in datafor i in range(len(data)): # extract the last 2 values d = data[i][-2:] Again, for each line in the data matrix, we extract the last two values that are needed to plot the bar for CSV. # select the data to compute the fitting functiony = data[i][:-2] Along with the other values needed to compute the fitting polynomial. # use a polynomial of degree 3c = np.polyfit(x, y, 3) Here, we set up a polynomial of degree 3; there is no need for higher degrees. # create a function out of those coefficientsp = np.poly1d(c) This method constructs a polynomial starting from the coefficients that we pass as parameter. # compute p on x2 values (we need integers, so the map)y2 = map(int, p(x2)) We use the polynomial that was defined earlier to compute its values for x2. We also map the resulting values to integer, as the bar() function expects them for height. # create bars for each element, on top of the previous barsbt = plt.bar(len(b1)+np.arange(len(d)), d, width=width/2, color=cm.hsv(32*(i)), bottom=b2_1) We draw a bar for the data from the CSV. Note how the width is half of that of the other bars. This is because in the same width we will draw the two sets of bars for a better visual comparison. # create the bars for the extrapolated valuesbt = plt.bar(len(b1)+np.arange(len(d))+width/2, y2, width=width/2, color=cm.bone(32*(i+2)), bottom=b2_2) Here, we plot the bars for the extrapolated values, using a dark color map so that we have an even better separation for the two datasets. # update the bottom arrayb2_1 += db2_2 += y2 We update both the bottom arrays. # label the X ticks with yearsplt.xticks(np.arange(len(years))+width/2, [int(year) for year in years]) We add the years as ticks for the X-axis. # draw a legend, with a smaller fontplt.legend(loc='upper left', prop=font_manager.FontProperties(size=7)) To avoid a very big legend, we used only the labels for the data from the CSV, skipping the interpolated values. We believe it's pretty clear what they're referring to. Here is the screenshot that is displayed on executing this example: The conclusion we can draw from this is that the United Nations uses a different function to prepare the predictions, especially because they have a continuous set of information, and they can also take into account other environmental circumstances while preparing such predictions. Tools using Matplotlib Given that it's has an easy and powerful API, Matplotlib is also used inside other programs and tools when plotting is needed. We are about to present a couple of these tools: NetworkX Mpmath
Read more
  • 0
  • 0
  • 6514

article-image-creating-design-ez-publish-4-templating-system-part-2
Packt
19 Nov 2009
8 min read
Save for later

Creating a Design with eZ Publish 4 Templating System: Part 2

Packt
19 Nov 2009
8 min read
eZ Webin For this article it is assumed that the eZ Webin package is installed as a frontend for our site. This package is very flexible and is usually used as a starting point for developing a new site. By default, it includes: A flexible layout Some useful custom content classes (blog, event, forum, article, and so on) Web 2.0 features, such as a tag cloud and comment functions Custom template operators In our project, we will extend and override the eZ Webin template in order to create the Packtmedia Magazine site and add some features needed for the project. We will see this step-by-step as we understand better how eZ Publish works. Overriding the standard page layout The page layout is the main template and defines the style of the entire site. To create a page layout template, we need to create a file named pagelayout.tpl and place it inside the templates folder of our design extension. As we said, we will work with eZ Webin. This extension doesn't use the standard page layout but overrides the standard page layout with its own custom behavior. We need to do the same overriding from the eZ Webin pagelayout.tpl. To override the template, we have to copy it in our design's extension folder placed in extension/packtmedia/design/magazine/templates/. Now open a shell and execute this: # cd /var/www/packtmediaproject/extension# cp /ezwebin/design/ezwebin/templates/pagelayout.tpl /packtmedia/design/magazine/templates/ We will use this new pagelayout.tpl file to implement the wireframe that we developed in the previous sections. Section for our project eZ Publish includes features for creating a particular view in order to add content objects inside specified sections. For example, if we take a look at our wireframe, we need to assign a different layout for rendering the Issue archive folder and its subfolders. To do this, we have to create a new section in the administration panel and associate it to the entire Issue archive subtree. After that, we can use the fetch functions to select the correct view for that section. Creating a new section To create a new section, we have to open our browser and from the site's backend, select the Setup tab from the top menu. We then need to navigate to the Sections link in the left-hand menu, and then click on the New section button. Next, we will create a new section called Archive and select the default Content structure value in the select menu. Now, a new Archive link will appear in the Sections list. We have to click on the + button to the left of the Archive link, and then select the Issue archive node, by selecting the relevant checkbox. After we have saved, click on the Select button. All of the Issue archive subfolders will be placed inside the Archive section. We have to remember the ID of this section, which we'll use to create the override rules. In this case, the section ID number is 6, as seen in the first screenshot in the Creating a new section section. Setting up the section permission access By default, eZ Publish creates private sections that only an administrator can access. To make a section public, we need to give read permission to anonymous users. To set up the rules, we have to go back to Setup tab on the top menu, and then click on the Role and policies link on the left-hand menu. Here, we have to click on the Edit button on the right-hand side of the Anonymous link, and then click on the New policy button. Next, select the content option in the Module field, and then click on the Grant access to one function button. Select the read option in the Function field, and then click on the Grant limited access button. Next, select the Anonymous option for the Section field. Click on the OK button, and then click on the OK button on the Edit <Anonymous> Role page. Now, the anonymous user can access the Archive section. In the next paragraph, we will use this section to create custom override rules. Customizing the page layout After we copy the pagelayout.tpl template into the new path, we have to work on it in order to create the three columns inside the content layout of the eZ Webin template. To do this, first of all, we have to remove the leftmost sidebar, along with the secondary navigation menu, inside the Archive section that we have created. Open the pagelayout.tpl file that you have copied into your favorite IDE, and take a look at the code. At line 62 we will find the following code: {if and( is_set( $content_info.class_identifier ), ezini('MenuSettings', 'HideLeftMenuClasses', 'menu.ini' )|contains($content_info.class_identifier ) )}{set $pagestyle = 'nosidemenu noextrainfo'} Here, eZ Webin hides the side menu if the content class belongs to the array returned by the ezini operator. We now need to extend the IF sentence and add a control to the section ID, by using the following code: {if or(and( is_set( $content_info.class_identifier ), ezini('MenuSettings', 'HideLeftMenuClasses', 'menu.ini' )|contains($content_info.class_identifier ) ), $module_result.section_id|eq(6))}{set $pagestyle = 'nosidemenu noextrainfo'} As we can see, this code will now check to see if the browsed section has an ID equal to 6 (that is, the archive section ID that we previously created) and if it has, will hide the unnecessary sidebar. CSS editing Luckily, the entire template code of eZ Webin is strongly semantic and all of the elements have their own IDs and classes. Thanks to this, we can change a lot of things by simply working on the CSS. By default, the CMS uses six CSSes. These are: core.css: this is the global stylesheet where all of the standard tag styles for eZ Publish are defined; usually, this file is overridden by all of the others webstyletoolbar.css: this stylesheet is imported for the frontend web toolbar that is used for editing the content pagelayout.css: this is where all of the default styles of the global pagelayout are defined content.css: this is where all the default styles of the content classes are defined site-colors.css: this file is used to override the pagelayout.css to skin a site differently classes-colors.css: this file is used to override the default styles defined by the content.css file To edit the CSS, we have to copy the original eZ Webin stylesheet from the /var/www/packtmediaproject/extension/ezwebin/design/ezwebin/stylesheets folder to our design directory and then to execute the following commands: # cd /var/www/packtmediaproject/extension/# cp -rf ezwebin/design/ezwebin/stylesheets/* packtmedia/design/magazine/stylesheets/ Now, every time that we want to change the stylesheet, we have to remember to edit the CSS files in the design/magazine/stylesheets/ directory of our extension. Creating a new style package In eZ Publish, as we did for extension, it's possible to create a portable style package, so we can share and reuse our custom style in other sites. We can do this by navigating to the backend admin site and uploading the new stylesheet that we want to use. First, we have to create our CSS files by using our favorite CSS editor; we have to remember that they will override the default styles, so we only need to add the lines that we want to change. After we create the new stylesheet files, we have to open the browser, click on the Setup tab, and then click on the Package link in the left-hand sidebar. The system will ask us where we want to create our new package. We will select the local repository and click on the Create new package button. eZ Publish will then ask us which kind of package we want to create. We have to select the Site style wizard, and then click on the Create new package button. We can now choose a thumbnail for the style that we are uploading, or continue without it. After selecting the thumbnail, the wizard will ask us to choose the CSS file that we previously created. Select it, and then click on the Next button. With the wizard, we will also upload one or more images, for example a new logo file, or other images related to the CSS. To not upload files, we simply have to click on the Next button without selecting a file in the form. We have to remember that all of the images that we upload will be saved in a subfolder named images, which will be placed in the same directory as the stylesheet. This will be useful when we need to set the relative path of the images used inside the CSS. We can now add the package information and export it to our PC (if required). The new style package will automatically be installed in the eZ Publish package folder. It will be accessible from the Design tab, via the sidebar's Look and Feel link. If we select the package and clear the cache automatically, it will be applied to the frontend. Summary In this article, we learned the basics of the templating system of eZ Publish. We worked on template's function and operator, and also learned how to extend the default WYSIWYG editor of eZ Publish. Moreover, we created the site wireframe and learned how the design overriding feature works. We also created a new stylesheet package, and applied it to our extension.
Read more
  • 0
  • 0
  • 2451

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

Managing Images and Videos in Joomla! 1.5: Part 1

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

Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 1

Packt
19 Nov 2009
7 min read
There are many reasons why you would want to display a calendar. You can use it to display upcoming events, to keep a diary, or to show a timetable. Recently, for example, I combined a calendar with an online store for a client to book meetings and receive payments more intuitively. Google calendar is probably what springs to mind when people think of calendars online. There is a very good plugin called jquery-week-calendar that shows a week with events in a fashion similar to Google's calendar. Its homepage is at http://www.redredred.com.au/projects/jquery-week-calendar/. To get the latest copy of the plugin, go to http://code.google.com/p/jquery-week-calendar/downloads/list and get the highest-numbered file. The examples in this article are done with version 1.2.0. Download the library and extract it so that there is a directory named jquery-weekcalendar-1.2.0 in the root of your demo directory. Displaying the calendar As usual, the HTML for the simplest configuration is very simple. Save this as calendar.html: <html> <head> <script src="../jquery.min.js"></script> <script src="../jquery-ui.min.js"></script> <script src="../jquery-weekcalendar-1.2.0/jquery.weekcalendar.js"> </script> <script src="calendar.js"></script> <link rel="stylesheet" type="text/css" href="../jquery-ui.css" /> <link rel="stylesheet" type="text/css" href="../jquery-weekcalendar-1.2.0/jquery.weekcalendar.css"/> </head> <body> <div id="calendar_wrapper" style="height:500px"></div> </body> </html> We will keep all of our JavaScript in an external file called calendar.js, which will initially contain just this: $(document).ready(function() { $('#calendar_wrapper').weekCalendar({ 'height':function($calendar){ return $('#calendar_wrapper')[0].offsetHeight; } }); }); This is fairly straightforward. The script will apply the widget to the #calendar_wrapper element, and the widget's height will be set to that of the wrapper element. Even with this tiny bit of code, we already have a good-looking calendar, and when you drag your mouse cursor around it, you'll see that events are created as you lift the mouse up: It looks good, but it doesn't do anything yet. The events are temporary, and will vanish as soon as you change the week or reload the page. In order to make them permanent, we need to send details of the events to the server and save them there. Creating an event What we need to do is to have the client save the event on the server when it is created. In this article, we'll use PHP sessions to save the data for the sake of simplicity. Sessions are chunks of data, which are kept on the server side and are related to the cookie or PHPSESSID parameter that the client uses to access that session. We will use sessions in these examples because they do not need as much setup as databases. For your own projects, you should adapt the PHP side in order to connect to a database instead. If you are using this article to create a full application, you will obviously want to use something more permanent than sessions, in which case the PHP code should be adapted such that all references to sessions are replaced with database references instead. This is beyond the scope of this book, but as you are a PHP developer, you probably do this everyday anyway! When the event has been created, we want a modal dialog to appear and ask for more details. In this test case, we'll add a text area for further details, which allows for more data than would appear in the small visible area in the calendar itself. A modal dialog is a "pop up" that appears and blocks all other actions on the page until it has been taken care of. It's useful in cases where the answer to a question must be known before a script can carry on with its work. Now, let's create an event and add it to our calendar. Client-side code In the calendar.js file, add an eventNew event to the weekCalendar call: $(document).ready(function() { $('#calendar_wrapper').weekCalendar({ 'height':function($calendar){ return $('#calendar_wrapper')[0].offsetHeight; }, 'eventNew':function(calEvent, $event) { calendar_new_entry(calEvent,$event); } }); }); When an event is created, the calendar_new_entry function will be called with details of the new event in the calEvent parameter. Now, add the function calendar_new_entry: function calendar_new_entry(calEvent,$event){ var ds=calEvent.start, df=calEvent.end; $('<div id="calendar_new_entry_form" title="New Calendar Entry"> event name<br /> <input value="new event" id="calendar_new_entry_form_title" /> <br /> body text<br /> <textarea style="width:400px;height:200px" id="calendar_new_entry_form_body">event description </textarea> </div>').appendTo($('body')); $("#calendar_new_entry_form").dialog({ bgiframe: true, autoOpen: false, height: 440, width: 450, modal: true, buttons: { 'Save': function() { var $this=$(this); $.getJSON('./calendar.php?action=save&id=0&start=' +ds.getTime()/1000+'&end='+df.getTime()/1000, { 'body':$('#calendar_new_entry_form_body').val(), 'title':$('#calendar_new_entry_form_title').val() }, function(ret){ $this.dialog('close'); $('#calendar_wrapper').weekCalendar('refresh'); $("#calendar_new_entry_form").remove(); } ); }, Cancel: function() { $event.remove(); $(this).dialog('close'); $("#calendar_new_entry_form").remove(); } }, close: function() { $('#calendar').weekCalendar('removeUnsavedEvents'); $("#calendar_new_entry_form").remove(); } }); $("#calendar_new_entry_form").dialog('open'); } What's happening here is that a form is created and added to the body (the second line of the function), then the third line of the function creates a modal window from that form and adds some buttons to it. Our modal dialog should look like this: The Save button, when pressed, calls the server-side file calendar.php with the parameters needed to save the event, including the start and end, and the title and body. When the result returns, the calendar is refreshed with the new event's data included. When any of the buttons are clicked, we close the dialog and remove it from the page completely. Note how we are sending time information to the server (shown highlighted in the code we just saw). JavaScript time functions usually measure in milliseconds, but we want to send it to PHP, which generally measures time in seconds. So, we convert the value on the client so that the PHP can use the received data as it is, without needing to do anything to it. Every little helps! Server-side code On the server side, we want to take the new event and save it. Remember that we're doing it in sessions in this example, but you should feel free to adapt this to any other model that you wish. Create a file called calendar.php and save it with this source in it: <?php session_start(); if(!isset($_SESSION['calendar'])){ $_SESSION['calendar']=array( 'ids'=>0, ); } if(isset($_REQUEST['action'])){ switch($_REQUEST['action']){ case 'save': // { $start_date=(int)$_REQUEST['start']; $data=array( 'title'=>(isset($_REQUEST['title'])?$_REQUEST['title']:''), 'body' =>(isset($_REQUEST['body'])?$_REQUEST['body']:''), 'start'=>date('c',$start_date), 'end' =>date('c',(int)$_REQUEST['end']) ); $id=(int)$_REQUEST['id']; if($id && isset($_SESSION['calendar'][$id])){ $_SESSION['calendar'][$id]=$data; } else{ $id= ++$_SESSION['calendar']['ids']; $_SESSION['calendar'][$id]=$data; } echo 1; exit; // } } } ?> In the server-side code of this project, all the requested actions are handled by a switch statement. This is done for demonstration purposes—whenever we add a new action, we simply add a new switch case. If you are using this for your own purposes, you may wish to rewrite it using functions instead of large switch cases. The date function is used to convert the start and end parameters into ISO 8601 date format. That's the format jquery-week-calendar prefers, so we'll try to keep everything in that format. Visually, nothing appears to happen, but the data is actually being saved. To see what's being saved, create a new file named test.php, and use the var_dump function in it to examine the session data (view it in your browser): <?php session_start(); var_dump($_SESSION); ?> Here's an example from my test machine:
Read more
  • 0
  • 0
  • 8277

article-image-installation-and-configuration-oracle-soa-suite-11g-r1-part-1
Packt
19 Nov 2009
6 min read
Save for later

Installation and Configuration of Oracle SOA Suite 11g R1: Part 1

Packt
19 Nov 2009
6 min read
These instructions are Windows based but Linux users should have no difficulty adjusting them for their environment. Checking your installation If you already have SOA Suite and JDeveloper installed, confirm that you have the correct version and configuration by following the steps in the section below called Testing your installation. In addition, you may want to complete the items in the section called Additional actions. Finally, you must complete the section called Configuration to run a tutorial. What you will need and where to get it This installation requires 3 GB or more available memory. If you have less memory, try separating the installation of the database, the servers, and JDeveloper onto different machines. Memory and Disk Space requirements This installation requires 3 GB or more available memory. If you have less memory, try separating the installation of the database, the servers, and JDeveloper onto different machines. The installation process requires about 12 GB of disk space. After installation, you can delete the files used by installation to save about 4 GB. As you can see, you are installing a lot of software with a large memory and disk footprint. Running your disk defragmentation program now, before you start downloading and installing, can significantly improve install time as well as performance and disk space usage later on. Downloading files Download all the software to get started. In the following steps, save all downloaded files to c:stageSOA. This document assumes that path. If you save them somewhere else then make sure there are no spaces in your path and adjust accordingly when c:stageSOA is referenced in this document. Go to: http://www.oracle.com/technology/products/soa/soasuite/index.html, and download the following from SOA Suite 11g Release 1 (11.1.1.1.0) to c:stageSOA: WebLogic Server:wls1031_win32.exe Repository Creation Utility:ofm_rcu_win32_11.1.1.1.0_disk1_1of1.zip SOA Suite:ofm_soa_generic_11.1.1.1.0_disk1_1of1.zip JDeveloper Studio, base install:jdevstudio11111install.jar Unzip the SOA Suite ZIP file to c:stageSOA. Unzip the RCU ZIP file to c:stageSOA. Additional Files needed: Tutorial Files: In Chapter 3, you were directed to download the files needed for this tutorial. Do that now as some are used during installation. You can download the files from here:http://www.oracle.com/technology/products/soa/soasuite/11gthebook.html. Unzip the tutorial ZIP file to c:stageSOA. SOA Extension for JDeveloper: You will get this later using the JDeveloper update option. Oracle Service Bus: When you are ready to do the Oracle Service Bus (OSB) lab, you will download the install file to install OSB. Checking your database Having your database up and running is the most important pre-requisite for installing SOA Suite. Read the following bulleted requirements carefully to be sure you are ready to begin the SOA Suite installation: You need one of: Oracle XE Universal database version 10.2.0.1 Oracle 10g database version 10.2.0.4+ Oracle 11g database version 11.1.0.7+ You cannot use any other database version in 11gR1 (certification of additional databases is on the roadmap). Specifically, you cannot use XE Standard, it must be Universal. We have seen problems with installing XE when a full 10g database is already installed in the environment. The Windows registry sometimes gets the database file location confused. It is recommended to pick one or the other to avoid such issues. If you need to uninstall XE, make sure that you follow the instructions in Oracle Database Express Edition Installation Guide 10g  Release 2 (10.2) for Microsoft Windows Part Number B25143-03, Section 7, Deinstalling Oracle Database XE (http://download.oracle.com/docs/cd/B25329_01/doc/install.102/b25143/toc.htm). If you need to uninstall 10.2, be sure to follow the instructions in Oracle Database Installation Guide 10g Release 2 (10.2) for Microsoft Windows (32-Bit) Part Number B14316-04, Section 6, Removing Oracle Database Software(http://download.oracle.com/docs/cd/B19306_01/install.102/b14316/ deinstall.htm). Optional: Install OracleXEUniv.exe—recommended for a small footprint database. Make sure that you read step 1 above before installing. You can get XE from here: http://www.oracle.com/technology/products/database/ xe/index.html. When you are using XE, you will see a warning when you install the database schema that this database version is too old. You can safely ignore this warning as it applies only to production environments. If needed, configure Oracle XE Universal. When you are using Oracle XE, you must update database parameters if you have never done this for your database installation. You only have to do this once after installing. Set the processes parameter to >=200 using the following instructions. C:OracleMiddlewarehome_11gR1user_projectsdomains domain1binsetSOADomainEnv.cmdCODE 1sqlplus sys/welcome1@XE as sysdbaSQL> show parameter sessionSQL> show parameter processesSQL> alter system reset sessions scope=spfile sid='*';SQL> alter system set processes=200 scope=spfile;SQL> shutdown immediateSQL> startupSQL> show parameter sessionSQL> show parameter processes The shutdown command can take a few minutes and sometimes the shutdown/startup command fails. In that case, simply restart the XE service in the Control Panel | Administrative Tools | Services dialog after setting up your parameters. Checking your browser Oracle SOA Suite 11gR1 has specific browser version requirements. Enterprise Manager requires Firefox 3 or IE 7. Firefox 3—get a portable version, such as the one available from http://portableapps.com, if you want it to co-exist peacefully with your Firefox 2 installation. Firefox 2 and IE 6 are not supported and will not work. BAM requires IE 7. Beware of certain IE 7 plugins that can create conflicts (a few search plugins have proved to be incompatible with BAM). IE 8 is not supported with 11gR1 (but is on the roadmap). IE 6 has a few issues and Firefox will not work with BAM Studio. Checking your JDK If you are going to install WebLogic server and JDeveloper on the same machine, you will use the JDK from WebLogic for JDeveloper too. However, if you are going to install on two machines, you need Java 1.6 update 11 JDK for JDeveloper. JDK 1.6 update 11—from the Sun downloads page: http://java.sun.com/products/archive/ You must use Java 1.6 update 11. Update 12 does not work.
Read more
  • 0
  • 0
  • 10880
Modal Close icon
Modal Close icon