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-getting-your-apex-components-logic-right
Packt
09 Oct 2009
10 min read
Save for later

Getting Your APEX Components Logic Right

Packt
09 Oct 2009
10 min read
Pre-generation editing After reading this article, we will understand our project a lot better. Also, to a certain level, we will be able control the way our application will be generated. Generation is often performed more than once as you refine the definitions and settings between iterations. In this article we will learn a lot of ways to edit the project in order to generate optimally. But we must understand that we will not cover all the exceptions in the generation process. If we want to do a real Forms to APEX conversion project, it will be very wise to carefully read the help texts in the Migration Documentation provided by Oracle in every APEX instance—especially the appendix called Oracle Forms Generation Capabilities and Workarounds, which will help you to understand the choices that can be made in the generation process. The information in these migration help texts tells us how the different components in Oracle Forms will be converted in APEX and how to implement business logic in the APEX application. For example, when we take a look at the Block to Page Region Mappings, we learn how APEX converts certain blocks to APEX regions during conversion. Investigating When we take a look at our conversion project, we must understand what will be generated. In case of generation, the most important parts are the blocks on our Forms modules. These are, quite literally, the building blocks our pages in APEX will be based upon. Of course, we have our program units, triggers, and much more; but the pages that are defined in the APEX application (which we put in production after the project is finished) will be based on Blocks, Reports, and Menus. This is why we need to adjust them before we generate anything. This might seem like a small part of the project as we look at the count of all the components in our project page, but that doesn't make it less important. We can't adjust reports as they are defined by the query that they are built upon, but we can alter the blocks. That's why we focus on those components first. Data blocks The building blocks of our APEX pages are the blocks and, of course, the reports. The blocks we can generate in our project are the ones that are based on database block. Non-database blocks such as those that hold menus and buttons are not generated by default, as they will be generated as blank pages. In the block overview page, we get the basic information about the blocks in our project. The way the blocks will be generated is determined by APEX based on the contents, the number of items on the block, and, most importantly, the number of records displayed. For further details on the generation rules, refer to the Migration Guide—Appendix A: Forms Generation Capabilities and Workarounds. In the Blocks overview page in our conversion project, we notice that not all the blocks are included. In other words, they aren't checked to be included in the project. This is because they are not oriented from a database block. To include or exclude a block during generation, we need to check or uncheck the specific block. Don't confuse this with the applicability of a block. We also might notice that some of the blocks are already set to complete. In our example we see that the S_CUSTOMER1 and S_CUSTOMER blocks are set to complete. If we take a look inside these components and check the annotations, they are indeed set to complete. There's also a note set for us. As we see in the following screenshot, it states Incorporating Enhanced Query: The Enhanced Query is something that we will use later in this article. But beware of the statement that a component is Complete as we will see that we might want to alter the query on which the customer's block is based. If we look at a block that is not yet set to complete in the overview page (such as the Orders block) and we look at the Application Express Page Query region in the details screen, we see that only Original Query is present. This is the query that is in the original Forms XML file we uploaded earlier. Although we have the Original Query present in our page, we can also alter it and customize the query on which this block is based. But this will be done later in the article. In this way, we have a better control over the way we will generate our application. We can't alter this query as it is to be implemented as a Master-Detail Form. Block items Each block contains a number of items. These items define the fields in our application and are derived from our Forms XML files. In the block details pages, we can find the details of the items on the particular block as well. Here we can see the most basic information about the items, namely their Type, Prompt, Column Name, and the Triggers on that particular item. We can also see the Name of the item if it is a Database Item and if the item is complete or not, and whether or not it is Applicable. When a block is set to complete, it is assumed that we have all the information required about the items, as we see in the example shown here: But there are also cases where we don't get all the information about the items we want. In our case, we might want to customize the query the block is based on or define the items further. We will cover this later in the article. In the above screenshot we notice that for all the items the Column Name is not known. This is an indication that the items will not be generated properly and we need to take a further look into the query and, maybe, some of the triggers. When we want to alter the completeness and applicability of the items in our block, there's a great functionality available on the upper-right of the Blocks Details page. In the Block Tasks section, we find a link that states: Set All Block Items Completeness and Applicability. This function is used to make bulk changes in the items in the block we are in. It can be useful to change the completeness of all items when we are not sure what more needs to be done. To set the completeness or the applicability with a bulk change on all the items, we click on the link in the Block Tasks region and this takes us to the following screen: In the Set Block Item & Trigger Status page we can select the Attribute (Items, Block Triggers, or Item Triggers), the Set Tracking Attribute (Complete or Applicable), and the Set Value (Yes or No). To make changes, set the correct attribute, tracking attribute, and value, and then click on Apply Changes. Original versus Enhanced Query As mentioned earlier, we can encounter both Original and Enhanced Queries in the blocks of our Forms. The Original Query is taken from the XML file directly as it is stated in the source of the block we are looking at. So where does the Enhanced Query originate from? This is one of the automatically generated parts of the Forms Conversion tool in APEX. If a block contains a POST QUERY trigger, the Forms Conversion tool generates an Enhanced Query for us. In the following screenshot, we see both the Enhanced Query and the Original Query in the S_CUSTOMER block. We can clearly notice the additional lines at the bottom of the Enhanced Query. The query in the Enhanced Query section still looks a lot like the one in the Original Query section, but is slightly altered. The code is generated automatically by taking the code from both the Original Query and POST QUERY triggers on this block. Please note that the query is automatically generated by APEX by adding a WHERE clause to the SQL query. This means that we will still need to check it and, probably, optimize it to work properly. The following screenshot shows us the POST QUERY trigger. Notice that it's set to both applicable and complete. This is because the code is now embedded in the enhanced query and so the trigger is taken care of for our project. Triggers Besides items, even blocks contain triggers. These define the actions in our blocks and are, therefore, equally important. Most of the triggers are very Forms-specific, but it's nice to be the judge of that ourselves. In the Orders Block, we have the Block Triggers region that contains the triggers in our orders block. The region tells us the name, applicability, and completeness. It gives us a snippet of the code inside the trigger and tells us the level it is set to (ITEM or BLOCK). A lot of the triggers in our project need to be implemented post-generation, which will be discussed later in this article. But as mentioned above, there is one trigger that we need in the pre-generation stage of our project. This is the POST-QUERY trigger. In this example, the applicability in the orders block is set to No. This is also the reason why we have no Enhanced Query to choose from in this block. The reasons behind setting the trigger to not applicable can be many, and you can learn more about the reasons if you read the migration help texts carefully. We probably want to change the applicability of the trigger ourselves because the POST-QUERY trigger contains some necessary information on how we need to define our block. If we click on the edit link (the pencil icon) for the POST-QUERY trigger, we can alter the applicability. Set the value for Applicable to Yes and click on Apply Changes. This will take us back to the Block Details screen. In the Triggers region, we can see that the applicability of the POST QUERY trigger is now set to Yes. Now if we scroll up to the Application Express Page Query region, we can also see that the Enhanced Query is now in place. As shown in the following screenshot, we can see that we automatically generated an extended version of the Original Query, embedding the logic in the Post Query trigger. For the developers among us, we can see that the query produced by the conversion tool in APEX doesn't make the query very optimal. We can rewrite the query in the Custom Query section, which we will describe later in this article. We are able to set the values for our triggers in the same way we used to set the applicability and completeness of the items in our blocks. In the upper-right corner of our Block Details screen, we find the Block Tasks region. Here we find the link to the tasks for items as well as triggers. Click on the Set All Block Triggers Completeness and Applicability to navigate to the screen where we can set the values. In the Attribute section, we can choose from both the block level triggers as well as the item level triggers. We can't adjust them all at once, so we may need to adjust them twice.  
Read more
  • 0
  • 0
  • 2652

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

Programmatically Creating SSRS Report in Microsoft SQL Server 2008

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

article-image-developing-post-types-plugin-wordpress
Packt
09 Oct 2009
7 min read
Save for later

Developing Post Types Plugin with WordPress

Packt
09 Oct 2009
7 min read
And you will do all of these by developing a Post Types plugin that provide pre-defined post templates to add a photo or a link quickly to your blog. The concepts you will learn in this article will help you discover the not so obvious capabilities of the WordPress platform that allows you to transform it into software—capable of handling much more than just a blog. Handling localization Localization is an important part of WordPress development as not everyone using WordPress speaks English (WordPress comes in different languages too). Localization involves just a small amount of the extra work on your side, since the translation itself is usually done by volunteers (people who like and use your plugin). You only need to provide some base files for translation, and don't be surprised when you start getting translated files sent to your inbox. WordPress uses the GNU gettext localization framework, which is a standardized method of managing translations, and we will make use of it in our plugin. Time for action – Create plugin and add localization We will start by defining our plugin as usual, and then add localization support. Create a new folder called post-types. Create a new post-types.php file with the following content: <?php// pluginname Post Types// shortname PostTypes// dashname post-types/*Plugin Name: Post TypesVersion: 0.1Plugin URI: http://www.prelovac.com/vladimir/wordpress-plugins/post-typesAuthor: Vladimir PrelovacAuthor URI: http://www.prelovac.com/vladimirDescription: Provides pre-defined post templates to quickly add a photo or a link to your blog*/// Avoid name collisions.if ( !class_exists('PostTypes') ) :class PostTypes{ // localization domain var $plugin_domain='PostTypes'; // Initialize the plugin function PostTypes() { global $wp_version; $exit_msg='Post Types requires WordPress 2.5 or newer. <a href="http://codex.wordpress.org/Upgrading_WordPress"> Please update!</a>'; if (version_compare($wp_version,"2.5","<")) { exit ($exit_msg); } } // Set up default values function install() { }}endif;if ( class_exists('PostTypes') ) : $PostTypes = new PostTypes(); if (isset($PostTypes)) { register_activation_hook( __FILE__, array(&$PostTypes, 'install') ); } endif; Adding localization is fairly simple. First we need to add a function to our class that will load the translation file: // Localization supportfunction handle_load_domain(){ // get current language $locale = get_locale(); // locate translation file $mofile = WP_PLUGIN_DIR.'/'.plugin_basename(dirname (__FILE__)).'/lang/' . $this->plugin_domain . '-' . $locale . '.mo'; // load translation load_textdomain($this->plugin_domain, $mofile);} Since loading the file takes resources, we will load it only when the translation is actually needed by checking the current page ($pagenow) and the list of pages pages where we need translations ($local_pages array): // Initialize the pluginfunction PostTypes(){ global $wp_version, $pagenow; // pages where our plugin needs translation $local_pages=array('plugins.php'); if (in_array($pagenow, $local_pages)) $this->handle_load_domain(); $exit_msg='Post Types requires WordPress 2.5 or newer. <a href="http://codex.wordpress.org/Upgrading_WordPress"> Please update!</a>'; Finally, to use the available translations, we only need to enclose our text in the __() function: $this->handle_load_domain();$exit_msg=__('Post Types requires WordPress 2.5 or newer.<a href="http://codex.wordpress.org/Upgrading_WordPress">Please update!</a>', $this->plugin_domain);if (version_compare($wp_version,"2.5","<")) What just happened? We have added localization support to our plugin by using the provided localization functions provided by WordPress. Currently, we have only localized the error message for WordPress version checking: $exit_msg=__('Post Types requires WordPress 2.5 or newer.<a href="http://codex.wordpress.org/Upgrading_WordPress">Please update!</a>', $this->plugin_domain); We have done that by enclosing the text in the __() function, which takes the text as localized, and enclosing our unique localization domain or context within the WordPress localization files. To load localization, we created a handle_load_domain function. The way it works is to first get the current language in use by using the get_locale() function: // Localization supportfunction handle_load_domain(){ // get current language $locale = get_locale(); Then it creates the language file name by adding together the plugin dir, plugin folder, and the lang folder where we will keep the translations. The file name is derived from the locale, and the *.mo language file extension: // locate translation file$mofile = WP_PLUGIN_DIR.'/'.plugin_basename(dirname(__FILE__)).'/lang/' . $this->plugin_domain .'-' . $locale . '.mo'; Finally, the localization file is loaded using the load_textdomain() function, taking our text domain and .mo file as parameters. // load translationload_textdomain($this->plugin_domain, $mofile); Optimizing localization usage The translation file needs to be loaded as the first thing in the plugin—before you output any messages. So we have placed it as the first thing in the plugin constructor. Since loading the translation file occurs at the beginning of the constructor, which is executed every time, it is a good idea to select only the pages where the translation will be needed in order to preserve resources. WordPress provides the global variable, $pagenow, which holds the name of the current page in use. We can check this variable to find out if we are on a page of interest. In the case of plugin activation error message, we want to check if we are on the plugins page defined as plugins.php in WordPress: // pages where our plugin needs translation$local_pages=array('plugins.php');if (in_array($pagenow, $local_pages)) $this->handle_load_domain(); You can optimize this further by querying the page parameter, if it exists, as this will—in most cases—point precisely to the usage of your page (plugins.php?page=photo): if ($_GET['page']=='photo') Optimizing the usage of the translation file is not required; it's just a matter of generally loading only what you need in order to speed up the whole system. How does localization work? For localization to work, you need to provide .po and .mo files with your plugins. These files are created by using external tools such as PoEdit. These tools output the compiled translation file, which can be then loaded by using the load_textdomain() function. This function accepts a language domain name and a path to the file. In order to use translated messages, you can use the __($text, $domain) and _e($text, $domain) functions. The _e() function is just an equivalent of echo __(); These functions accept two parameters, the first being the desired text, and the second, the language domain where the message will be looked for. If no translation was found, the text is just printed out as it is. This means that you can always safely use these functions, even if you do not provide any translation files. This will prepare the plugin for future translation. Quick reference$pagenow: A global variable holding the name of the currently displayed page within WordPress.get_locale(): A function which gets the currently selected language.load_textdomain(domain, filepath): This function loads the localization file and adds it to the specified language domain identifier._(); _e(): These functions are used to find the output text using a given language domain.More information about WordPress localization is available at: http://codex.wordpress.org/Translating_WordPress.
Read more
  • 0
  • 0
  • 4189

article-image-preparing-your-forms-conversion-using-oracle-application-express-apex
Packt
09 Oct 2009
9 min read
Save for later

Preparing Your Forms Conversion Using Oracle Application Express (APEX)

Packt
09 Oct 2009
9 min read
When we are participating in a Forms Conversion project, it means we take the source files of our application, turn them into XML files, and upload them into the Forms Conversion part of APEX. This article describes what we do before uploading the XML files and starting our actual Forms Conversion project. Get your stuff! When we talk about source files, it would come in very handy if we got all the right versions of these files. In order to do the Conversion project, we need the same components that are used in the production environment. For these components, we have to get the source files of the components we want to convert. This means we have no use of the runtime files (Oracle Forms runtime files have the FMX extension). In other words, for Forms components we don't need the FMX files, but the FMB source files. These are a few ground rules we have to take into account: We need to make sure that there's no more development on the components we are about to use in our Conversion project. This is because we are now going to freeze our sources and new developments won't be taken into the Conversion project at all. So there will be no changes in our project. Put all the source files in a safe place. In other words, copy the latest version of your files into a new directory to which only you, and perhaps your teammates, have access. If the development team of your organization is using Oracle Designer for the development of its applications, it would be a good idea to generate all the modules from scratch. You would like to use the source on which the runtime files were created only if there are post-generation adjustments to be made in the modules. We need the following files for our Conversion project: Forms Modules: With the FMB extension Object Libraries: With the OLB extension Forms Menus: With the MMB extension PL/SQL Libraries: With the PLL extension Report Files: With the RDF, REX, or JSP extensions When we take these source files, we will be able to create all the necessary XML files that we need for the Forms Conversion project. Creating XML files To create XML files, we need three parts of the Oracle Developer Suite. All of these parts come with a normal 10g or 9i installation of the Developer Suite. These three parts are the Forms Builder, the Reports Builder, and the Forms2XML conversion tool. The Forms2XML conversion tool is the most extensive to understand and is used to create XML files from Form modules, Object Libraries, and Forms Menus. So, we will first discuss the possibilities of this tool. The Forms2XML conversion tool This tool can be used both from the command line as well as a Java applet. As the command line gives us all the possibilities we need and is as easy as a Java applet, we will only use the command-line possibilities. The frmf2xml command comes with some options. The following syntax is used while converting the Forms Modules, the Object Libraries, and the Forms Menus to an XML structure: frmf2xml [option] file [file] In other words, we follow these steps: We first type frmf2xml. Alternatively, we give one of the options with it. We tell the command which file we want to convert, and we have the option to address more than one file for the conversion to XML. We probably want to give the OVERWRITE=YES option with our command. This property ensures that the newly created XML file will overwrite the one with the same name in the directory where we are working. If another file with the same name already exists in this directory and we don't give the OVERWRITE option the value YES (the default is NO), the file will not be generated, as we see in the following screenshot: If there are any images used in modules (Forms or Object Libraries), the Forms2XML tool will refer to the image in the XML file created, and that file will create a TIF file of the image in the directory. The XML files that are created will be stored in the same directory from which we call the command. It will use the following syntax for the name of the XML file: formname.fmb will become formname_fmb.xml libraryname.olb will become libraryname_olb.xml menuname.mmb will become menuname_mmb.xml To convert the .FMB, OLB and, MMB files to XML, we need to do the following steps in the command prompt: Forms Modules The following steps are done in order to convert the .FMB file to XML: We will change the working directory to the directory that has the FMB file. In my example, I have stored all the files in a directory called summit directly under the C drive, like this: C:>cd C:summit Now, we can call the frmf2xml command to convert one of our Forms Modules to an XML file. In this example, we convert the orders.fmb module: C:summit>frmf2xml OVERWRITE=YES orders.fmb As we see in the following screenshot, this command creates an XML file called orders_fmb.xml in the working directory: Object Libraries To convert the .OLB file to XML, the following steps are needed: We first change the working directory to the directory that the OLB file is in. It's done like this: C:>cd C:summit Now we can call the frmf2xml command to convert one of our Object Libraries to an XML file. In this example, we convert the Form_Builder_II.olb library as follows: C:summit>frmf2xml OVERWRITE=YES Form_Builder_II.olb As we see in the following screenshot, the command creates an XML file calledForm_Builder_II_olb.xml and two images as .tif files in the working directory: Forms Menus To convert the MMB file to XML, we follow these steps: We change the working directory to the directory that the .MMB file is in, like this: C:>cd C:summit Now we can call the frmf2xml command to convert one of our Forms Menus to an XML file. In this example we convert the customers.mmb menu: C:summit>frmf2xml OVERWRITE=YES customers.mmb As we can see in the following screenshot, the command creates an XML file called customers_mmb.xml in the working directory: Report Files In our example, we will convert the Customers Report from a RDF file to an XML file. To do this, we follow the steps given here: We need to open the Employees.rdf file with Reports Builder. Open Reports Builder from your Start menu. If Reports Builder is opened, we need to cancel the wizard that asks us if we want to create a new report. After this we use Ctrl+O to open the Report File (or in the menu, File | Open) which we want to convert to XML as we see in the following screenshot: After this we use Shift+Ctrl+S (or in the File | Save As menu) to save the Report. We choose that we want to save the report as a Reports XML (*.xml) file and we click on the Save button as shown in the following screenshot: PL/SQL Libraries To convert PL/SQL Libraries to an XML format, it's easiest to use the convert command that comes with the Report Builder. With this command called rwconverter, we define the source type, call the source, and define the destination type and the destination. In this way, we have control over the way we need to convert the original .pll file to a .pld flat file that we can upload into the APEX Forms converter. It is possible to convert the PL/SQL Libraries with the convert option in Forms Builder, but, personally, I think this option works better. The rwconverter command has a few parameters we give with it to execute. They are given as follows: stype: This is the type of source file we need to convert. In our situation, this will be a .pll file and so the value we need to set is pllfile. source: This is the name of the source file, including the extension. In our case, it is wizard.pll. dtype: This is the file type we want to convert our source file to. In our case, it is a .pld file and so the value becomes pldfile. dest: This is the name, including the extension, of the destination file. In our case, it is wizard.pld. In our example, we use the wizard.pll file that's in our summit files directory. This PL/SQL Library that contains .pll files is normally used to create a PL/SQL Library in the Oracle Database. But this time, we will use it to create a .pld flat file that we will upload to APEX. First, we change the directory to work directory which has the original .pll file. In our case, the summit directory directly under the C drive, shown as follows: C:>cd C:summit After this, we call rwconverter in the command prompt as shown here: C:summit> rwconverter stype=pllfile source=wizard.pll dtype=pldfile dest=wizard.pld When you press the Enter key, a screen will open that is used to do the conversion. We will see that the types and names of the files are the same as we entered them in the command line. We need to click on the OK button to convert the file from .pll to .pld. The conversion may take a few seconds, but when the file has been converted we will see a confirmation that the conversion was successful. After this, we can look in the C:summit directory and we will see that a file wizard.pld is created.
Read more
  • 0
  • 0
  • 11837

article-image-using-aspnet-controls-sharepoint
Packt
09 Oct 2009
4 min read
Save for later

Using ASP.NET Controls in SharePoint

Packt
09 Oct 2009
4 min read
ASP.NET controls We can view the controls that are available by opening up the Toolbox task pane and maximizing the ASP.NET Controls option. Within this option, there are six categories of controls. Of these, we can ignore the WebParts option because that is simply a link to the Web Parts task pane. It should be noted that it is not possible to use ASP.NET WebParts in SharePoint 2007 sites. It is, however, possible for developers to create their new user controls as SmartParts (see http://www.codeplex.com/smartpart) to allow them to be included within WSS and MOSS sites. The five remaining categories are: Standard controls This contains a large number of controls. Most of these are simple, for example: The Image control, which displays a picture. The Label control, which displays text. The Hyperlink control, which we will use to link from our homepage shortly. In addition, we have standard controls that are somewhat more exciting: The FileUpload control allows files to be uploaded to the server from the user's computer. The Wizard control allows a multi-step form to be added to our site. At each step of the wizard, the user is asked for different information. The Xml control allows data from an XML document to be displayed on our page (although you may find it easier to use a Data View to display the contents of your XML file). The Calendar control, which we will also add to our site later in this article. Data controls The data controls allow us to connect to various different data sources, display the results on our page, and update the data in the source. Because SharePoint already provides us with access to data sources in the Data Source Library task pane, we can safely ignore these controls. Validation controls The validation controls allow us to validate information input by the user. We will see this in practice towards the end of the article, when we add validation to a form. Navigation controls The navigation controls provide us with three different methods of helping users navigate our site. The Menu and TreeView controls would allow users to browse to a particular page, while the SiteMapPath control displays breadcrumbs that show their position within the page hierarchy. We will see an example of the Menu control later in this article. Login controls The login controls allow us to take advantage of ASP.NET's extensive membership provider system. The benefit of this is that we no longer need to manually create all the elements required by a login system (i.e. registration, login, password reminder, etc.). We will also look at this in detail in this article. Further information about virtually all of the ASP.NET server controls, including examples and code snippets, is available in the ASP.NET Control Reference in the .NET Framework SDK, which is available at. Adding a simple control In this article, we will be using various server controls in our pages. We will start by adding one of the simplest controls to our homepage: Open the share site in SharePoint Designer. Open the default.aspx page in Design view. Make sure that the Standard controls are visible in the Toolbox task pane. Click on the HyperLink control and drag it onto our page. Right-click on the control that we have just placed and select Properties from the shortcut menu. This will open the Tag Properties task pane to the left of our design window. Type View Orders Graph into the Text field in the Tag Properties task pane. Click on the ellipsis to the right of the NavigateUrl field and select orders.aspx from the list of pages. Finally, save the page. The following image shows the Properties shortcut menu that we see as we work through this process: Now, when we open http://olmec/share/ in our browser, we see that the default page links to the Order Graphs.
Read more
  • 0
  • 0
  • 8012

article-image-migrating-ms-sql-server-2008-enterprisedb
Packt
09 Oct 2009
2 min read
Save for later

Migrating from MS SQL Server 2008 to EnterpriseDB

Packt
09 Oct 2009
2 min read
With many database vendor products in the market and data intensive applications using them, it is often required to port the application to use the data or, migrate the data so that the application can use it. Migration of data is therefore one of the realities of the IT Industry. Some of the author's previous articles on migration can be found at this link. You may find more if you do a search on his blog site. Table to be migrated in SQL Server 2008 The following figure shows the Categories table in the Microsoft SQL Server 2008's Management Studio that will be migrated to the Postgres database. Creating a database in Postgres Studio Right click Databases node in the Advanced Server 8.3 and click on New Database... menu as shown. The New Database... window gets displayed as shown. Create an empty database PGNorthwind in Postgres Studio by entering information shown in the next figure. This creates a new database and related objects as shown in the next figure. This also creates the script in the Properties pane as shown. Review the properties. The database may be dropped using the Drop Database statement. Starting the Migration Studio Click on Start | All Programs | Postgres Advanced Server 8.3 to display the drop-down menu as shown. Click on the Migration Studio drop-down item. This opens the EnterpriseDB Migration Studio 8.3(Migration Studio for the rest of the tutorial) with a modal form with the title Edit Server Advanced Server 8.3(localhost:5432). This is the server we installed in the previous tutorial. Enter the User Name and Password and click OK. You will get a message displaying the result as shown in the next figure. Click OK to both the open windows and the EnterpriseDB Migration Studio shows up as shown here. Click on the File in the main menu on the Migration Studio and pick Add Server. This brings up the Add Server window with a default as shown.
Read more
  • 0
  • 0
  • 2939
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-searching-data-using-phpmyadmin-and-mysql
Packt
09 Oct 2009
4 min read
Save for later

Searching Data using phpMyAdmin and MySQL

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

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

Drupal 6 Content Construction Kit (CCK)

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

article-image-looking-apache-axis2
Packt
09 Oct 2009
11 min read
Save for later

Looking into Apache Axis2

Packt
09 Oct 2009
11 min read
(For more resources on Axis2, see here.) Axis2 Architecture Axis2 is built upon a modular architecture that consists of core modules and non-core modules. The core engine is said to be a pure SOAP processing engine (there is not any JAX-PRC concept burnt into the core). Every message coming into the system has to be transformed into a SOAP message before it is handed over to the core engine. An incoming message can either be a SOAP message or a non-SOAP message (REST JSON or JMX). But at the transport level, it will be converted into a SOAP message. When Axis2 was designed, the following key rules were incorporated into the architecture. These rules were mainly applied to achieve a highly flexible and extensible SOAP processing engine: Separation of logic and state to provide a stateless processing mechanism. (This is because Web Services are stateless.) A single information model in order to enable the system to suspend and resume. Ability to extend support to newer Web Service specifications with minimal changes made to the core architecture. The figure below shows all the key components in Axis2 architecture (including core components as well as non-core components). Core Modules XML Processing Model : Managing or processing the SOAP message is the most diffcult part of the execution of a message. The efficiency of message processing is the single most important factor that decides the performance of the entire system. Axis1 uses DOM as its message representation mechanism. However, Axis2 introduced a fresh XML InfoSet-based representation for SOAP messages. It is known as AXIOM (AXIs Object Model). AXIOM encapsulates the complexities of efficient XML processing within the implementation. SOAP Processing Model :  This model involves the processing of an incoming SOAP message. The model defines the different stages (phases) that the execution will walk through. The user can then extend the processing model in specific places. Information Model :  This keeps both static and dynamic states and has the logic to process them. The information model consists of two hierarchies to keep static and run-time information separate. Service life cycle and service session management are two objectives in the information model. Deployment Model :  The deployment model allows the user to easily deploy the services, configure the transports, and extend the SOAP Processing Model. It also introduces newer deployment mechanisms in order to handle hot deployment, hot updates, and J2EE-style deployment. Client API : This provides a convenient API for users to interact with Web Services using Axis2. The API consists of two sub-APIs, for average and advanced users. Axis2 default implementation supports all the eight MEPs (Message Exchange Patterns) defined in WSDL 2.0. The API also allows easy extension to support custom MEPs. Transports :  Axis2 defines a transport framework that allows the user to use and expose the same service in multiple transports. The transports fit into specific places in the SOAP processing model. The implementation, by default, provides a few common transports (HTTP, SMTP, JMX, TCP and so on). However, the user can write or plug-in custom transports, if needed. XML Processing Model Axis2 is built on a completely new architecture as compared to Axis 1.x. One of the key reasons for introducing Axis2 was to have a better, and an efficient XML processing model. Axis 1.x used DOM as its XML representation mechanism, which required the complete object hierarchy (corresponding to incoming message) to be kept in memory. This will not be a problem for a message of small size. But when it comes to a message of large size, it becomes an issue. To overcome this problem, Axis2 has introduced a new XML representation. AXIOM (AXIs Object Model) forms the basis of the XML representation for every SOAP-based message in Axis2. The advantage of AXIOM over other XML InfoSet representations is that it is based on the PULL parser technique, whereas most others are based on the PUSH parser technique. The main advantage of PULL over PUSH is that in the PULL technique, the invoker has full control over the parser and it can request the next event and act upon that, whereas in case of PUSH, the parser has limited control and delegates most of the functionality to handlers that respond to the events that are fired during its processing of the document. Since AXIOM is based on the PULL parser technique, it has on-demand-building capability whereby it will build an object model only if it is asked to do so. If required, one can directly access the underlying PULL parser from AXIOM, and use that rather than build an OM (Object Model). SOAP Processing Model Sending and receiving SOAP messages can be considered two of the key jobs of the SOAP-processing engine. The architecture in Axis2 provides two Pipes ('Flows'), in order to perform two basic actions. The AxisEngine or driver of Axis2 defines two methods, send() and receive() to implement these two Pipes. The two pipes are namedInFlow and OutFlow.   The complex Message Exchange Patterns (MEPs) are constructed by combining these two types of pipes. It should be noted that in addition to these two pipes there are two other pipes as well, and those two help in handling incoming Fault messages and sending a Fault message. Extensibility of the SOAP processing model is provided through handlers. When a SOAP message is being processed, the handlers that are registered will be executed. The handlers can be registered in global, service, or in operation scopes, and the final handler chain is calculated by combining the handlers from all the scopes. The handlers act as interceptors, and they process parts of the SOAP message and provide the quality of service features (a good example of quality of service is security or reliability). Usually handlers work on the SOAP headers; but they may access or change the SOAP body as well. The concept of a flow is very simple and it constitutes a series of phases wherein a phase refers to a collection of handlers. Depending on the MEP for a given method invocation, the number of flows associated with it may vary. In the case of an in-only MEP, the corresponding method invocation has only one pipe, that is, the message will only go through the in pipe (inflow). On the other hand, in the case of in-out MEP, the message will go through two pipes, that is the in pipe (inflow) and the out pipe (outflow). When a SOAP message is being sent, an OutFlow begins. The OutFlow invokes the handlers and ends with a Transport Sender that sends the SOAP message to the target endpoint. The SOAP message is received by a Transport Receiver at the target endpoint, which reads the SOAP message and starts the InFlow. The InFlow consists of handlers and ends with the Message Receiver, which handles the actual business logic invocation. A phase is a logical collection of one or more handlers, and sometimes a phase itself acts as a handler. Axis2 introduced the phase concept as an easy way of extending core functionalities. In Axis 1.x, we need to change the global configuration files if we want to add a handler into a handler chain. But Axis2 makes it easier by using the concept of phases and phase rules. Phase rules specify how a given set of handlers, inside a particular phase, are ordered. The figure below illustrates a flow and its phases. If the message has gone through the execution chain without having any problem, then the engine will hand over the message to the message receiver in order to do the business logic invocation, After this, it is up to the message receiver to invoke the service and send the response, if necessary. The figure below shows how the Message Receiver fits into the execution chain. The two pipes do not differentiate between the server and the client. The SOAP processing model handles the complexity and provides two abstract pipes to the user. The different areas or the stages of the pipes are named 'phases' in Axis2. A handler always runs inside a phase, and the phase provides a mechanism to specify the ordering of handlers. Both pipes have built-in phases, and both define the areas for User Phases, which can be defined by the user, as well. Information Model As  shown  in  the figure below, the information model consists of two hierarchies: Description hierarchy and Context hierarchy. The Description hierarchy represents the static data that may come from different deployment descriptors. If hot deployment is turned off, then the description hierarchy is not likely to change. If hot deployment is turned on, then we can deploy the service while the system is up and running. In this case, the description hierarchy is updated with the corresponding data of the service. The context hierarchy keeps run-time data. Unlike the description hierarchy, the context hierarchy keeps on changing when the server starts receiving messages. These two hierarchies create a model that provides the ability to search for key value pairs. When the values are to be searched for at a given level, they are searched while moving up the hierarchy until a match is found. In the resulting model, the lower levels override the values present in the upper levels. For example, when a value has been searched for in the Message Context and is not found, then it would be searched in the Operation Context, and so on. The search is first done up the hierarchy, and if the starting point is a Context then it would search for in the Description hierarchy as well. This allows the user to declare and override values, with the result being a very flexible configuration model. The flexibility could be the Achilles' heel of the system, as the search is expensive, especially for something that does not exist. Deployment Model The previous versions of Axis failed to address the usability factor involved in the deployment of a Web Service. This was due to the fact that Axis 1.x was released mainly to prove the Web Service concepts. Therefore in Axis 1.x, the user has to manually invoke the admin client and update the server classpath. Then, you need to restart the server in order to apply the changes. This burdensome deployment model was a definite barrier for beginners. Axis2 is engineered to overcome this drawback, and provide a flexible, user-friendly, easily configurable deployment model. Axis2 deployment introduced a J2EE-like deployment mechanism, wherein the developer can bundle all the class files, library files, resources files, and configuration fi  les together as an archive file, and drop it in a specified location in the file system. The concept of hot deployment and hot update is not a new technical paradigm, particularly for the Web Service platform. But in the case of Apache Axis, it is a new feature. Therefore, when Axis2 was developed, hot deployment features were added to the feature list. Hot deployment : This refers to the capability to deploy services while the system is up and running. In a real time system or in a business environment, the availability of the system is very important. If the processing of the system is slow, even for a moment, then the loss might be substantial and it may affect the viability of the business. In the meanwhile, it is required to add new service to the system. If this can be done without needing to shut down the servers, it will be a great achievement. Axis2 addresses this issue and provides a Web Service hot deployment ability, wherein we need not shut down the system to deploy a new Web Service. All that needs to be done is to drop the required Web Service archive into the services directory in the repository. The deployment model will automatically deploy the service and make it available. Hot update : This refers to the ability to make changes to an existing Web Service without even shutting down the system. This is an essential feature, which is best suited to use in a testing environment. It is not advisable to use hot updates in a real-time system, because a hot update could lead a system into an unknown state. Additionally, there is the possibility of loosening the existing service data of that service. To prevent this, Axis2 comes with the hot update parameter set to FALSE by default.
Read more
  • 0
  • 0
  • 3114

article-image-file-sharing-grails
Packt
09 Oct 2009
7 min read
Save for later

File Sharing in Grails

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

Search Engine Optimization in WordPress-part2

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

article-image-seam-data-validation
Packt
09 Oct 2009
8 min read
Save for later

Seam Data Validation

Packt
09 Oct 2009
8 min read
Data validation In order to perform consistent data validation, we would ideally want to perform all data validation within our data model. We want to perform data validation in our data model so that we can then keep all of the validation code in one place, which should then make it easier to keep it up-to-date if we ever change our minds about allowable data values. Seam makes extensive use of the Hibernate validation tools to perform validation of our domain model. The Hibernate validation tools grew from the Hibernate project (http://www.hibernate.org) to allow the validation of entities before they are persisted to the database. To use the Hibernate validation tools in an application, we need to add hibernate-validator.jar into the application's class path, after which we can use annotations to define the validation that we want to use for our data model. Let's look at a few validations that we can add to our sample Seam Calculator application. In order to implement data validation with Seam, we need to apply annotations either to the member variables in a class or to the getter of the member variables. It's good practice to always apply these annotations to the same place in a class. Hence, throughout this article, we will always apply our annotation to the getter methods within classes. In our sample application, we are allowing numeric values to be entered via edit boxes on a JSF form. To perform data validation against these inputs, there are a few annotations that can help us. Annotation Description @Min The @Min annotation allows a minimum value for a numeric variable to be specified. An error message to be displayed if the variable's value is less than the specified minimum can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be greater than or equal to ...). @Min(value=0, message="...") @Max The @Max annotation allows a maximum value for a numeric variable to be specified. An error message to be displayed if the variable's value is greater than the specified maximum can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be less than or equal to ...). @Max(Value=100, message="...") @Range The @Range annotation allows a numeric range-that is, both minimum and maximum values-to be specified for a variable. An error message to be displayed if the variable's value is outside the specified range can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be between ... and ...). @Range(min=0, max=10, message="...") At this point, you may be wondering why we need to have an @Range validator, when by combining the @Min and @Max validators, we can get a similar effect. If you want a different error message to be displayed when a variable is set above its maximum value as compared to the error message that is displayed when it is set below its minimum value, then the @Min and @Max annotations should be used. If you are happy with the same error message being displayed when a variable is set outside its minimum or maximum values, then the @Range validator should be used. Effectively, the @Min and @Max validators are providing a finer level of error message provision than the @Range validator. The following code sample shows how these annotations can be applied to a sample application, to add basic data validation to our user inputs. package com.davidsalter.seamcalculator; import java.io.Serializable; import org.jboss.seam.annotations.Name; import org.jboss.seam.faces.FacesMessages; import org.hibernate.validator.Max;import org.hibernate.validator.Min;import org.hibernate.validator.Range; @Name("calculator") public class Calculator implements Serializable { private double value1; private double value2; private double answer; @Min(value=0) @Max(value=100) public double getValue1() { return value1; } public void setValue1(double value1) { this.value1 = value1; } @Range(min=0, max=100) public double getValue2() { return value2; } public void setValue2(double value2) { this.value2 = value2; } public double getAnswer() { return answer; } ... } Displaying errors to the user In the previous section, we saw how to add data validation to our source code to stop invalid data from being entered into our domain model. Now that we have reached a level of data validation, we need to provide feedback to the user to inform them of any invalid data that they have entered. JSF applications have the concept of messages that can be displayed associated with different components. For example, if we have a form asking for a date of birth to be entered, we could display a message next to the entry edit box if an invalid date were entered. JSF maintains a collection of these error messages, and the simplest way of providing feedback to the user is to display a list of all of the error messages that were generated as a part of the previous operation. In order to obtain error messages within the JSF page, we need to tell JSF which components we want to be validated against the domain model. This is achieved by using the <s:validate/> or <s:validateAll/> tags. These are Seam-specific tags and are not a part of the standard JSF runtime. In order to use these tags, we need to add the following taglib reference to the top of the JSF page. <%@ taglib uri="http://jboss.com/products/seam/taglib" prefix="s" %> In order to use this tag library, we need to add a few additional JAR files into the WEB-INF/lib directory of our web application, namely: jboss-el.jar jboss-seam-ui.jar jsf-api.jar jsf-impl.jar This tag library allows us to validate all of the components (<s:validateAll/>) within a block of JSF code, or individual components (<s:validate/>) within a JSF page. To validate all components within a particular scope, wrap them all with the <s:validateAll/> tag as shown here: <h:form> <s:validateAll> <h:inputText value="..." /> <h:inputText value="..." /> </s:validateAll> </h:form> To validate individual components, embed the <s:validate/> tag within the component, as shown in the following code fragment. <h:form> <h:inputText value="..." > <s:validate/> </h:inputText> <h:inputText value="..." > <s:validate/> </h:inputText> </h:form> After specifying that we wish validation to occur against a specified set of controls, we can display error messages to the user. JSF maintains a collection of errors on a page, which can be displayed in its entirety to a user via the <h:messages/> tag. It can sometimes be useful to show a list of all of the errors on a page, but it isn't very useful to the user as it is impossible for them to say which error relates to which control on the form. Seam provides some additional support at this point to allow us to specify the formatting of a control to indicate error or warning messages to users. Seam provides three different JSF facets (<f:facet/>) to allow HTML to be specified both before and after the offending input, along with a CSS style for the HTML. Within these facets, the <s:message/> tag can be used to output the message itself. This tag could be applied either before or after the input box, as per requirements. Facet Description beforeInvalidField This facet allows HTML to be displayed before the input that is in error. This HTML could contain either text or images to notify the user that an error has occurred. <f:facet name="beforeInvalidField"> ... </f:facet> afterInvalidField This facet allows HTML to be displayed after the input that is in error. This HTML could contain either text or images to notify the user that an error has occurred. <f:facet name="afterInvalidField"> ... </f:facet> aroundInvalidField This facet allows the CSS style of the text surrounding the input that is in error to be specified. <f:facet name="aroundInvalidField"> ... </f:facet> In order to specify these facets for a particular field, the <s:decorate/>  tag must be specified outside the facet scope. <s:decorate> <f:facet name="aroundInvalidField"> <s:span styleClass="invalidInput"/> </f:facet> <f:facet name="beforeInvalidField"> <f:verbatim>**</f:verbatim> </f:facet> <f:facet name="afterInvalidField"> <s:message/> </f:facet> <h:inputText value="#{calculator.value1}" required="true" > <s:validate/> </h:inputText> </s:decorate> In the preceding code snippet, we can see that a CSS style called invalidInput is being applied to any error or warning information that is to be displayed regarding the <inputText/> field. An erroneous input field is being adorned with a double asterisk (**) preceding the edit box, and the error message specific to the inputText field after is displayed in the edit box.
Read more
  • 0
  • 0
  • 2566

article-image-remote-job-agent-oracle-11g-database-oracle-scheduler
Packt
09 Oct 2009
7 min read
Save for later

Remote Job Agent in Oracle 11g Database with Oracle Scheduler

Packt
09 Oct 2009
7 min read
Oracle Scheduler in Oracle 10g is a very powerful tool. However, Oracle 11g has many added advantages that give you more power. In this article by Ronald Rood, we will get our hands on the most important addition to the Scheduler—the remote job agent . This is a whole new kind of process, which allows us to run jobs on machines that do not have a running database. However, they must have Oracle Scheduler Agent installed, as this agent is responsible for executing the remote job. This gives us a lot of extra power and also solves the process owner's problem that exists in classical local external jobs. In classical local external jobs, the process owner is by default nobody and is controlled by $ORACLE_HOME/rdbms/admin/externaljob.ora. This creates problems in installation, where the software is shared between multiple databases because it is not possible to separate the processes. In this article, we will start by installing the software, and then see how we can make good use of it. After this, you will want to get rid of the classical local external jobs as soon as possible because you will want to embrace all the improvements in the remote job agent over the old job type. Security Anything that runs on our database server can cause havoc to our databases. No matter what happens, we want to be sure that our databases cannot be harmed. As we have no control over the contents of scripts that can be called from the database, it seems logical not to have these scripts run by the same operating system user who also owns the Oracle database files and processes. This is why, by default, Oracle chose the user nobody as the default user to run the classical local external jobs. This can be adjusted by editing the contents of $ORACLE_HOME/rdbms/admin/externaljob.ora. On systems where more databases are using the same $ORACLE_HOME directory, this automatically means that all the databases run their external jobs using the same operating system account. This is not very flexible. Luckily for us, Oracle has changed this in the 11g release where remote external jobs are introduced. In this release, Oracle decoupled the job runner process and the database processes. The job runner process, that is the job agent, now runs as a remote process and is contacted using a host:port combination over TCP/IP. The complete name for the agent is remote job agent, but this does not mean the job agent can be installed only remotely. It can be installed on the same machine where the database runs, and where it can easily replace the old-fashioned remote jobs. As the communication is done by TCP/IP, this job agent process can be run using any account on the machine. Oracle has no recommendations for the account, but this could very well be nobody. The operating system user who runs the job agent does need some privileges in the $ORACLE_HOME directory of the remote job agent, namely, an execution privilege on $ORACLE_HOME/bin/* as well as read privileges on $ORACLE_HOME/lib/*. At the end of the day, the user has to be able to use the software. The remote job agent should also have the ability to write its administration (log) in a location that (by default) is in $ORACLE_HOME/data, but it can be configured to a different location by setting the EXECUTION_AGENT_DATA environment variable. In 11g, Oracle also introduced a new object type called CREDENTIAL. We can create credentials using dbms_scheduler.create_credential. This allows us to administrate which operating system user is going to run our jobs in the database. This also allows us to have control over who can use this credential. To see which credentials are defined, we can use the *_SCHEDULER_CREDENTIAL views. We can grant access to a credential by granting execute privilege on the credential. This adds lots more control than we ever had in Oracle 10gR2. Currently, the Scheduler Agent can only use a username-password combination to authenticate against the operating system. The jobs scheduled on the remote job agent will run using the account specified in the credential that we use in the job definition. Check the Creating job section to see how this works. This does introduce a small problem in maintenance. On many systems, customers are forced to use security policies such as password aging. When combining with credentials, this might cause a credential to become invalid. Any change in the password of a job runtime account needs to be reflected in the credential definition that uses the account. As we get much more control over who executes a job, it is strongly recommend to use the new remote job agent in favor of the classical local external jobs, even locally. The classical external job type will soon become history. A quick glimpse with a wireshark, a network sniffer, does not reveal the credentials in the clear text, so it looks like it's secure by default. However, the job results do pass in clear text. The agent and the database communicate using SSL and because of this, a certificate is installed in the ${EXECUTION_AGENT_DATA}/agent.key.  You can check this certificate using Firefox. Just point your browser to the host:port where the Scheduler Agent is running and use Firefox to examine the certificate. There is a bug in 11.1.0.6 that generates a certificate with an expiration date of 90 days past the agent's registration date. In such a case, you will start receiving certificate validation errors when trying to launch a job. Stopping the agent can solve this. Just remove the agent.key and re-register the agent with the database. The registration will be explained in this article shortly. Installation on Windows We need to get the software before the installation can take place. The Scheduler Agent can be found on the Transparent Gateways disk, which can be downloaded from Oracle technet at http://www.oracle.com/technology/software/products/database/index.html. There's no direct link to this software, so find a platform of your choice and click on See All to get the complete list of database software products for that platform. Then download the Oracle Database Gateways CD. Unzip the installation CD, and then navigate to the setup program found in the top level folder and start it. The following screenshot shows the download directory where you run the setup file: After running the setup, the following Welcome screen will appear. The installation process is simple. Click on the Next button to continue to the product selection screen. Select Oracle Scheduler Agent 11.1.0.6.0 and click on the Next button to continue. Enter Name and Path for ORACLE_HOME (we can keep the default values). Now click on Next to reach the screen where we can choose a port on which the database can contact the agent. I chose 15021. On Unix systems, pick a port above 1023 because the lower ports require root privileges to open. The port should be unused and easily memorizable, and should not be used by the database's listener process. If possible, keep all the remote job agents registered to the same database and the same port. Also, don't forget to open the firewall for that port. Hitting the Next button brings us to the following Summary screen: We click on the Install button to complete the installation. If everything goes as expected, the End of Installation screen pops up as follows: Click on the Exit button and confirm the exit. We can find Oracle Execution Agent in the services control panel. Make sure it is running when you want to use the agent to run jobs.
Read more
  • 0
  • 0
  • 3452
article-image-creating-your-own-theme-wordpress-tutorial
Packt
09 Oct 2009
10 min read
Save for later

Creating Your Own Theme - A Wordpress Tutorial

Packt
09 Oct 2009
10 min read
WordPress is the most widely used content management system amongst bloggers for many reasons. Not only does it make site management seem like a walk in the park, but it also uses a type of shared hosting, which means that most users can afford it. It has plug-ins for any occasion and desire and finally, it has themes. For many WordPress users, finding the right theme is a long process that often leads to endless tweaking in the code and stylesheets. However, only a few ever consider learning how to create their own. If you are one of them, this tutorial by Brian Franklin will help you learn how to built and start your own theme. Template files and DIV tags The WordPress theme that waits to be created in this tutorial consists of one stylesheet, one functions file, one comments file and a number of template files. Each template file represents a separate part. Together they form the outline of the website’s overall look. However, it is in the stylesheet that web design elements for each template file are decided. DIV tags are used to define, design, and format values of each template file as well as structure its content and elements. The <div> is often described as an invisible box that is used to separate site content in a structural manner. These are later defined in the stylesheet where size, position, form etc. are assigned.  Template files that will be used in this tutorial are: Index Header Footer Sidebar Single Page And the files that define specific functions for the theme are: Functions Comments DIV tags that will be used in this tutorial are: <div id="wrapper"></div> <div id="header"></div> <div id="container"></div> <div id="footer"></div> <div class="post"></div> <div class="entry"></div> <div class="navigation"></div> <div class="sidebar"></div> Using tags requires proper opening and closing. If any tag is not properly closed (</div>) it may affect the presentation on the entire site. There is difference between a DIV id and a class is what they are used for. Unique site features require definition by ID while values that are used to define several elements are defined as class. In the stylesheet, div id is identified with a # and div class with a . (dot). Install WordPress Before you can start building a theme you need to decide how to work. It is recommended to install WordPress on your local computer. This will allow you to save your changes on a local server rather than dealing with remote server access and uploading. Follow the link for further instructions. The other alternative is installing WordPress through your hosting provider. WordPress hosting is a popular plan offered by most hosts. Either way you need to have WordPress installed, remote or local, and create a folder for your theme under the directory /wp-content/themes/yourtheme. Create the template files Use Dreamweaver, Notepad, EditPlus or any other text editor of your choice and create the template files listed above, including the functions files. Leave them blank for now and save them as PHP files (.php) in your theme folder. index.php Open the index.php, add this piece of code and save the file: <?php get_header(); ?><div id="container"> <?php if(have_posts()) : ?><?php while(have_posts()) : the_post(); ?> <div class="post" id="post-<?php the_ID(); ?>"> <h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"> <?php the_title(); ?></a></h2> <div class="entry"> <?php the_content(); ?> <p class="postmetadata"><?php _e('Filed under&#58;'); ?> <?php the_category(', ') ?> <?php _e('by'); ?> <?php the_author(); ?><br /><?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?> <?php edit_post_link('Edit', ' &#124; ', ''); ?> </p> </div> </div> <?php endwhile; ?> <div class="navigation"> <?php posts_nav_link(); ?> </div> <?php endif; ?></div><?php get_sidebar(); ?><?php get_footer(); ?> The index-file now contains the code that calls to the header, sidebar and footer template file. But since there is no code to define these template files yet, you will not see them when previewing the site. The index file is the first file the web browser will call when requesting your site. This file defines the site’s frontpage and thus also includes DIV ID tags "container" and DIV classes "post" and "entry". These elements have been included to structure your frontpage content; posts and post entries. If you preview your WordPress site you should see your three latest blog posts, including ‘next’ and ‘previous’ buttons to the remaining ones. To shorten the length of displayed frontpage post, simply log in to the WordPress admin and insert a page break where you want the post to display a Read more link. You will come back to index.php in a moment, but for now you can save and close the file. It is now time to create the remaining template files. header.php Open header.php, add this code and save the file: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head profile="http://gmpg.org/xfn/11"> <title><?php bloginfo('name'); ?><?php wp_title(); ?></title> <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" /> <meta name="generator" content="WordPress <?php bloginfo('version'); ?>" /> <!-- leave this for stats please --> <link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" /> <link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="<?php bloginfo('rss2_url'); ?>" /> <link rel="alternate" type="text/xml" title="RSS .92" href="<?php bloginfo('rss_url'); ?>" /> <link rel="alternate" type="application/atom+xml" title="Atom 0.3" href="<?php bloginfo('atom_url'); ?>" /> <link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" /> <?php wp_get_archives('type=monthly&format=link'); ?> <?php //comments_popup_script(); // off by default ?> <?php wp_head(); ?></head><body><div id="wrapper"><div id="header"><h1><a href="<?php bloginfo('url'); ?>"><?php bloginfo('name'); ?></a></h1><?php bloginfo('description'); ?></div> The header template file now has the opening tags <html> and <body>. Included in the <html> tag is the <head> tag that holds the meta tags and stylesheet links. The body tag includes two DIV ID tags; wrapper and header that define the boxes and hold the overall position of the site and the header content. footer.php Open footer.php, add the code below and save the file: <div id="footer"> <p>Copyright 2007 <a href="<?php bloginfo('url'); ?>"><?php bloginfo('name'); ?></a></p></div></div></body></html> The footer is a template that defines the bottom part of the website. The footer for this theme now holds a Copyright announcement and a php code that adds the name of the blog as a permalink. As it is the last template file to be called for a site it also closes the body and html tag. sidebar.php Open sidebar.php, add the code below and save the file: <div class="sidebar"><ul><?php if ( function_exists('dynamic_sidebar') && dynamic_sidebar() ) : else : ?> <?php wp_list_pages('depth=3&title_li=<h2>Pages</h2>'); ?> <li><h2><?php _e('Categories'); ?></h2> <ul> <?php wp_list_cats('sort_column=name&optioncount=1&hierarchical=0'); ?> </ul> </li> <li><h2><?php _e('Archives'); ?></h2> <ul> <?php wp_get_archives('type=monthly'); ?> </ul> </li> <?php get_links_list(); ?> <?php endif; ?></ul></div> The sidebar template is now defined and includes the site’s pages, categories, archive and blogroll. Study the code and see the changes in the web browser. Regarding the DIV class, it is left to be designed in the stylesheet. single.php Open single.php, add the code below and save the file: <?php get_header(); ?><div id="container"> <?php if(have_posts()) : ?><?php while(have_posts()) : the_post(); ?> <div class="post" id="post-<?php the_ID(); ?>"> <h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"> <?php the_title(); ?></a></h2> <div class="entry"> <?php the_content(); ?> <p class="postmetadata"><?php _e('Filed under&#58;'); ?> <?php the_category(', ') ?> <?php _e('by'); ?> <?php the_author(); ?><br /><?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?> <?php edit_post_link('Edit', ' &#124; ', ''); ?> </p> </div> <div class="comments-template"><?php comments_template(); ?></div> </div> <?php endwhile; ?> <div class="navigation"> <?php previous_post_link('%link') ?> <?php next_post_link(' %link') ?> </div> <?php endif; ?></div><?php get_sidebar(); ?><?php get_footer(); ?> The single.php template file specifically defines the elements on the single post page that is different from both the frontpage post listing and pages. The code above is basically a copy/paste from the index-file, only with minor changes to the Next and Previous links. 
Read more
  • 0
  • 0
  • 7720

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

The Multi-Table Query Generator using phpMyAdmin and MySQL

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