Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
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 - CMS and E-Commerce

830 Articles
article-image-customizing-menus-menu-joomla
Packt
12 Oct 2011
8 min read
Save for later

Customizing the Menus Menu in Joomla!

Packt
12 Oct 2011
8 min read
The Top Menu is a horizontal menu; the other menus are vertical. Each menu is coupled with a so-called module, which is administered in the module manager. Menus By clicking on this menu item, you get an overview of the available menus. You can also access the content of these menus by means of the menu bar—Menus | Main Menu, Top Menu, or by clicking the respective menu link in the overview. This Menu Manager serves as an overview and shows you the number of Published and Unpublished menu items, the number of menu items that are in the Trash can, and the respective menu ID. In this section you can, for instance, copy a menu or create a new one. Customizing an Existing Menu Experiment a little with the menus to get a feel for things. The following edit steps are same for all the menus. Go to the menu item Menus | Main Menu. You will see a listing of the menu items that turn up in the mainmenu. Several functions can be executed in the table with a simple mouse click. By clicking on the checkmark, you can enable or disable a menu link. You can change the order of the items by clicking on the triangles or by typing numbers into the fields under Order. If you use the numbers method, you have to click on the disk symbol in the header in order to make the change effective. In the Access Level column, via mouse click you can decide whether the menu is available to all users (Public), only to registered users (Registered), or only to a particular circle of users (Special). The menu items are then displayed or hidden, independent of the user's rights. Menus Icon If you click on this icon, you are taken to the menu overview screen. Default Icon The menu item that is marked as default here with a star is displayed as the start page when someone calls up the URL of your website. At the moment this is the menu item Home, but you can designate any element that you want as the start page. Just mark the checkbox and click on the Default icon. Publish/Unpublish Icon The status of a content element can either be published (activated) or unpublished (deactivated). You can toggle this status individually by clicking the green checkmark and/or the red cross, or marking the checkbox and subsequently clicking on the appropriate icon. If you follow the later method, you can toggle several menu items at the same time. Move Icon This entails the moving of menu entries. Let's move the text More about Joomla! into the top menu. Select the respective menu elements or even several menu elements and click the Move icon. This opens a form, listing the available menus. On the right you will see the elements that you want to move: Select the menu into which you would like to move the marked menu items. Here, we have moved More about Joomla! from Main Menu into the Top Menu. You can admire the results in the front end. Copy Icon You can also copy menu items. To do that, select one or more menu items and click on the Copy icon. Just as with moving, a form with the available menus opens. Select the menu into which you want to copy the marked menu entries. Trash Icon In order to protect you from inadvertently deleting items, when editing them you cannot delete them immediately; you can only throw them in the trash. To throw them into trash can, select one or several menu elements and click on the Trash icon. The marked menu items are then dumped into the trash can. You can display the content of the trash can by clicking on Menus | Menu Trash. Edit Icon (Edit Menu Items) Here you can modify an existing menu, for instance the Web Links. After clicking on the name Web Links you will see the edit form for menu elements: The form is divided into three parts.    Menu Item Type    Menu Item Details    Parameters Menu Item Type Every menu item is of a particular type. We will get into greater details when we create new menus. For instance, a menu item can refer to an installed Joomla! component, a content element, a link to an external website, or many other things. You can see what the type of the link is in this section; in our case it is a link to the Joomla! weblinks component, and you can also see a button with the label Change Type. If you click on that button, you get the following screen: This manager is new in Joomla! version 1.5 and really handy. In version 1.0.x there was no option to change the type of a menu item. You had to delete the old menu item and create a new one. Now you can change the display to a single category or to a link-suggestion menu item, with which you invite other users to suggest links. Now close this; we will get back to it when we create a new menu. Menu Item Details It contains the following options: ID: Everything in an administration requires an ID number and so does our menu item. In this case the menu item has the ID number 48. Joomla! assigns this number for internal administration purposes at the time the item is created. This number cannot be changed. Title: This is the name of the menu and it will be displayed that way on your website. Alias: This is the name of the search-engine friendly URL after the domain name. When this is enabled, the URL for this menu will look as follows: http://localhost/joomla150/web-links Link: This is the request for a component, in other words also the part of the URL after the domain name with which you call up your website. In this case it is  index.php?option=com_weblinks&view=categories Display in: With this you can change the place where the item is displayed; in other words you can move it to another menu. The options field presents you with a list of the available menus. Parent Item: Of course menus can also contain nested, tree-like items. Top means that the item is at the uppermost level. The rest of the items represent existing menu items. If, for instance, you classify and save Web Links under The News, the display on the item list and the display on your website are changed. The following figures show the change. The menu item Web Links has now moved into The News on your website. So you have to first click on The News in order to see the Web Links item. Your website can easily and effectively be structured like a database tree in this manner. Published: With this you can publish a menu item. Order: From the options list, you can select after which link you want to position this link. Access Level: You can restrict users that can see this list. On Click, Open in: A very handy option that influences the behavior of the link. The page is either opened in the existing window or in a new browser window after clicking. You can also define whether the new window will be displayed with or without browser navigation. Parameters The possible parameters of a menu item depend on the type of the item. A simple link, of course, has fewer parameters than a configurable list or for example the front page link. In this case we have a link to the categories. The number and type of parameters depend on the type of the menu item. You can open and collapse the parameter fields by clicking on the header. If the parameter fields are open, the arrow next to header points down. Parameters–Basic The basic parameters are the same for all menu links. Image: Here you can specify an image that must be in the root directory of the media manager (/images/stories/). Depending on the template, this picture is displayed on the left, next to the menu item. Image Align: You can decide if the image should be on the left or right. Show a Feed Link: It is possible to create an RSS feed for every list display in Joomla! 1.5. This could be desirable or undesirable depending on the content of the list. In this case, with list displays, RSS feed links that contain the list items are enabled in the browser.
Read more
  • 0
  • 0
  • 4324

article-image-installation-and-getting-started-firebug
Packt
05 Apr 2010
3 min read
Save for later

Installation and Getting Started with Firebug

Packt
05 Apr 2010
3 min read
What is Firebug? Firebug is a free, open source tool that is available as a Mozilla Firefox extension, and allows debugging, editing, and monitoring of any website's CSS, HTML, DOM, and JavaScript. It also allows performance analysis of a website. Furthermore, it has a JavaScript console for logging errors and watching values. Firebug has many other tools to enhance the productivity of today's web developer. Firebug integrates with Firefox to put a wealth of development tools at our fingertips while we browse a website. Firebug allows us to understand and analyze the complex interactions that take place between various elements of any web page when it is loaded by a browser. Firebug simply makes it easier to develop websites/applications. It is one of the best web development extensions for Firefox. Firebug provides all the tools that a web developer needs to analyze, debug, and monitor JavaScript, CSS, HTML, and AJAX. It also includes a debugger, error console, command line, and a variety of useful inspectors. Although Firebug allows us to make changes to the source code of our web page, the changes are made to the copy of the HTML code that has been sent to the browser by the server. Any changes to the code are made in the copy that is available with the browser. The changes don't get reflected in the code that is on the server. So, in order to ensure that the changes are permanent, corresponding changes have to be made in the code that resides on the server. The history of Firebug Firebug was initially developed by Joe Hewitt, one of the original Firefox creators, while working at Parakey Inc. Facebook purchased Parakey in July, 2007. Currently, the open source development and extension of Firebug is overseen by the Firebug Working Group. It has representation from Mozilla, Google, Yahoo, IBM, Facebook, and many other companies. Firebug 1.0 Beta was released in December 2006. Firebug usage has grown very fast since then. Approximately 1.3 million users have Firebug installed as of January 2009. The latest version of Firebug is 1.5. Today, Firebug has a very open and thriving community. Some individuals as well as some companies have developed very useful plugins on top of Firebug. The need for Firebug During the 90s, websites were mostly static HTML pages, JavaScript code was considered a hack, and there were no interactions between page components on the browser side. The situation is not the same anymore. Today's websites are a product of several distinct technologies and web developers must be proficient in all of them—HTML, CSS, JavaScript, DOM, and AJAX, among others. Complex interactions happen between various page components on the browser side. However, web browsers have always focused on the needs of the end users; as a result, web developers have long been deprived of a good tool on the client/browser side to help them develop and debug their code. Firebug fills this gap very nicely—it provides all the tools that today's web developer needs in order to be productive and efficient with code that runs in the browser. Firebug capabilities Firebug has a host of features that allow us to do the following (and much more!): Inspect and edit HTML Inspect and edit CSS and visualize CSS metrics Use a performance tuning application Profile and debug JavaScript Explore the DOM Analyze AJAX calls
Read more
  • 0
  • 0
  • 4306

article-image-basics-wordpress-and-jquery-plugin
Packt
27 Sep 2010
10 min read
Save for later

The Basics of WordPress and jQuery Plugin

Packt
27 Sep 2010
10 min read
  WordPress 3.0 jQuery Enhance your WordPress website with the captivating effects of jQuery. Enhance the usability and increase visual interest in your WordPress 3.0 site with easy-to-implement jQuery techniques Create advanced animations, use the UI plugin to your advantage within WordPress, and create custom jQuery plugins for your site Turn your jQuery plugins into WordPress plugins and share with the world Implement all of the above jQuery enhancements without ever having to make a WordPress content editor switch over into HTML view   Read more about this book (For more resources on WordPress and jQuery, see here.) WordPress plugins overview So themes change the look of WordPress without affecting its functionality. But what if you want to change or add functionality? WordPress plugins allow easy modification, customization, and enhancement to a WordPress site. Instead of having to dig in to the main files and change the core programming of WordPress, you can add functionality by installing and activating WordPress plugins. The WordPress development team took great care to make it easy to create plugins using access points and methods provided by the WordPress' Plugin API (Application Program Interface). The best place to search for plugins is: http://wordpress.org/extend/plugins/. The following is a screenshot of the WordPress plugin directory's main page: (Move the mouse over the image to enlarge.) Once you have a plugin, it's a simple matter of decompressing the file (usually just unzipping it) and reading the included readme.txt file for installation and activation instructions. For most WordPress plugins, this is simply a matter of uploading the file or directory to your WordPress installation's wp-content/plugins directory and then navigating to the Administration | Plugins | Installed panel to activate it. The next screenshot shows the Plugins admin panel with the activation screen for the default Askimet, Hello Dolly, and new WordPress Importer plugins: So how does a WordPress plugin differ from a jQuery plugin? In theory and intent, not that much, but in practice, there are quite a few differences. Let's take a look at jQuery plugins. jQuery plugins overview jQuery has the ability to allow you to take the scripts that you've created and encapsulate them into the jQuery function object. This allows your jQuery code to do a couple of key things. First, it becomes more easily ported over to different situations and uses. Second, your plugin works as a function that can be integrated into larger scripts as part of the jQuery statement chain. The best place to browse for jQuery plugins is the jQuery plugins page (http://plugins.jquery.com/), as seen in the next screenshot: In addition to having jQuery already bundled, WordPress has quite a few jQuery plugins already bundled with it as well. WordPress comes bundled with Color, Thickbox as well as Form and most of the jQuery UI plugins. Each of these plugins can be enabled with the wp_enqueue_script either in the theme's header.php file or function.php file, in WordPress. In this article, we'll shortly learn how to enable a jQuery plugin directly in a WordPress plugin. Of course, you can also download jQuery plugins and include them manually into your WordPress theme or plugins. You'd do this for plugins that aren't bundled with WordPress, or if you need to amend the plugins in anyway. Yes, you've noticed there's no easy jQuery plugin activation panel in WordPress. This is where understanding your chosen theme and WordPress plugins will come in handy! You'll soon find you have quite a few options to choose from when leveraging jQuery. Now that we have an overview of what WordPress themes, plugins, and jQuery plugins are, let's learn how to take better advantage of them. The basics of a WordPress plugin The goal here is to show you the structure of a simple WordPress plugin and the basics of how to construct one. Understanding this, you can begin to write your own basic plugins and feel more confident looking through other people's plugins when assessing what kind of features they provide to your WordPress site and if you need to tweak anything for your jQuery enhancements. Even as simply and basically as we're going to work, you'll see how truly powerful WordPress plugins can be. Want to become a WordPress plugin rockstar? You can start off with, yet again, WordPress 2.7 Complete by April Hodge Silver and Hasin Hayder. There's a chapter on plugins that walks you through creating very useful simple plugins, as well as a more complex plugin that writes to the WordPress database. Beyond that, you'll want to check out WordPress Plugin Development: Beginner's Guide by Vladimir Prelovac. Don't let the title fool you, Vladimir will have you generating feature rich and dynamic WordPress plugins using WordPress' coding standards all explained with clear, step-by-step code. Working with plugins does require some experience with PHP. I'll keep this explanation fairly straightforward for non-PHP developers, and those of you with PHP experience should be able to see how to expand on this example to your advantage in WordPress. Just as with themes, WordPress plugins require a little structure to get started with them. There's no defined hierarchy for plugin files, but you do need, at the very least, a PHP file with a special comment up top so that WordPress can display it within the Plugin Management page. While there are some single-file plugins out there, such as the Hello Dolly plugin, which comes with your WordPress installation, you never know when you first start developing, the ways in which a plugin may grow. To be safe, I like to organize my plugins into a uniquely named folder. Again, like with themes, WordPress relies on the plugin directory's namespace, so uniqueness is of key importance! In the wp-content/plugins directory you can place a unique folder and inside that, create a .php file, and at the beginning of the file, inside the <?php ?> tags, include the following header information. Only the bold information is absolutely required. The rest of the information is optional and populates the Manage Plugins page in the Administration panel. <?php /* Plugin Name: your WordPress Plugin Name goes here Plugin URI: http://yoururl.com/plugin-info Description: Explanation of what it does Author: Your Name Version: 1.0 Author URI: http://yoururl.com */ //plugin code will go here ?> Make sure that you don't have any spaces before your <?php tag or after your ?> tag. If you do, WordPress will display some errors because the system will get some errors about page headers already being sent. Once you have your .php file set up in its own directory, inside your plugin directory, you can add a basic PHP function. You can then decide how you want to evoke that function, using an action hook or a filter hook. For example: <?php /* Plugin Name: your WordPress Plugin Name goes here Plugin URI: http://yoururl.com/plugin-info Description: Explanation of what it does Author: Your Name Version: 1.0 Author URI: http://yoururl.com */ function myPluginFunction(){ //function code will go here } add_filter('the_title', 'myPluginFunction'); //or you could: /*add_action('wp_head', 'myPluginFunction');*/ ?> If you didn't have wp_head or wp_footer in your theme, many plugins can't function, and you limit yourself to the plugins you can write. In my plugins, I mostly use wp_header and the init action hooks. Luckily, most filter hooks will work in your plugins as WordPress will run through them in The Loop. For the most part, you'll get the most work done in your plugin using the_title and the_content filter hooks. Each of these filter's hooks will execute your function when WordPress loops through those template tags in the loop. Want to know what filter and action hooks are available? The list is exhaustive. In fact, it's so immense that the WordPress codex doesn't seem to have them all documented! For the most complete listing available of all action and filter hooks, including newer hooks available in version 2.9.x, you'll want to check out Adam Brown's WordPress Hooks Database: http://adambrown.info/p/wp_hooks. Overwhelmed by the database? Of course, checking out Vladimir's WordPress Plugin Development: Beginner's Guide will get you started with an arsenal of action and filter hooks as well. You now understand the basics of a WordPress plugin! Let's do something with it. Project: Writing a WordPress plugin to display author bios As we've discussed, plugins can help expand WordPress and give it new functionality. However, we've seen that adding jQuery scripts directly to the theme and editing its template pages here and there will do the trick in most cases. But let's imagine a more complicated scenario using our modified default theme and the hypothetical client. While we tweaked the default theme, I figured that this client might want to have her site's focus be more journalism oriented, and thus, she'd want some attention drawn to the author of each post upfront. I was right, she does. However, there's a catch. She doesn't just want their WordPress nickname displayed; she'd prefer their full first and last name be displayed as well, as it's more professional. She'd also like their quick biography displayed with a link to their own URL and yet, not have that information "get in the way" of the article itself, or lost down at the bottom of the post. And here's the really fun part; she wants this change affected not just on this site, but across her network of genre-specific news sites, over 20 of them at last count (dang, I forgot she had so many sites! Good thing she's hypothetical). For this specific WordPress site, it's easy enough to go in and comment out the custom function we dealt with earlier: add in the_author tag and display it twice, passing each tag some parameters to display the first and last name. I can also add a tag to display the author's biography snippet from the user panel and URL (if they've filled out that information). Also, it's certainly easy enough to add a little jQuery script to make that bio div show up on a rollover of the author's name. However, having to take all that work and then re-copy it into 20 different sites, many of which are not using the default theme, and most of which have not had jQuery included into their theme, does sound like an unnecessary amount of work (to boot, the client has mentioned that she's deciding on some new themes for some of the sites, but she doesn't know which sites will get what new themes yet). It is an unnecessary amount of work. Instead of amending this theme and then poking through, pasting, testing, and tweaking in 20 other themes, we'll spend that time creating a WordPress plugin. It will then be easy to deploy it across all the client's sites, and it shouldn't matter what theme each site is using. Let's get started!
Read more
  • 0
  • 0
  • 4295

article-image-ibm-filenet-p8-content-manager-end-user-tools-and-tasks
Packt
15 Feb 2011
10 min read
Save for later

IBM FileNet P8 Content Manager: End User Tools and Tasks

Packt
15 Feb 2011
10 min read
Getting Started with IBM FileNet P8 Content Manager Install, customize, and administer the powerful FileNet Enterprise Content Management platform Quickly get up to speed on all significant features and the major components of IBM FileNet P8 Content Manager Provides technical details that are valuable both for beginners and experienced Content Management professionals alike, without repeating product reference documentation Gives a big picture description of Enterprise Content Management and related IT areas to set the context for Content Manager Written by an IBM employee, Bill Carpenter, who has extensive experience in Content Manager product development, this book gives practical tips and notes with a step-by-step approach to design real Enterprise Content Management solutions to solve your business needs Parts of some of these topics will cover things that are features of the XT application rather than general features of CM and the P8 platform. We'll point those out so there is no confusion. What is Workplace XT? IBM provides complete, comprehensive APIs for writing applications to work with the CM product and the P8 platform. They also provide several pre-built, ready to use environments for working with CM. These range from connectors and other integrations, to IBM and third-party applications, to standalone applications provided with CM. Business needs will dictate which of these will be used. It is common for a given enterprise to use a mix of custom coding, product integrations, and standalone CM applications. Even in cases where the standalone CM applications are not widely deployed throughout the enterprise, they can still be used for ad hoc exploration or troubleshooting by administrators or power users. XT is a complete, standalone application included with CM. It's a good application for human-centered document management, where users in various roles actively participate in the creation and management of individual items. XT exposes most CM features, including the marriage of content management and process management (workflow). XT is a thin client web application built with modern user interface technologies so that it has something of a Web 2.0 look and feel. To run XT, open its start page with your web browser. The URL is the server name where XT is installed, the appropriate port number, and the default context of WorkplaceXT. In our installation, that's http://wjc-rhel.example.net:9080/WorkplaceXT. We don't show it here, but for cases where XT is in wider use than our all-in-one development system, it's common to configure things so that it shows up on port 80, the default HTTP port. This can be done by reconfiguring the application server to use those ports directly or by interposing a web server (for example, IBM HTTP Server, IHS) as a relay between the browser clients and the application server. It's also common to configure things such that at least the login page is protected by TLS/SSL. Details for both of these configuration items are covered in depth in the product documentation (they vary by application server type). For some of the examples in this article, we'll log on as the high-privileged user poweruser, and, for others, we'll log on as the low-privileged user unpriv. You can create them now or substitute any pair of non-administrator accounts from your own directory. Browsing folders and documents Let's have a look at XT's opening screen. Log onto XT as user poweruser. With the folder icon selected from the top-left group of four icons, as in the figure below, XT shows a tree view that allows browsing through folders for content. Of course, we don't actually have any content in the Object Store yet, so all we see when we expand the Object Store One node are pseudo-folders (that is, things XT puts into the tree but which are not really folders in the Object Store). Let's add some content right now. For now, we'll concentrate on the user view of things. Adding folders In the icon bar are two icons with small, green "+" signs on them (you can see them in the screenshot above). The left icon, which looks like a piece of paper, is for adding documents to the currently expanded folder. The icon to the right of that, which looks like an office supply folder, is for adding a subfolder to the currently expanded folder. Select Object Store One in the tree view, and click the icon for adding a folder. The first panel of a pop-up wizard appears, as shown above, prompting you for a folder name. We have chosen the name literature to continue the example that we started in Administrative Tools and Tasks. Click the Add button, and the folder will be created and will appear in the tree view. Follow the same procedure to add a subfolder to that called shakespeare. That is, create a folder whose path is /literature/shakespeare. You can modify the security of most objects by right-clicking and selecting More Information | Security. A pop-up panel shows the object's Access Control List (ACL). For now, we just want to allow other users to add items to the shakespeare folder (we'll need that for the illustration of entry templates when we get to that section below). Open that folder's security panel. Click the link for #AUTHENTICATEDUSERS, and check the File In Folder box in the Allow column, highlighted in the following screenshot: Adding documents Now let's add some actual documents to our repository. We'll add a few of Shakespeare's famous works as sample documents. There are many sources for electronic copies of Shakespeare's works readily available on the Internet. One of our favorites for exercises like this is at the Massachusetts Institute of Technology: http://shakespeare.mit.edu. It's handy because it's really just the text without a lot of notes, criticisms, and so on. The first thing you see is a list of all the works categorized by type of work, and you're only a click or two away from the full HTML text of the work. It doesn't hurt that they explicitly state that they have placed the HTML versions in the public domain. We'll use the full versions in a single HTML page for our sample documents. In some convenient place on your desktop machine, download a few of the full text files. We chose As You Like It (asyoulikeit_full.html), Henry V (henryv_full.html), Othello (othello_full.html), and Venus and Adonis (VenusAndAdonis.html). Select the /literature/shakespeare folder in the tree view, and click the icon for adding a document. The document add wizard pops up, as shown next: Browse to the location of the first document file, asyoulikeit_full.html, and click the Next button. Don't click Add Now or you won't get the correct document class for our example. Initially, the class Document is indicated. Click on Class and select Work of Literature. The list of properties automatically adjusts to reflect the custom properties defined for our custom class. Supply the values indicated (note in particular that you have to adjust the Document Title property because it defaults to the file name). XT uses the usual convention of marking required properties with an asterisk. Click Add. Repeat the above steps for the other three documents. You'll now have a short list in the shakespeare folder. XT also provides a "landing zone" for the drag-and-drop of documents. It's located in the upper right-hand corner of the browser window, as shown next. This can save you the trouble of browsing for documents in your filesystem. Even though it can accept multiple documents in a single drag-and-drop, it prompts only for a single set of property values that are applied to all of the documents. Viewing documents Clicking on a document link in XT will lead to the download of the content and the launching of a suitable application. For most documents, the web browser is used to find and launch an application based on the document content type, although XT does have some configurability in its site preferences for customizing that behavior. The behavior you can normally expect is the same as if you clicked on a link for a document on any typical website. For graphical image content (JPEG, PNG, and similar formats), XT launches the Image Viewer applet. The Image Viewer applet is especially handy for dealing with Tagged Image Format Files (TIFF) graphics because most browsers do not handle TIFF natively. It is common for fax and scanning applications to generate TIFF images of pages. However, even for common graphics formats that can be rendered by the browser, the Image Viewer applet has more functionality. The most interesting extra features are for adding textual or graphical annotations to the image. Rather than directly manipulating the original image, the annotations are created in an overlay layer and saved as Annotation objects in the repository. For example, in the image below, being displayed in the Image Viewer applet, the stamp tool has been used to mark it as a DRAFT. That annotation can easily be repositioned or even removed without affecting the original image. The included Image Viewer applet is licensed only for use within the FileNet components where it's already integrated. It is an OEM version of ViewONE from Daeja Image Systems. The ViewONE Pro application, which has additional functionality, is available for license directly from Daeja and can be integrated into FileNet applications as a supported configuration. However, in such cases, support for the viewer itself comes directly from Daeja. Entry templates Although each step of document and folder creation is individually straightforward, taken together they can become bewildering to non-technical users, especially if coupled with naming, security, and other conventions. Even when the process is completely understood, there are several details which are purely clerical in nature but which still might suffer from mis-typing and so on. From these motivations comes an XT feature called Entry Templates. Someone, usually an administrator, creates an entry template as an aid for other users who are creating folders or documents. A great many details can be specified in advance, but the user can still be given choices at appropriate points. To create an entry template, navigate to Tools | Advanced Tools | Entry Templates | Add. A wizard is launched from which you can define a Document Entry Template or a Folder Entry Template. We won't go through all of the steps here since the user interface is easy to understand. Both types of entry templates are Document subclasses, and XT files created entry templates into folders. When you double-click on an entry template, XT presents a user interface that adheres to the entry template design. For example, in this screen shot which uses an entry template called Shakespearean Document, the document class and target folder are already selected and cannot be changed by the user. Likewise, the author last and full names are pre-populated. Other properties, which genuinely need user input, can be edited as usual.
Read more
  • 0
  • 0
  • 4292

article-image-jquery-table-manipulation-part-2
Packt
24 Oct 2009
6 min read
Save for later

jQuery Table Manipulation: Part 2

Packt
24 Oct 2009
6 min read
Advanced Row Striping Row striping can be as simple as two lines of code to alternate the background color: $(document).ready(function() {   $('table.sortable tbody tr:odd').addClass('odd');   $('table.sortable tbody tr:even').addClass('even'); }); If we declare background colors for the odd and even classes as follows, we can see the rows in alternating shades of gray: tr.even {   background-color: #eee; } tr.odd {   background-color: #ddd; } While this code works fine for simple table structures, if we introduce non‑standard rows into the table, such as sub-headings, the basic odd-even pattern no longer suffices. For example, suppose we have a table of news items grouped by year, with columns for date, headline, author, and topic. One way to express this information is to wrap each year's news items in a <tbody> element and use <th colspan="4"> for the subheading. Such a table's HTML (in abridged form) would look like this: <table class="striped"> <thead> <tr> <th>Date</th> <th>Headline</th> <th>Author</th> <th class="filter-column">Topic</th> </tr> </thead><tbody> <tr> <th colspan="4">2007</th> </tr> <tr> <td>Mar 11</td> <td>SXSWi jQuery Meetup</td> <td>John Resig</td> <td>conference</td> </tr> <tr> <td>Feb 28</td> <td>jQuery 1.1.2</td> <td>John Resig</td> <td>release</td> </tr> <tr> <td>Feb 21</td> <td>jQuery is OpenAjax Compliant</td> <td>John Resig</td> <td>standards</td> </tr> <tr> <td>Feb 20</td> <td>jQuery and Jack Slocum's Ext</td> <td>John Resig</td> <td>third-party</td> </tr></tbody><tbody> <tr> <th colspan="4">2006</th> </tr> <tr> <td>Dec 27</td> <td>The Path to 1.1</td> <td>John Resig</td> <td>source</td> </tr> <tr> <td>Dec 18</td> <td>Meet The People Behind jQuery</td> <td>John Resig</td> <td>announcement</td> </tr> <tr> <td>Dec 13</td> <td>Helping you understand jQuery</td> <td>John Resig</td> <td>tutorial</td> </tr></tbody><tbody> <tr> <th colspan="4">2005</th> </tr> <tr> <td>Dec 17</td> <td>JSON and RSS</td> <td>John Resig</td> <td>miscellaneous</td> </tr></tbody></table> With separate CSS styles applied to <th> elements within <thead> and <tbody>, a snippet of the table might look like this: To ensure that the alternating gray rows do not override the color of the subheading rows, we need to adjust the selector expression: $(document).ready(function() { $('table.striped tbody tr:not([th]):odd').addClass('odd'); $('table.striped tbody tr:not([th]):even').addClass('even');}); The added selector, :not([th]), removes any table row that contains a <th> from the matched set of elements. Now the table will look like this: Three-color Alternating Pattern There may be times when we want to apply more complex striping. For example, we can apply a pattern of three alternating row colors rather than just two. To do so, we first need to define another CSS rule for the third row. We'll also reuse the odd and even styles for the other two, but add more appropriate class names for them: tr.even,tr.first { background-color: #eee;}tr.odd,tr.second { background-color: #ddd;}tr.third { background-color: #ccc;} To apply this pattern, we start the same way as the previous example—by selecting all rows that are descendants of a <tbody>, but filtering out the rows that contain a <th<. This time, however, we attach the .each() method so that we can use its built-in index: $(document).ready(function() { $('table.striped tbody tr').not('[th]').each(function(index) { //Code to be applied to each element in the matched set. });}); To make use of the index, we can assign our three classes to a numeric key: 0, 1, or 2. We'll do this by creating an object, or map: $(document).ready(function() { var classNames = { 0: 'first', 1: 'second', 2: 'third' }; $('table.striped tbody tr').not('[th]').each(function(index) { // Code to be applied to each element in the matched set. });}); Finally, we need to add the class that corresponds to those three numbers, sequentially, and then repeat the sequence. The modulus operator, designated by a %, is especially convenient for such calculations. A modulus returns the remainder of one number divided by another. This modulus, or remainder value, will always range between 0 and one less than the dividend. Using 3 as an example, we can see this pattern: 3/3 = 1, remainder 0.4/3 = 1, remainder 1.5/3 = 1, remainder 2.6/3 = 2, remainder 0.7/3 = 2, remainder 1.8/3 = 3, remainder 2. And so on. Since we want the remainder range to be 0 – 2, we can use 3 as the divisor (second number) and the value of index as the dividend (first number). Now we simply put that calculation in square brackets after classNames to retrieve the corresponding class from the object variable as the .each() method steps through the matched set of rows: $(document).ready(function() { var classNames = { 0: 'first', 1: 'second', 2: 'third' }; $('table.striped tbody tr').not('[th]').each(function(index) { $(this).addClass(classNames[index % 3]); });}); With this code in place, we now have the table striped with three alternating background colors: We could of course extend this pattern to four, five, six, or more background colors by adding key-value pairs to the object variable and increasing the value of the divisor in classNames[index % n].
Read more
  • 0
  • 0
  • 4287

article-image-getting-started-omnet
Packt
30 Sep 2013
5 min read
Save for later

Getting Started with OMNeT++

Packt
30 Sep 2013
5 min read
(For more resources related to this topic, see here.) What this book will cover This book will show you how you can get OMNeT++ up and running on your Windows or Linux operating system. This book will then take you through the components that make up an OMNeT++ network simulation. The components include models written in the NED (Network Description) language, initialization files, C++ source files, arrays, queues, and then configuring and running a simulation. This book will show you how these components make up a simulation using different examples, which can all be found online. At the end of the book, I will be focusing on a method to debug your network simulation using a particular type of data visualization known as a sequence chart, and what the visualization means. What is OMNeT++? OMNeT++ stands for Objective Modular Network Testbed in C++. It's a component-based simulation library written in C++ designed to simulate communication networks. OMNeT++ is not a network simulator but a framework to allow you to create your own network simulations. The need for simulation Understanding the need for simulation is a big factor in deciding if this book is for you. Have a look at this table of real network versus simulated network comparison. A real network A network simulation The cost of all the hardware, servers, switches and so on has to be borne. The cost of a single standalone machine with OMNeT++ installed (which is free). It takes a lot of time to set up big specialist networks used for business or academia It takes time to learn how to create simulations, though once you know how it's done, it's much easier to create new ones. Making changes to a pre-existing network takes planning, and if a change is made in error, it may cause the network to fail. Making changes to a simulated network of a real pre-existing network doesn't pose any risk. The outcome of the simulation can be analyzed to determine how the real network will be affected. You get the real thing, so what you observe from the real network is actually happening. If there is a bug in the simulation software, it could cause the simulation to act incorrectly. As you can see, there are benefits of using both real networks and network simulations when creating and testing your network. The point I want to convey though, is that network simulations can make network design cheaper and less costly. Examples of simulation in the industry After looking into different industries, we can see that there is obviously a massive need for simulation where the aim is to solve real-world problems from how a ticketing system should work in a hospital to what to do when a natural disaster strikes. Simulation allows us to forecast potential problems without having to first live through those problems. Different uses of simulation in the industry are as follows: Manufacturing: The following are the uses under manufacturing: To show how labor management will work, such as worker efficiency, and how rotas and various other factors will affect production To show what happens when a component fails on a production line Crowd Management: The following are the uses under crowd management: To show the length of queues at theme parks and how that will affect business To show how people will get themselves seated at an event in a stadium Airports: The following are the uses for airports: Show the effects of flight delays on air-traffic control Show how many bags can be processed at any one time on a baggage handling system, and what happens when it fails Weather Forecasting: The following are the uses under weather forecasting: To predict forthcoming weather To predict the effect of climate change on the weather That's just to outline a few, but hopefully you can see how and where simulation is useful. Simulating your network will allow you to test the network against myriads of network attacks, and test all the constraints of the network without damaging it in real life. What you will learn After reading this book you will know the following things: How to get a free copy of OMNeT++ How to compile and install OMNeT++ on Windows and Linux What makes up an OMNeT++ network simulation How to create network topologies with NED How to create your own network simulations using the OMNeT++ IDE How to use pre-existing libraries in order to make robust and realistic network simulations without reinventing the wheel Learning how to create and run network simulations is definitely a big goal of the book. Another goal of this book is to teach you how you can learn from the simulations you create. That's why this book will also show you how to set up your simulations, and to collect data of the events that occur during the runtime of the simulation. Once you have collected data from the simulation, you will learn how to debug your network by using the Data Visualization tools that come with OMNeT++. Then you will be able to grasp what you learned from debugging the simulated network and apply it to the actual network you would like to create. Summary You should now know that this book is intended for people who want to get network simulations up and running with OMNeT++ as soon as possible. You'll know by now, roughly, what OMNeT++ is, the need for simulation, and therefore OMNeT++. You'll also know what you can expect to learn from this book. Resources for Article: Further resources on this subject: Installing VirtualBox on Linux [Article] Fedora 8 — More than a Linux Distribution [Article] Linux Shell Scripting – various recipes to help you [Article]
Read more
  • 0
  • 0
  • 4282
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-using-bean-validation-jsr-303-annotations-apache-myfaces-12
Packt
30 Mar 2010
9 min read
Save for later

Using Bean Validation (JSR 303) annotations with Apache MyFaces 1.2

Packt
30 Mar 2010
9 min read
Using annotations in JavaBeans is an elegant way of defining validation rules in a declarative way. Apart from MyFaces ExtVal there are other projects that introduced declarative validation, such as the Hibernate Validator and the Bean Validation Framework for Spring. Some framework developers realized that it would be a good idea to standardize this type of validation. This led to the Bean Validation specification that was developed as JSR 303 in the Java Community Process. Accordingly, Bean Validation will be a standard part of Java EE 6, but it can be used in Java EE 5 by manually including a Bean Validation implementation. One of the benefits of having an official standard for validation is that various user interface frameworks can implement support for this type of validation. For example, JavaServer Faces 2.0 will have support for Bean Validation embedded in it, and other UI frameworks will probably follow But at the moment, we’re still building Java EE 5 and JSF 1.2 applications. And although we can use Bean Validation in Java EE 5, JSF 1.2 doesn’t have Bean Validation support. And that’s where ExtVal comes in. We can use ExtVal to integrate JSR 303 Bean Validation into JSF 1.2 (and even JSF 1.1) projects. This section will discuss some Bean Validation basics and show how to use Bean Validation with ExtVal. Note that we can only cover some basics of Bean Validation here. As Bean Validation is a new standard, there is not much reference documentation available yet. However, some decent documentation comes bundled with Hibernate Validator—the reference implementation of JSR 303. That documentation is also available online at http://docs.jboss.org/hibernate/stable/validator/reference/. As an alternative, the official specification of JSR 303 can be used as documentation. The official specification can be found at http://jcp.org/en/jsr/summary?id=303. Setting up Bean Validation and ExtVal To use Bean Validation, we need a JSR 303 implementation, unless we’re using a Java EE 6 compliant application server. Currently, the only available JSR 303 implementation is the reference implementation, which is Hibernate Validator 4.0. Hibernate Validator can be downloaded from http://www.hibernate.org/subprojects/validator/download.html . We should make sure we download a 4.0 version, as versions before 4.0 do not implement the JSR 303 standard. At the time of writing this article, the latest release is 4.0.2 GA. After downloading Hibernate Validator, we have to add the Bean Validation libraries to our project. All libraries have to be in the shared lib directory of our EAR. We also have to add the libraries that Hibernate Validator depends on. The following table shows a list of libraries that have to be added to our project in order to be able to use the Hibernate Validator. If we had used Maven, these libraries would have been downloaded and added to our project automatically by Maven. Library Description Where to get hibernate-validator-4.0.2.GA.jar The main Hibernate Validator library. Included in the root directory of the Hibernate Validator distribution. validation-api-1.0.0.GA.jar Contains all interfaces and annotations defined by the JSR 303 standard. Included in the lib directory of the Hibernate Validator distribution. slf4j-log4j12-1.5.6.jar slf4j-api-1.5.6.jar log4j-1.2.14.jar jpa-api-2.0.Beta-20090815.jar   Runtime dependencies of Hibernate Validator. Included in the lib directory of the Hibernate Validator distribution. activation-1.1.jar jaxb-api-2.1.jar jaxb-impl-2.1.3.jar stax-api-1.0-2.jar Runtime dependencies for Hibernate Validator. These libraries are only needed if we run Hibernate Validator on a JDK 5 version. So even if we use a Java EE 5 server that runs on a JDK 6, we don't need these libs. Included in the lib/jdk5 directory of the Hibernate Validator distribution. Once we have added the Bean Validation libraries to our project, we have to make sure that we have also added ExtVal’s Bean Validation module to our project. The Bean Validation module is only available from ExtVal version 1.2.3 onwards. See the Setting up ExtVal section for more details. Using Bean Validation annotations The basic usage of Bean Validation is very similar to the use of ExtVal’s Property Validation annotations. There are some differences in the annotations, though. The following table lists all of the annotations that are defined in the Bean Validation specification: Annotation Attributes Description @AssertFalse   Assure that the element that is annotated is false. @AssertTrue   Assure that the element that is annotated is true. @DecimalMin value The value of the annotated element must be a numeric value greater than or equal to the indicated value. The value attribute must be a String that will be interpreted as a BigDecimal string representation. @DecimalMax value The value of the annotated element must be a numeric value less than or equal to the indicated value. The value attribute has the same behavior as the value attribute of the @DecimalMin annotation. @Digits integer, fraction The annotated element must have a numeric value that can't have more integer digits and fraction digits than indicated by the integer and fraction attributes. @Past   Can be applied to java.util.Date and java.util.Calendar elements. The value of the annotated element must be in the past. @Future   Can be applied to java.util.Date and java.util.Calendar elements. The value of the annotated element must be in the future. @Min value Only for integer values. The value of the annotated element must be greater than or equal to the given value. @Max value Only for integer values. The value of the annotated element must be less than or equal to the given value. @NotNull   The annotated value can't be null. @Null   The annotated value must be null. @Pattern regexp, flags Can only be applied to Strings. The annotated String must match the regular expression that is given in the regexp attribute. The flags attribute can be set to an array of Pattern.Flag values, indicating which flags should be set to the java.util.regex.Pattern that will be used to match the value against. Valid flags are UNIX_LINES, CASE_INSENSITIVE, COMMENTS, MULTILINE, DOTALL, UNICODE_CASE, and CANON_EQ. See the JavaDoc documentation of java.util.regex.Pattern for an explanation of the flags. (http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html) @Size min, max Can be applied to Strings, Collections, Maps, and arrays. Verifies that the size of the annotated element is between the given min and max values, min and max included. @Valid   For recursive validation. All annotations are defined in the javax.validation.constraints package. Apart from the attributes mentioned in the previous table, all annotations (except the @Valid annotation) have the following common attributes: message: This attribute can be used to set a custom error message that will be displayed if the constraint defined by the annotation is not met. If we want to set a message bundle key instead of a literal message, we should surround it with braces. So we can set message to either "This value is not valid" or "{inc.monsters.mias.not_valid}". groups: This attribute can be used to associate a constraint with one or more validation processing groups. Validation processing groups can be used to influence the order in which constraints get validated, or to validate a bean only partially. (See http://docs.jboss.org/hibernate/stable/validator/reference/en/html/validator-usingvalidator.html#validator-usingvalidator-validationgroups for more on validation groups.) payload: This attribute can be used to attach extra meta information to a constraint. The Bean Validation standard does not define any standard metadata that can be used, but specific libraries can define their own metadata. This mechanism can be used with ExtVal to add severity information to constraints, enabling the JSF pages to show certain constraint violations as warnings instead of errors. See the Using payloads to set severity levels section for an example of this. OK, now we know which annotations can be used. Let’s see how we can use Bean Validation annotations on our Employee class: // Package declaration and imports omitted for brevitypublic class Employee implements Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; @Temporal(TemporalType.DATE) @Column(name="BIRTH_DATE") @Past private Date birthDate; @Column(name="FIRST_NAME") private String firstName; @Temporal(TemporalType.DATE) @Column(name="HIRE_DATE") @Past private Date hireDate; @Column(name="JOB_TITLE") @NotNull @Size(min=1) private String jobTitle; @Column(name="LAST_NAME") private String lastName; @Min(value=100) private int salary; @Column(name="KIDS_SCARED") private int kidsScared; @OneToMany(mappedBy="employee") private List<Kid> kids; // Getters and setters and other code omitted.} The Bean Validation annotations are highlighted in the code example. Note that the annotations are applied to the member variables here. Alternatively, we could have applied them to the getter methods. In this example, the birthDate and hireDate are annotated with @Past so that only dates in the past can be set. The jobTitle is set to have a minimum length of one character by the @Size annotation. The salary must have a minimum value of 100, as set by the @Min annotatiion. Reusing validation Bean Validation does not have a solution like the @JoinValidation annotation of ExtVal’s Property Validation module. However, Bean Validation offers other ways to avoid repetitive code and help us reusing validation. This section describes some of the possibilities Inheriting validation Constraints defined on (the properties of) super classes are inherited. This means that if we have a super class called Person, like the following example, our Employee class can inherit the properties—including the annotated constraints—as follows: public class Person { @Size(min=1) private String firstName; @Size(min=1) private String lastName; @Past private Date birthDate; // Getters and setters omitted.} No special actions have to be taken to inherit annotated validation constraints. Using recursive validation We can use the @Valid annotation to use recursive validation (or graph validation as it is called in the JSR 303 specification). The @Valid annotation can be used on single member objects as well as on Collections. If applied to a Collection, all objects in the collection are validated, but null values in the Collection are ignored. For example, we could use this to validate the List of scared Kids that is part of our Employee class, as follows: public class Employee implements Serializable { // Other member variables are left out here. @OneToMany(mappedBy="employee") @Valid private List<Kid> kids; // Getters and setters are omitted.} Now the List of Kids that is referenced by the kidsvariable can only contain valid Kid objects. This means that all Bean Validation constraints that are defined on the Kid class will be checked on all Kid objects in the List.
Read more
  • 0
  • 0
  • 4267

article-image-creating-animated-gauge-css3
Packt
20 Mar 2013
15 min read
Save for later

Creating an Animated Gauge with CSS3

Packt
20 Mar 2013
15 min read
(For more resources related to this topic, see here.) A basic gauge structure Let's begin with a new project; as usual we need to create an index.html file. This time the markup involved is so small and compact that we can add it right now: <!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>Go Go Gauges</title> <link rel="stylesheet" type="text/css" href="css/application.css"> </head> <body> <div data-gauge data-min="0" data-max="100" data-percent="50"> <div data-arrow></div> </div> </body> </html> The gauge widget is identified by the data-gauge attribute and defined with three other custom data attributes; namely, data-min, data-max, and data-percent, which indicate the respective minimum and maximum value of the range and the current arrow position expressed in percentage value. Within the element marked with the data-gauge attribute, we have defined a div tag that will become the arrow of the gauge. To start with the styling phase, we first need to equip ourselves with a framework that is easy to use and can give us the opportunity to generate CSS code. We decide to go for SASS so we first need to install Ruby (http://www.ruby-lang.org/en/downloads/) and then enter the following from a command-line terminal: gem install sass You would probably need to execute the following command if you are working in Unix/Linux environments: sudo gem install sass   Installing Compass For this project we'll also use Compass, a SASS extension able to add some interesting features to our SASS stylesheet. To install Compass, we have to just enter gem install compass (or sudo gem install compass) in a terminal window. After the installation procedure is over, we have to create a small config.rb file in the root folder of our project using the following code: # Require any additional compass plugins here. # Set this to the root of your project when deployed: http_path = YOUR-HTTP-PROJECT-PATH css_dir = "css" sass_dir = "scss" images_dir = "img" javascripts_dir = "js" # You can select your preferred output style here (can be overridden via the command line): # output_style = :expanded or :nested or :compact or :compressed # To enable relative paths to assets via compass helper functions. Uncomment: relative_assets = true # To disable debugging comments that display the original location of your selectors. Uncomment: # line_comments = false preferred_syntax = :sass The config.rb file helps Compass to understand the location of the various assets of the project; let's have a look at these options in detail: http_path: This must be set to the HTTP URL related to the project's root folder css_dir: This contains the relative path to the folder where the generated CSS files should be saved sass_dir: This contains the relative path to the folder that contains our .scss files images_dir: This contains the relative path to the folder that holds all the images of the project javascripts_dir: This is similar to images_dir, but for JavaScript files There are other options available; we can decide whether the output CSS should be compressed or not, or we can ask Compass to use relative paths instead of absolute ones. For a complete list of all the options available, see the documentation at http://compass-style.org/help/tutorials/configuration-reference/. Next, we can create the folder structure we just described, providing our project with the css, img, js, and scss folders. Lastly, we can create an empty scss/application.scss file and start discovering the beauty of Compass. CSS reset and vendor prefixes We can ask Compass to regenerate the CSS file after each update to its SCSS counterpart. To do so, we need to execute the following command from the root of our project using a terminal: compass watch . Compass provides an alternative to the Yahoo! reset stylesheet we used in our previous project. To include this stylesheet, all we have to do is add a SASS include directive to our application.scss file: @import "compass/reset"; If we check css/application.css, the following is the result (trimmed): /* line 17, ../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass- 0.12.2/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; } /* line 22, ../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass- 0.12.2/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ html { line-height: 1; } ... Notice also how the generated CSS keeps a reference to the original SCSS; this comes in handy when it's a matter of debugging some unexpected behaviors in our page. The next @import directive will take care of the CSS3 experimental vendor prefixes. By adding @import "compass/css3" on top of the application.scss file, we ask Compass to provide us with a lot of powerful methods for adding experimental prefixes automatically; for example, the following snippet: .round { @include border-radius(4px); } Is compiled into the following: .round { -moz-border-radius: 4px; -webkit-border-radius: 4px; -o-border-radius: 4px; -ms-border-radius: 4px; -khtml-border-radius: 4px; border-radius: 4px; } Equipped with this new knowledge, we can now start deploying the project. Using rem For this project we want to introduce rem, a measurement unit that is almost equivalent to em, but is always relative to the root element of the page. So, basically we can define a font size on the html element and then all the sizes will be related to it: html{ font-size: 20px; } Now, 1rem corresponds to 20px; the problem of this measurement is that some browsers, such as Internet Explorer version 8 or less, don't actually support it. To find a way around this problem, we can use the following two different fallback measurement units: em: The good news is that em, if perfectly tuned, works exactly as rem; the bad news is that this measurement unit is relative to the element's font-size property and is not relative to html. So, if we decide to pursue this method, we then have to take extra care every time we deal with font-size. px: We can use a fixed unit pixel size. The downside of this choice is that in older browsers, we're complicating the ability to dynamically change the proportions of our widget. In this project, we will use pixels as our unit of measurement. The reason we have decided this is because one of the rem benefits is that we can change the size of the gauge easily by changing the font-size property with media queries. This is only possible where media queries and rem are supported. Now, we have to find a way to address most of the duplication that would emerge from having to insert every statement containing a space measurement unit twice (rem and px). We can easily solve this problem by creating a SASS mixin within our application.scss file as follows (for more info on SASS mixins, we can refer to the specifications page at http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixins): @mixin px_and_rem($property, $value, $mux){ #{$property}: 0px + ($value * $mux); #{$property}: 0rem + $value; } So the next time instead of writing the following: #my_style{ width: 10rem; } We can instead write: #my_style{ @include px_and_rem(width, 10, 20); } In addition to that, we can also save the multiplier coefficient between px and rem in a variable and use it in every call to this function and within the html declaration; let's also add this to application.scss: $multiplier: 20px; html{ font-size: $multiplier; } Of course, there are still some cases in which the @mixin directive that we just created doesn't work, and in such situations we'll have to handle this duality manually. Basic structure of a gauge Now we're ready to develop at least the basic structure of our gauge, which includes the rounded borders and the minimum and maximum range labels. The following code is what we need to add to application.scss: div[data-gauge]{ position: absolute; /* width, height and rounded corners */ @include px_and_rem(width, 10, $multiplier); @include px_and_rem(height, 5, $multiplier); @include px_and_rem(border-top-left-radius, 5, $multiplier); @include px_and_rem(border-top-right-radius, 5, $multiplier); /* centering */ @include px_and_rem(margin-top, -2.5, $multiplier); @include px_and_rem(margin-left, -5, $multiplier); top: 50%; left: 50%; /* inset shadows, both in px and rem */ box-shadow: 0 0 #{0.1 * $multiplier} rgba(99,99,99,0.8), 0 0 #{0.1 * $multiplier} rgba(99,99,99,0.8) inset; box-shadow: 0 0 0.1rem rgba(99,99,99,0.8), 0 0 0.1rem rgba(99,99,99,0.8) inset; /* border, font size, family and color */ border: #{0.05 * $multiplier} solid rgb(99,99,99); border: 0.05rem solid rgb(99,99,99); color: rgb(33,33,33); @include px_and_rem(font-size, 0.7, $multiplier); font-family: verdana, arial, sans-serif; /* min label */ &:before{ content: attr(data-min); position: absolute; @include px_and_rem(bottom, 0.2, $multiplier); @include px_and_rem(left, 0.4, $multiplier); } /* max label */ &:after{ content: attr(data-max); position: absolute; @include px_and_rem(bottom, 0.2, $multiplier); @include px_and_rem(right, 0.4, $multiplier); } } With box-shadow and border, we can't use the px_and_rem mixin, so we duplicated these properties using px first and then rem. The following screenshot shows the result: Gauge tick marks How to handle tick marks? One method would be by using images, but another interesting alternative is to benefit from multiple background support and create those tick marks out of gradients. For example, to create a vertical mark, we can use the following within the div[data-gauge] selector: linear-gradient(0deg, transparent 46%, rgba(99, 99, 99, 0.5) 47%, rgba(99, 99, 99, 0.5) 53%, transparent 54%) Basically, we define a very small gradient between transparent and another color in order to obtain the tick mark. That's the first step, but we're yet to deal with the fact that each tick mark must be defined with a different angle. We can solve this problem by introducing a SASS function that takes the number of tick marks to print and iterates up to that number while also adjusting the angles of each mark. Of course, we also have to take care of experimental vendor prefixes, but we can count on Compass for that. The following is the function. We can create a new file called scss/_gauge.scss for this and other gauge-related functions; the leading underscore is to tell SASS to not create a .css file out of this .scss file, because it will be included in a separate file. @function gauge-tick-marks($n, $rest){ $linear: null; @for $i from 1 through $n { $p: -90deg + 180 / ($n+1) * $i; $linear: append($linear, linear-gradient( $p, transparent 46%, rgba (99,99,99,0.5) 47%, rgba(99,99,99,0.5) 53%, transparent 54%), comma); } @return append($linear, $rest); } We start with an empty string adding the result of calling the linear-gradient Compass function, which handles experimental vendor prefixes, with an angle that varies based on the current tick mark index. To test this function out, we first need to include _gauge.scss in application.scss: @import "gauge.scss"; Next, we can insert the function call within the div[data-gauge] selector in application.scss, specifying the number of tick marks required: @include background(gauge-tick-marks(11,null)); The background function is also provided by Compass and it is just another mechanism to deal with experimental prefixes. Unfortunately, if we reload the projects the results are far from expected: Although we can see a total of 11 stripes, they are of the wrong sizes and in the wrong position. To resolve this, we will create some functions to set the correct values for background-size and background-position. Dealing with background size and position Let's start with background-size, the easiest. Since we want each of the tick marks to be exactly 1rem in size, we can proceed by creating a function that prints 1rem 1rem as many times as the number of the passed parameter; so let's add the following code to _gauge.scss: @function gauge-tick-marks-size($n, $rest){ $sizes: null; @for $i from 1 through $n { $sizes: append($sizes, 1rem 1rem, comma); } @return append($sizes, $rest, comma); } We already noticed the append function; an interesting thing to know about it is that the last parameter of this function lets us decide if some letter must be used to concatenate the strings being created. One of the available options is comma, which perfectly suits our needs. Now, we can add a call to this function within the div[data-gauge] selector: background-size: gauge-tick-marks-size(11, null); And the following is the result: Now the tick marks are of the right size, but they are displayed one above the other and are repeated all across the element. To avoid this behavior, we can simply add background-repeat: no-repeat just below the previous instruction: background-repeat: no-repeat; On the other hand, to handle the position of the tick marks we need another SASS function; this time it's a little more complex and involves a bit of trigonometry. Each gradient must be placed in the function of its angle—x is the cosine of that angle and y the sine. The sin and cos functions are provided by Compass, we need just to handle the shift, because they are referred to the center of the circle whereas our css property's origin is in the upper-left corner: @function gauge-tick-marks-position($n, $rest){ $positions: null; @for $i from 1 through $n { $angle: 0deg + 180 / ($n+1) * $i; $px: 100% * ( cos($angle) / 2 + 0.5 ); $py: 100% * (1 - sin($angle)); $positions: append($positions, $px $py, comma); } @return append($positions, $rest, comma); } Now we can go ahead and add a new line inside the div[data-gauge] selector: background-position: gauge-tick-marks-position(11, null); And here's the much-awaited result: The next step is to create a @mixin directive to hold these three functions together, so we can add the following to _gauge.scss: @mixin gauge-background($ticks, $rest_gradient, $rest_size, $rest_position) { @include background-image( gauge-tick-marks($ticks, $rest_gradient) ); background-size: gauge-tick-marks-size($ticks, $rest_size); background-position: gauge-tick-marks-position($ticks, $rest_position); background-repeat: no-repeat; } And replace what we placed inside div[data-gauge] in this article with a single invocation: @include gauge-background(11, null, null, null ); We've also left three additional parameters to define extra values for background, background-size, and background-position, so we can, for example, easily add a gradient background: @include gauge-background(11, radial-gradient(50% 100%, circle, rgb(255,255,255), rgb(230,230,230)), cover, center center ); And following is the screenshot: Creating the arrow To create an arrow we can start by defining the circular element in the center of the gauge that holds the arrow. This is easy and doesn't introduce anything really new; here's the code that needs to be nested within the div[data-gauge] selector: div[data-arrow]{ position: absolute; @include px_and_rem(width, 2, $multiplier); @include px_and_rem(height, 2, $multiplier); @include px_and_rem(border-radius, 5, $multiplier); @include px_and_rem(bottom, -1, $multiplier); left: 50%; @include px_and_rem(margin-left, -1, $multiplier); box-sizing: border-box; border: #{0.05 * $multiplier} solid rgb(99,99,99); border: 0.05rem solid rgb(99,99,99); background: #fcfcfc; } The arrow itself is a more serious business; the basic idea is to use a linear gradient that adds a color only to half the element starting from its diagonal. Then we can rotate the element in order to move the pointed end at its center. The following is the code that needs to be placed within div[data-arrow]: &:before{ position: absolute; display: block; content: ''; @include px_and_rem(width, 4, $multiplier); @include px_and_rem(height, 0.5, $multiplier); @include px_and_rem(bottom, 0.65, $multiplier); @include px_and_rem(left, -3, $multiplier); background-image: linear-gradient(83.11deg, transparent, transparent 49%, orange 51%, orange); background-image: -webkit-linear-gradient(83.11deg, transparent, transparent 49%, orange 51%, orange); background-image: -moz-linear-gradient(83.11deg, transparent, transparent 49%, orange 51%, orange); background-image: -o-linear-gradient(83.11deg, transparent, transparent 49%, orange 51%, orange); @include apply-origin(100%, 100%); @include transform2d( rotate(-3.45deg)); box-shadow: 0px #{-0.05 * $multiplier} 0 rgba(0,0,0,0.2); box-shadow: 0px -0.05rem 0 rgba(0,0,0,0.2); @include px_and_rem(border-top-right-radius, 0.25, $multiplier); @include px_and_rem(border-bottom-right-radius, 0.35, $multiplier); } To better understand the trick behind this implementation, we can temporarily add border: 1px solid red within the &:before selector to the result and zoom a bit: Moving the arrow Now we want to position the arrow to the correct angle depending on the data-percent attribute value. To do so we have to take advantage of the power of SASS. In theory the CSS3 specification would allow us to valorize some properties using values taken from attributes, but in practice this is only possible while dealing with the content property. So what we're going to do is create a @for loop from 0 to 100 and print in each iteration a selector that matches a defined value of the data-percent attribute. Then we'll set a different rotate() property for each of the CSS rules. The following is the code; this time it must be placed within the div[data-gauge] selector: @for $i from 0 through 100 { $v: $i; @if $i < 10 { $v: '0' + $i; } &[data-percent='#{$v}'] > div[data-arrow]{ @include transform2d(rotate(#{180deg * $i/100})); } } If you are too scared about the amount of CSS generated, then you can decide to adjust the increment of the gauge, for example, to 10: @for $i from 0 through 10 { &[data-percent='#{$i*10}'] > div[data-arrow]{ @include transform2d(rotate(#{180deg * $i/10})); } } And the following is the result:    
Read more
  • 0
  • 0
  • 4224

article-image-creating-new-zen-cart-template
Packt
08 Oct 2009
11 min read
Save for later

Creating a new Zen Cart Template

Packt
08 Oct 2009
11 min read
Creating A File System Let us start building a new template for Zen Cart by creating a new folder under includes/templates/. Let us name it Packt (or whatever you like). But remember to use underscore instead of spaces in a long name. Avoid using Book Shop. Instead, use book_shop or BookShop. images' folder —will contain all the images needed for the template. css' folder — will contain all the CSS files for the template. It's better to copy all the files from the includes/templates/template_default/css directory to this css folder. common' folder — will contain the common files for the template. You may copy the files from the includes/templates/template_default/common folder, and edit those to suit your needs. sideboxes'folder — will contain module-specific sideboxes. Here, you can add new sideboxes, which you are going to use. templates folder — contains page-specific templates. Whenever you want to change a page's layout, copy the template for that page to this directory and modify it as required. Information regarding a template is located in the template_info.php file. You need to create a new template_info.php file for the new template. Copy the file called includes/templates/template_default/template_info.php into the new template folder, and then open the template_info.php file in your favorite text editor. Change the text between each set of single quotes to suit your new template. <?php $template_name = 'Packt Publishing'; $template_version = 'Version 1.0'; $template_author = 'Suhreed Sarkar'; $template_description = 'This template is designed for Packt Publishing'; $template_screenshot = ''; ?> Remember to keep the single quotes. Your template name does not need to be identical to your folder name, and you can use spaces to make it read well, but it is best to keep them similar. Leave the space between the quotes for the template screenshot field empty for now, as you don't have one yet. When you've finished, your new file structure should appear as follows: Open your Admin panel and navigate to Tools | Template Selection. Click the Edit button, then choose Packt Publishing from the drop-down menu and click the Update button. Now, navigate to Tools | Layout boxes controller, and click the Reset button at the bottom of the page. Your new template is now enabled and ready to be customized. Using Overrides When building a new template for Zen Cart, you can use its powerful overriding feature. Overriding means using some template as the base and extending it by adding different properties through separate templates. For example, you may want to make some modifications to the default template—template_default. You could modify the files in the template_default directory to do this. But due to its overriding character, you can add the changes in the new template, say packt, which will apply the changes to the shop. In fact, you can override any file in the path includes/templates/ template_default. Files in this directory generally determine the layout and the HTML formatting of your web pages. By default, Zen Cart has two standard templates: template_default and classic, both of which are located in the includes/templates/ folder. Out of these two standard templates, only template_default contains a full set of files. Every other template contains only the files that differ from template_default. If your template does not contain a particular file, Zen Cart will pull that file from template_default. Graphics You need to add your templates graphics to the appropriate folders. The header image, logo, background image, background image for sidebox headings, and so on should be placed in the images directory under your template directory. If you want to change the buttons and icons, create the graphic files in the GIF, JPG or PNG format and put them in the /includes/templates/template_name/buttons/language_name folder. Then, update the button_names.php file to define the button image file name, and the ALT texts for those images. Sideboxes You do not need to copy existing sideboxes from the template_default directory, as these will automatically be displayed. If you are planning to develop a new sidebox, put the template for that sidebox in the sideboxes folder under your template directory. A sidebox consists of three files, which are located in the includes directory: modules/sideboxes/template_name/name_of_sidebox.php' languages/english/extra_definitions/template_name/ name_of_sidebox_defines.php ' templates/template_name/sideboxes/tpl_name_of_sidebox.php ' You need to replace template_name and name_of_sidebox with you template name and the sidebox name respectively. For example, let us build a sidebox named my_sidebox. Then, my_sidebox.php file will read like this: <?php $show_my_sidebox = true; if ($show_my_sidebox == true){ require($template->get_template_dir('tpl_my_sidebox.php', DIR_WS_TEMPLATE, $current_page_base,'sideboxes'). '/tpl_my_sidebox.php'); $title = BOX_HEADING_MY_SIDEBOX; $left_corner = false; $right_corner = false; $right_arrow = false; require($template->get_template_dir($column_box_default, DIR_WS_TEMPLATE, $current_page_base,'common') . '/' . $column_box_default); } ?> This page actually defines what is to be shown in that sidebox. Note that this page also includes the corresponding template file. Here, we have used a constant BOX_HEADING_MY_SIDEBOX. You need to define this in the includes/languages/english/extra_definitions/packt/my_sidebox_defines.php file. This file will look like this: <?php define('BOX_HEADING_MY_SIDEBOX', 'My Sidebox'); ?> Now, you have to build its template file includes/templates/packt/sideboxes/tpl_my_sidebox.php, which will read as: <?php $content = "This is my first Sidebox. I have created it in 5 minutes. Although it is not of practical use yet, I hope I can eventually build a good sidebox."; ?> If you have created these files for the packt template, you can try it by going to Tools | Layout Boxes Controller in the administration panel. From here, turn the sidebox ON and set it up to display in the left or the right side column. This sidebox will look like the following figure. Stylesheets All stylesheets for your new template should be placed in the /includes/templates/template_name/css folder. You should follow stylesheet naming conventions. It is a good idea to copy an old stylesheet and then modify it to suit your needs. You can have multiple stylesheets for your shop you can even add a stylesheet for each page. As a design rule, try to keep the declarations minimal, simple, and self explanatory. Try to restrain yourself from changing the class and ID names in the core files. Creating and Modifying Email Templates As a store owner, you need to send several mails to your existing and potential customers. All these emails use some templates that reside in the /email folder under the Zen Cart installation directory. To change these emails to your style, you may edit these templates. The email's structure is determined in one of two ways. If you are sending plain text emails, the email structure is determined by the way you put together the various items (customer greeting, order number, link to detailed invoice, and so on) in a string variable that is then passed to the zen_mail() function. If you are sending HTML emails, the structure is determined by the template you use. Text Email Template You can rearrange, add, or delete items in a plain text email. To do so, you will need to edit the Zen Cart files where the email is created. For example, if you want to edit the order confirmation email, you will need to edit the file includes/classes/order.php. In your example, open up includes/classes/order.php and scroll down to the bottom of the file, in the function send_order_email(). There, you will see the lines that construct the plain text email message: [Line 827]$email_order = EMAIL_TEXT_HEADER . EMAIL_TEXT_FROM . STORE_NAME . "nn" . $this->customer['firstname'] . ' ' . $this->customer['lastname'] . "nn" . EMAIL_THANKS_FOR_SHOPPING . "n" . EMAIL_DETAILS_FOLLOW . "n" . EMAIL_SEPARATOR . "n" . EMAIL_TEXT_ORDER_NUMBER . ' ' . $zf_insert_id . "n" . EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "n" . EMAIL_TEXT_INVOICE_URL . ' ' . zen_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $zf_insert_id, 'SSL' [Line 848]$email_order .= zen_db_output($this->info['comments']) . "nn";[Line 855]$email_order .= EMAIL_TEXT_PRODUCTS . "n" . EMAIL_SEPARATOR . "n" . $this->products_ordered . EMAIL_SEPARATOR . "n"; In this file, the variable that holds the plain text email message is called $email_order. It generally has a different name in each file, such as $email or $email_text. Whatever its name, this is the place where you will make your changes. You can add, delete, and rearrange the order of the items to suit your wishes. HTML Email Templates HTML Email templates have two parts: embedded CSS and HTML codes. You may be surprised to see the embedded stylesheet in each mail template, and may want to know why linked stylesheets have not been used. One reason for not using the linked stylesheet is that you may not know how the email clients will behave. Most email clients used today can handle HTML emails and stylesheets to some extent. But there is no guarantee that every customer will have an email client that can retrieve linked stylesheets and render the emails in the desired format. Stylesheets The first portion of the email template is devoted to defining styles for different parts of the mail. Open the /email/email_template_welcome.html file in your favorite text editor to examine the stylesheet in an email template. The stylesheet in this template will appear as follows: <style type="text/css">.body {background-color:#ffffff; color:#000000; font-family:Verdana, Arial, Helvetica, sans-serif;}....header {font-size:10px; padding:0px; width:550px;}.content {font-size:10px; padding:5px; width:550px;}.content-line {padding:5px;}.coupon-block { padding: 5px; border: 1px #cccccc solid; background-color: #FFFF99; }....disclaimer1 a:link {color:#666666;}.disclaimer1 a:visited {color:#666666;}.disclaimer2 { color: #666666; padding: 5px; }.copyright { border-bottom: 0px #9a9a9a solid; padding: 5px; }</style> Style declarations in this stylesheet are straight-forward. First, it has defined style for the body and hyperlinks. Then, it defines the content and email related styles. Most of the style names are self-explanatory. You will find the HTML blocks with these names in the template. HTML with variables The main part of the email template is the HTML code with style classes and variables. The following are some of the variables used to construct content for the email: $EMAIL_GREETING $EMAIL_WELCOME $COUPON_BLOCK $GV_BLOCK $EMAIL_MESSAGE_HTML $EMAIL_CONTACT_OWNER $EMAIL_CLOSURE $EMAIL_FOOTER_COPYRIGHT $EMAIL_DISCLAIMER $EMAIL_SPAM_DISCLAIMER $EXTRA_INFO These variables are defined in several PHP files, such as create_account.php. Once you have found the files that need to be edited, you may want to add a definition for your new HTML item to each one. For example, you have added an item called $EMAIL_HOURS_OF_OPERATION to the email_template_order_status.html template. One of the files that you will need to edit is admin/orders.php. Find the part of that file where the email message is being constructed. In this case, it begins around line 100. You can see that the HTML message is constructed with several statements such as: $html_msg['EMAIL_CUSTOMERS_NAME'] = $check_status->fields['customers_name'];$html_msg['EMAIL_TEXT_ORDER_NUMBER'] = EMAIL_TEXT_ORDER_NUMBER . ' ' . $oID; All you need to do is add a new statement under all of these, to define your new item: $html_msg['EMAIL_HOURS_OF_OPERATION'] = 'We are open from 9 AM to 5 PMevery day of the week.'; Use a $ in front of the name of your new item in the HTML template, but do not use the $ where you define it. To change the text displayed in your emails, edit the corresponding language file. You can change an existing text, or add a new one (if you've added it to your email structure). You add or change text values using the define() statements: define(EMAIL_LOVELY_YOU_DROPPED_BY,'We are just so immeasurably delighted that you stopped by our store today!'); There is another language file you need to modify when altering text for your emails, includes/languages/english/email_extras.php. This file contains several text strings common to all emails sent from your store. Summary Thus we have seen how to create new template using Zen Cart.   If you have read this article you may be interested to view : Integrating Zen Cart with Content Management Systems Installing Zen Cart Troubleshooting Zen Cart  
Read more
  • 0
  • 0
  • 4215

article-image-aspnet-4-social-networking-implementing-complete-messaging-system
Packt
25 Mar 2011
12 min read
Save for later

ASP.NET 4 Social Networking: Implementing a Complete Messaging System

Packt
25 Mar 2011
12 min read
Problem A basic messaging system should be able to manage messages, senders and recipients, folders that contain the messages, and email notifications. In our case, we are going to try and keep things simple where it makes sense to do so, but in one area, we will do things in a more complicated way simply because it will result in less wear and tear on the overall system. This is how the messages will be delivered to the users. Rather than following a standard email messaging system where each person gets a physical copy of a message, we are going to build our system in the same way that the MS Exchange server works. We are going to make one copy of a message and subscribe users to that message. So rather than have 50 messages for 50 recipients, we will have one message and 50 recipient subscriptions. The next problem lies in building a WYSIWYG (what you see is what you get) messaging editor. For this feature, there are many open source WYSIWYG editors; we will use one of those to save us a bit of time. We will be using one of the popular editors—X INHA. This editor can be downloaded for free here at http://xinha.webfactional.com/. You may have seen this editor already as it is widely used across many popular community sites. Design Let's take a look at the design of these features. Messages Messages are the core of any messaging system. Generally, a message would contain details like the sender of the message, receiver of the message, and other metadata like time sent, server from where it was sent, etc. and the message, subject, and body. In our case, the message will contain the sender, subject, body, and the data sent. It will also contain one additional field, i.e. the type of message (message, friend request, and so on). We will need to create a page that allows a user to compose a new message (as seen in the image at the start of this article). This interface should also allow a user to add his/her friends easily rather than force them to remember everyone. Also, this interface should allow a user to quickly snap together some HTML without ever having to look at HTML. This can be accomplished with a WYSIWYG editor. Recipients As we have already discussed that we are going to move some of the complexity away from the message, following a subscription model instead, you will find that most of the complexity of this system lies around the recipient concepts. In this case, the recipient subscription is what will be contained in a folder and will have a read status. With this design, we will remove some of the burden from the database. The overhead of doing this of course means that we now need to manage our data closely, as it is kept in many pieces. A more simple design that would result in more copies of data to be managed would be to create one message for each recipient. This is easier as each message can easily be deleted and moved around without having to worry about the copies of that message of the other recipients. Having said that, if the message is quite large, and more importantly if we were to allow file attachments, all the copies of the messages would be identical for each recipient. This would quickly bloat your database! Solution Now let's take a look at our solution. Implementing the database First let's take a look at what tables are needed: Messages A message will primarily be made up of the subject and its body. In addition to that we will need to know what type of message we are sending so that we can do some more fancy things in the UI down the road. In addition to this, we are going to maintain who owns/created the message at this level. There aren't really any major complexities to note here other than the fact that the Body is made up of a varchar(MAX) data type. If you feel this is too large for your system, feel free to make it anything you are comfortable with. The value you eventually use will drive the message for your system. MessageTypes Message Types allows us to assign a type to our messages. This is purely a lookup table that will allow us to know what the types are during queries. We will keep a list of enums in the code to make the lookups easier from that end. MessageRecipients A message recipient is simply the receiving party to the message. But as we try to minimize the data that we manage in our system, the message recipient is also a very important part of the message. In our case, it is the receiving party as well as all the things that the receiving party does with their subscription of that message. We will use this subscription to denote which folder the receiver is keeping the message in, and whether the receiver has read the message or not. Also, if the receiver chooses to delete the message, he/she can just delete the subscription to a message (unless they are the last subscription, in which case we will delete the message as well). The SQL for this subscription is actually quite straightforward. It tracks a relationship to the message, a relationship to the receiver, which folder the subscription is currently in, and the status of the message for this receiver. MessageRecipientTypes The message recipient type allows us to track the receiver of this message addressed in the TO, CC, or BCC fields. Initially, our interface will only have a TO field. We should add this bit of metadata though just in case we want to expand our capabilities down the road! This is another example of a lookup table that we might need to use in the SQL queries. In our case, we will have an enum defined that maintains this lookup for us on the code side. MessageStatusTypes MessageStatusTypes allows us to track what a recipient is doing with his/her copy of the message, whether they have read the message, replied to the message, and so on. This is primarily so that we can change the UI to refiect its status to the recipient. However, we could also create a dashboard down the road for the senders of the messages to know whether their message was read or not and by whom (think of all the big brother things one could do...but probably should not do!). MessageFolders MessageFolders in our first round of implementation will simply hold copies of new messages in the Inbox and copies of sent messages in the Sent folder. We will also have a trash folder and a spam folder. That said, we always wanted to build a system with the future in mind if it doesn't require a lot of extra work, and so we have also baked in the concept of a user being able to create and manage his/her own folders. Therefore, rather than just see the MessageFolders table as another lookup table, you will see that there is an IsSystem fiag to denote which folders are to be seen system-wide. And you will see an AccountID column for custom folders so that we know who owns which folders. Creating the relationships Once all the tables are created, we can create the relationships. For this set of tables, we have relationships between the following tables: Messages and MessageRecipients Messages and Accounts Messages and MessageTypes MessageRecipients and MessageRecipientTypes MessageRecipients and MessageFolders MessageRecipients and MessageStatusTypes Setting up the data access layer The data access layer in this case is very straightforward. Open up your Fisharoo.edmx file and add all of your new message-oriented tables. Once you save this, you should now have a list of new domain objects in your arsenal (see the previous screenshot). Building repositories With these new tables come some additional repositories. We will create the following repositories. MessageRepository MessageRecipientRepository MessageFolderRepository A detailed creation of repositories is out of the scope of this article. We will create a method for selecting a single entity by ID, a group of entities by their parents, saving entities, and deleting entities. Having said that, there are a couple of methods that have something special in the set of repositories. As we are using message subscriptions, we don't necessarily want to delete recipients haphazardly. We may want to delete a recipient, and if that recipient is the last recipient with a subscription to a message, we may also want to delete the message. On the other end of the spectrum, if we do delete a message, we may also want to remove all the recipient subscriptions. In addition to these different ways of deleting data, we will also run into a scenario where selecting a single entity from our repositories won't be quite good enough. So in this case, we have created an aggregate class that will allow us to select several entities at once for use in our inbox scenarios. MessageRepository When we think of a standard inbox, we know that we need to see the messages that we have, who sent them, when they were sent, and at least the subject of their message. In this case, we have discussed two different entities here. When we think about the fact that we also need to know who they were sent to, we have added a third entity. While we could run three separate queries for this data, it would be better for us to run one query (as we would have done in the old days) and return the data that we need in one shot. What do we do? In this case, we need to create an aggregate. This is a class that contains other entities. We will therefore create a MessageWithRecipient class that will contain the sender's account info, the message, and the recipient. This should provide us with enough data to represent messages in our inbox view later. Before we write any queries, we first need to create the aggregate. //Fisharoo/DataAccess/MessageWithRecipient.cs namespace Fisharoo.DataAccess { public class MessageWithRecipient { public Account Sender { get; set; } public Message Message { get; set; } public MessageRecipient MessageRecipient{ get; set; } } } With this aggregate in place we can now turn our attention to the repository that will get all this data for us. //Fisharoo/DataAccess/Repositories/MessageRepository.cs public List<MessageWithRecipient> GetMessagesByAccountID(Int32 AccountID, Int32 PageNumber, MessageFolders Folder) { List<MessageWithRecipient> result = new List<MessageWithRecipient>(); using(FisharooDataContext dc = conn.GetContext()) { IEnumerable<MessageWithRecipient> messages = (from r in dc.MessageRecipients join m in dc.Messages on r.MessageID equals m.MessageID join a in dc.Accounts on m.SentByAccountID equals a.AccountID where r.AccountID == AccountID && r.MessageFolderID == (int)Folder orderby m.CreateDate descending select new MessageWithRecipient() { Sender = a, Message = m, MessageRecipient = r }).Skip((PageNumber - 1)*10).Take(10); result = messages.ToList(); } return result; } This is a fun method! This method involves selecting a list of our MessageWithRecipient aggregate objects. The LINQ query is joining all the tables that we need and selecting a new instance of the MessageWithRecipient aggregate, that is then populated with the three classes that we need in the aggregate. Additionally, we have introduced some paging logic with the .Skip and .Take methods to produce a subset of the MessageWithRecipient objects. In addition to the selection method above, we also need to discuss the delete method for this repository. As we have the data holding a subscription to our message data, it is important that we first remove all the subscriptions prior to removing the message itself. //Fisharoo/DataAccess/Repositories/MessageRepository.cs public void DeleteMessage(Message message) { using (FisharooDataContext dc = conn.GetContext()) { IEnumerable<MessageRecipient> recipients = dc.MessageRecipients .Where(mr => mr.MessageID == message.MessageID); foreach (MessageRecipient mr in recipients) { dc.MessageRecipients.DeleteObject(mr); } dc.Messages.DeleteObject(message); dc.SaveChanges(); } } This is easily accomplished by retrieving all the MessageRecipients for the needed MessageID from the MessageRecipients in DataContext. Once we have the list, we iterate over each recipient and remove it from DataContext's MessageRecipients list. Finally, we delete the message and save changes. MessageRecipientRepository The message recipient repository is considerably easier. It simply has an altered delete statement to adjust for the fact that if we delete the last subscription to a message, it will amount to deleting the message. //Fisharoo/DataAccess/Repositories/MessageRecipientRepository.cs public void DeleteMessageRecipient(MessageRecipient messageRecipient) { using (FisharooDataContext dc = conn.GetContext()) { dc.MessageRecipients.DeleteObject(dc.MessageRecipients.Where (mr=> mr.MessageRecipientID.Equals (messageRecipient.MessageRecipientID)) .FirstOrDefault()); //if the last recipient was deleted //...also delete the message int RemainingRecipientCount = dc.MessageRecipients.Where(mr => mr.MessageID == messageRecipient.MessageID).Count(); if (RemainingRecipientCount == 0) { dc.Messages.DeleteObject(dc.Messages.Where(m => m.MessageID == messageRecipient.MessageID). FirstOrDefault()); } dc.SaveChanges(); } } In this method, we delete the recipient in question. We then get a count of the remaining recipients for the message, which has the last recipient removed. If that count is zero, then there are no more recipients remaining for that message. In that case we perform a delete on that message and remove it from the system as well.
Read more
  • 0
  • 0
  • 4213
article-image-migrating-wordpress-blog-middleman-and-deploying-amazon-s3-part2
Mike Ball
28 Nov 2014
9 min read
Save for later

Part 2: Migrating a WordPress Blog to Middleman and Deploying to Amazon S3

Mike Ball
28 Nov 2014
9 min read
Part 2: Migrating WordPress blog content and deploying to production In part 1 of this series, we created middleman-demo, a basic Middleman-based blog. Part 1 addressed the benefits of a static site, setting up a Middleman development environment, Middleman’s templating system, and how to configure a Middleman project to support a basic blogging functionality. Now that middleman-demo is configured for blogging, let’s export old content from an existing WordPress blog, compile the application for production, and deploy to a web server. In this part, we’ll cover the following: Using the wp2middleman gem to migrate content from an existing WordPress blog Creating a Rake task to establish an Amazon Web Services S3 bucket Deploying a Middleman blog to Amazon S3 Setting up a custom domain for an S3-hosted site If you didn’t follow part 1, or you no longer have your original middleman-demo code, you can clone mine and check out the part2 branch: $ git clone http://github.com/mdb/middleman-demo && cd middleman-demo && git checkout part2 Export your content from Wordpress Now that middleman-demo is configured for blogging, let’s export old content from an existing Wordpress blog. Wordpress provides a tool through which blog content can be exported as an XML file, also called a WordPress “eXtended RSS” or “WXR” file. A WXR file can be generated and downloaded via the Wordpress admin’s Tools > Export screen, as is explained in Wordpress’s WXR documentation. In absence of a real Wordpress blog, download middleman_demo.wordpress.xml file, a sample WXR file: $ wget www.mikeball.info/downloads/middleman_demo.wordpress.xml Migrating the Wordpress posts to markdown To migrate the posts contained in the Wordpress WXR file, I created wp2middleman, a command line tool to generate Middleman-style markdown files from the posts in a WXR. Install wp2middleman via Rubygems: $ gem install wp2middleman wp2middleman provides a wp2mm command. Pass the middleman_demo.wordpress.xml file to the wp2mm command: $ wp2mm middleman_demo.wordpress.xml If all goes well, the following output is printed to the terminal: Successfully migrated middleman_demo.wordpress.xml wp2middleman also produced an export directory. The export directory houses the blog posts from the middleman_demo.wordpress.xml WXR file, now represented as Middleman-style markdown files: $ ls export/ 2007-02-14-Fusce-mauris-ligula-rutrum-at-tristique-at-pellentesque-quis-nisl.html.markdown 2007-07-21-Suspendisse-feugiat-enim-vel-lorem.html.markdown 2008-02-20-Suspendisse-rutrum-Suspendisse-nisi-turpis-congue-ac.html.markdown 2008-03-17-Duis-euismod-purus-ac-quam-Mauris-tortor.html.markdown 2008-04-02-Donec-cursus-tincidunt-libero-Nam-blandit.html.markdown 2008-04-28-Etiam-nulla-nisl-cursus-vel-auctor-at-mollis-a-quam.html.markdown 2008-06-08-Praesent-faucibus-ligula-luctus-dolor.html.markdown 2008-07-08-Proin-lobortis-sapien-non-venenatis-luctus.html.markdown 2008-08-08-Etiam-eu-urna-eget-dolor-imperdiet-vehicula-Phasellus-dictum-ipsum-vel-neque-mauris-interdum-iaculis-risus.html.markdown 2008-09-08-Lorem-ipsum-dolor-sit-amet-consectetuer-adipiscing-elit.html.markdown 2013-12-30-Hello-world.html.markdown Note that wp2mm supports additional options, though these are beyond the scope of this tutorial. Read more on wp2middleman’s GitHub page. Also note that the markdown posts in export are named *.html.markdown and some -- such as SOME EXAMPLE TODO -- contain the HTML embedded in the original Wordpress post. Middleman supports the ability to embed multiple languages within a single post file. For example, Middleman will evaluate a file named .html.erb.markdown first as markdown and then ERb. The final result would be HTML. Move the contents of export to source/blog and remove the export directory: $ mv export/* source/blog && rm -rf export Now, assuming the Middleman server is running, visiting http://localhost:4567 lists all the blog posts migrated from Wordpress. Each post links to its permalink. In the case of posts with tags, each tag links to a tag page. Compiling for production Thus far, we’ve been viewing middleman-demo in local development, where the Middleman server dynamically generates the HTML, CSS, and JavaScript with each request. However, Middleman’s value lies in its ability to generate a static website -- simple HTML, CSS, JavaScript, and image files -- served directly by a web server such as Nginx or Apache and thus requiring no application server or internal backend. Compile middleman-demo to a static build directory: $ middleman build The resulting build directory houses every HTML file that can be served by middleman-demo, as well as all necessary CSS, JavaScript, and images. Its directory layout maps to the URL patterns defined in config.rb. The build directory is typically ignored from source control. Deploying the build to Amazon S3 Amazon Web Services is Amazon’s cloud computing platform. Amazon S3, or Simple Storage Service, is a simple data storage service. Because S3 “buckets” can be accessible over HTTP, S3 offers a great cloud-based hosting solution for static websites, such as middleman-demo. While S3 is not free, it is generally extremely affordable. Amazon charges on a per-usage basis according to how many requests your bucket serves, including PUT requests, i.e. uploads. Read more about S3 pricing on AWS’s pricing guide. Let’s deploy the middleman-demo build to Amazon S3. First, sign up for AWS. Through AWS’s web-based admin, create an IAM user and locate the corresponding “access key id” and “secret access key:” 1: Visit the AWS IAM console. 2: From the navigation menu, click Users. 3: Select your IAM user name. 4: Click User Actions; then click Manage Access Keys. 5: Click Create Access Key. 6: Click Download Credentials; store the keys in a secure location. 7: Store your access key id in an environment variable named AWS_ACCESS_KEY_ID: $ export AWS_ACCESS_KEY_ID=your_access_key_id 8: Store your secret access key as an environment variable named AWS_SECRET_ACCESS_KEY: $ export AWS_SECRET_ACCESS_KEY=your_secret_access_key Note that, to persist these environment variables beyond the current shell session, you may want to automatically set them in each shell session. Setting them in a file such as your ~/.bashrc ensures this: export AWS_ACCESS_KEY_ID=your_access_key_id export AWS_SECRET_ACCESS_KEY=your_secret_access_key Creating an S3 bucket with Ruby To deploy to S3, we’ll need to create a “bucket,” or an S3 endpoint to which the middleman-demo’s build directory can be deployed. This can be done via AWS’s management console, but we can also automate its creation with Ruby. We’ll use the aws-sdk Ruby gem and a Rake task to create an S3 bucket for middleman-demo. Add the aws-sdk gem to middleman-demo’s Gemfile: gem 'aws-sdk Install the new gem: $ bundle install Create a Rakefile: $ touch Rakefile Add the following Ruby to the Rakefile; this code establishes a Rake task -- a quick command line utility -- to automate the creation of an S3 bucket: require 'aws-sdk' desc "Create an AWS S3 bucket" task :s3_bucket, :bucket_name do |task, args| s3 = AWS::S3.new(region: 'us-east-1) bucket = s3.buckets.create(args[:bucket_name]) bucket.configure_website do |config| config.index_document_suffix = 'index.html' config.error_document_key = 'error/index.html' end end From the command line, use the newly-established :s3_bucket Rake task to create a unique S3 bucket for your middleman-demo. Note that, if you have an existing domain you’d like to use, your bucket should be named www.yourdomain.com: $ rake s3_bucket[some_unique_bucket_name] For example, I named my S3 bucket www.middlemandemo.com by entering the following: $ rake s3_bucket[www.middlemandemo.com] After running rake s3_bucket[YOUR_BUCKET], you should see YOUR_BUCKET amongst the buckets listed in your AWS web console. Creating an error template Our rake task specifies a config.error_document_key whose value is error/index.html. This configures your S3 bucket to serve an error.html for erroring responses, such as 404s. Create an source/error.html.erb template: $ touch source/error.html.erb And add the following: --- title: Oops - something went wrong --- <h2><%= current_page.data.title %></h2> Deploying to your S3 bucket With an S3 bucket established, the middleman-sync Ruby gem can be used to automate uploading middleman-demo builds to S3. Add the middleman-sync gem to the Gemfile: gem ‘middleman-sync’ Install the middleman-sync gem: $ bundle install Add the necessary middleman-sync configuration to config.rb: activate :sync do |sync| sync.fog_provider = 'AWS' sync.fog_region = 'us-east-1' sync.fog_directory = '<YOUR_BUCKET>' sync.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID'] sync.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] end Build and deploy middleman-demo: $ middleman build && middleman sync Note: if your deployment fails with a ’post_connection_check': hostname "YOUR_BUCKET" does not match the server certificate (OpenSSL::SSL::SSLError) (Excon::Errors::SocketError), it’s likely due to an open issue with middleman-sync. To work around this issue, add the following to the top of config.rb: require 'fog' Fog.credentials = { path_style: true } Now, middlemn-demo is browseable online at http://YOUR_BUCKET.s3-website-us-east-1.amazonaws.com/ Using a custom domain With middleman-demo -- deployed to an S3 bucket whose name matches a domain name, a custom domain can be configured easily. To use a custom domain, log into your domain management provider and add a CNAME mapping your domain to www.yourdomain.com.s3-website-us-east-1.amazonaws.com.. While the exact process for managing a CNAME varies between domain name providers, the process is generally fairly simple. Note that your S3 bucket name must perfectly match your domain name. Recap We’ve examined the benefits of static site generators and covered some basics regarding Middleman blogging. We’ve learned how to use the wp2middleman gem to migrate content from a Wordpress blog, and we’ve learned how to deploy Middleman to Amazon’s cloud-based Simple Storage Service (S3). About this author Mike Ball is a Philadelphia-based software developer specializing in Ruby on Rails and JavaScript. He works for Comcast Interactive Media where he helps build web-based TV and video consumption applications.
Read more
  • 0
  • 0
  • 4206

article-image-microsoft-dynamics-nav-2009-using-journals-and-entries-custom-application
Packt
10 Jun 2010
9 min read
Save for later

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

Packt
10 Jun 2010
9 min read
(Further on Microsoft Dynamics NAV:here.) Designing a journal Now it is time to start on the product part of the Squash Application. In this part we will no longer reverse engineer in detail. We will learn how to search in the standard functionality and reuse parts in our own software. For this part we will look at resources in Microsoft Dynamics NAV. Resources are similar to use products as Items but far less complex making it easier to look and learn. Squash Court master data Our company has 12 courts that we want to register in Microsoft Dynamics NAV. This master data is comparable to resources so we'll go ahead and copy this functionality. Resources are not attached to umbrella data like the vendor/squash player tables. We need the number series again so we'll add a new number series to our squash setup table. The Squash Court table should look like this after creation: Chapter objects With this chapter some objects are required. A description of how to import these objects can be found in the Appendix. After the import process is completed make sure that your current database is the default database for the role tailored client and run Page 123456701, Squash Setup. From this page select the Action Initialise Squash Application. This will execute the C/AL code in the InitSquashApp function of this page, which will prepare demo data for us to play with. The objects are prepared and tested in a Microsoft Dynamics NAV 2009 SP1 W1 database. Reservations When running a squash court we want to be able to keep track of reservations.Looking at standard Dynamics NAV functionality it might be a good idea to create Squash player Journal. The Journal can create entries for reservations that can be invoiced. A journal needs the object structure. The journal is prepared in the objects delivered with this article. Creating a new journal from scratch is a lot of work and can easily lead to making mistakes. It is easier and safer to copy an existing Journal structure from the standard application that is similar to the journal we need for our design. In our example we have copied the Resource Journals. You can export these objects to text format, and then rename and renumber the objects to be reused easily. The squash journal objects are renumbered and renamed from the resource journal. all journals have the same structure. The template, batch and register tables are almost always the same, whereas the journal line and ledger entry table contain function specific fields. Let's have a look at all of them one by one. Journal Template The Journal Template has several fields as shown in the following screenshot: Lets discuss these fields in more detail: Name: This is the unique name. It is possible to define as many Templates as required but usually one Template per Form ID and one for Recurring will do. If you want journals with different source codes you need to have more templates. Description: A readable and understandable description of its purpose. Test Report ID: All Templates have a test report that allows the user to check for posting errors. Form ID: For some journals, more UI objects are required. For example, the General Journals have a special form for bank and cash. Posting Report ID: This report is printed when a user selects Post and Print. Force Posting Report: Use this option when a posting report is mandatory. Source Code: Here you can enter a Trail Code for all the postings done via this Journal. Reason Code: This functionality is similar to source sodes. Recurring: Whenever you post lines from a recurring journal, new lines are automatically created with a posting date defined in the recurring date formula. No. Series: When you use this feature the Document No. in the Journal Line is automatically populated with a new number from this Number Series. Posting No. Series: Use this feature for recurring journals. Journal Batch Journal Batch has various fields as shown in the following screenshot: Lets discuss these fields in more detail: Journal Template Name: The name of the Journal Template this batch refers to Name : Each batch should have a unique code Description: A readable and explaining description for this batch Reason Code: When populated, this Reason Code will overrule the Reason Code from the Journal Template No. Series: When populated this No. Series will overrule the No. Series from the Journal Template Posting No. Series: When populated this Posting No. Series will overrule the Posting No. Series from the Journal Template Register The Register table has various fields as shown in the following screenshot: Lets discuss these fields in more detail: No.: This field is automatically and incrementally populated for each transaction with this journal. There are no gaps between the numbers. From Entry No.: A reference to the first Ledger Entry created is with this transaction. To Entry No.: A reference to the last Ledger Entry is created with this transaction. Creation Date: Always populated with the real date when the transaction was posted. User ID: The ID of the end user who has posted the transaction. The Journal The journal line has a number of mandatory fields that are required for all journals and some fields that are required for its designed functionality. In our case the journal should create a reservation which then can be invoiced. This requires some information to be populated in the lines. Reservation The reservation process is a logistical process that requires us to know the number of the Squash Court, the date and the time of the reservation. We also need to know how long the players want to play. To check the reservation it might also be useful to store the number of the Squash Player. Invoicing For the invoicing part we need to know the price we need to invoice. It might also be useful to store the cost to see our profit. For the system to figure out the proper G/L Account for the turnover we also need to define a General Product Posting Group. Journal Template Name: This is a reference to the current journal template. Line No. : Each journal has a virtually unlimited number of lines; this number is automatically incremented by 10000 allowing lines to be created in between. Entry Type: Reservation or invoice. Document No.: This number can be used to give to the squash player as a reservation number. When the entry type is invoice, it is the invoice number. Posting Date: Posting date is usually the reservation date but when the entry type is invoice it might be the date of the invoice which might differ from the posting date in the general ledger. Squash Player No.: A reference to the squash player who has made the reservation. Squash Court No.: A reference to the squash court. Description: This is automatically updated with the number of the squash court, reservation date and times, but can be changed by the user. Reservation Date: The actual date of the reservation. From Time: The starting time of the reservation. We allow only whole or half hours. To Time: The ending time of the reservation. We only allow whole and half hours. This is automatically populated when people enter a quantity. Quantity: The number of hours playing time. We only allow units of 0.5 to be entered here. This is automatically calculated when the times are populated. Unit Cost: The cost to run a Squash Court for one hour. Total Cost: The cost for this reservation. Unit Price: The invoice price for this reservation per hour. This depends on whether or not the squash player is a member or not. Total Price: The total invoice price for this reservation. Shortcut Dimension Code 1 & 2: A reference to the dimensions used for this transaction. Applies-to Entry No.: When a reservation is invoiced, this is the reference to the squash entry no. of the reservation. Source Code: Inherited from the journal batch or template and used when posting the transaction. Chargeable: When this option is used, there will not be an invoice for the reservation. Journal Batch Name: A reference to the journal batch that is used for this transaction. Reason Code: Inherited from the journal batch or template, and used when posting the transaction. Recurring Method: When the journal is a recurring journal you can use this field to determine whether the amount field is blanked after posting the lines. Recurring Frequency: This field determines the new posting date after the recurring lines are posted. Gen. Bus. Posting Group: The combination of general business and product posting group determines the G/L cccount for turnover when we invoice the reservation. The Gen. Bus. Posting Group is inherited from the bill-to customer. Gen. Prod. Posting Group: This will be inherited from the squash player. External Document No.: When a squash player wants us to note a reference number we can store it here. Posting No. Series: When the journal template has a posting no. series it is populated here to be used when posting. Bill-to Customer No.: This determines who is paying for the reservation. We will inherit this from the squash player. So now we have a place to enter reservations but we have something to do before we can start doing this. Some fields were determined to be inherited and calculated: The time field needs calculation to avoid people entering wrong values The Unit Price should be calculated The Unit Cost, Posting groups and Bill-to Customer No. need to be inherited As final cherry on top, we will look at implementing dimensions
Read more
  • 0
  • 0
  • 4181

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

Form Validation with Codeigniter 1.7

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

AJAX Implementation in APEX

Packt
01 Jun 2010
8 min read
(For more resources on Oracle, see here.) APEX introduced AJAX supports in version 2.0 (the product was called HTML DB back then). The support includes a dedicated AJAX framework that allows us to use AJAX in our APEX applications, and it covers both the client and the server sides. AJAX support on the client side The APEX built-in JavaScript library includes a special JavaScript file with the implementation of the AJAX client-side components. In earlier versions this file was called htmldb_get.js, and in APEX 3.1, it was changed to apex_get_3_1.js. In version 3.1, APEX also started to implement JavaScript namespace in the apex_ns_3_1.js file. Within the file, there is a definition to an apex.ajax namespace. I'm not mentioning the names of these files just for the sake of it. As the AJAX framework is not officially documented within the APEX documentation, these files can be very important and a useful source of information. By default, these files are automatically loaded into every application page as part of the #HEAD# substitution string in the Header section of the page template. This means that, by default, AJAX functionality is available to us on every page of our application, without taking any extra measures. The htmldb_Get object The APEX implementation of AJAX is based on the htmldb_Get object and as we'll see, creating a new instance of htmldb_Get is always the first step in performing an AJAX request. The htmldb_Get constructor function has seven parameters: function htmldb_Get(obj,flow,req,page,instance,proc,queryString) 1—obj The first parameter is a String that can be set to null, a name of a page item (DOM element), or an element ID. Setting this parameter to null will cause the result of the AJAX request to be assigned in a JavaScript variable. We should use this value every time we need to process the AJAX returned result, like in the cases where we return XML or JSON formatted data, or when we are relaying on the returned result, further in our JavaScript code flow. The APEX built-in JavaScript library defines, in the apex_builder.js file, (which is also loaded into every application page, just like apex_ get_3_1.js), a JavaScript global variable called gReturn. You can use this variable and assign it the AJAX returned result. Setting this parameter to the name (ID) of a page item will set the item value property with the result of the AJAX call. You should make sure that the result of the AJAX call matches the nature of the item value property. For example, if you are returning a text string into a text item it will work just fine. However, if you are returning an HTML snippet of code into the same item, you'll most likely not get the result you wanted. Setting this parameter to a DOM element ID, which is not an input item on the page, will set its innerHTML property to the result of the AJAX call. Injecting HTML code, using the innerHTML property, is a cross-browser issue. Moreover, we can't always set innerHTML along the DOM tree. To avoid potential problems, I strongly recommend that you use this option with <div> elements only. 2—flow This parameter represents the application ID. If we are calling htmldb_Get() from an external JavaScript file, this parameter should be set to $v('pFlowId') or its equivalent in version 3.1 or before ($x('pFlowId').value or html_GetElement('pFlowId').value ). This is also the default value, in case this parameter is left null. If we are calling htmldb_Get() as part of an inline JavaScript code we can use the Substitution String notation &APP_ID. (just to remind you that the trailing period is part of the syntax). Less common, but if you are using Oracle Web Toolkit to generate dynamic code (for dynamic content) that includes AJAX, you can also use the bind variable notation :APP_ID. (In this case, the period is just a punctuation mark.) 3—req This String parameter stands for the REQUEST value. Using the keyword APPLICATION_PROCESS with this parameter allows us to name an application level On Demand—PL/SQL Anonymous Block process that will be fired as part of the AJAX server-side processing. For example: 'APPLICATION_PROCESS=demo_code'. This parameter is case sensitive, and as a String, should be enclosed with quotes. If, as part of the AJAX call, we are not invoking an on-demand process, this parameter should be set to null (which is its default value). 4—page This parameter represents an application page ID. The APEX AJAX process allows us to invoke any application page, to run it in the background, on the server side, and then clip portions of the generated HTML code for this page into the AJAX calling page. In these cases, we should set this parameter to the page ID that we want to pull from. The default value of this parameter is 0 (this stands for page 0). However, this value can be problematic at times, especially when page 0 has not been defined on the application, or when there are inconsistencies between the Authorization scheme, or the page Authentication (such as Public and Required Authentication) of page 0 and the AJAX calling page. These inconsistencies can fail the execution of the AJAX process. In cases where you are not pulling information from another page, the safe bet is to set this parameter to the page ID of the AJAX calling page, using $v('pFlowStepId') or its equivalent for versions earlier than 3.1. In the case of an inline code, the &APP_PAGE_ID. Substitution String can also be used. Using the calling page ID as the default value for this parameter can be considered a "good practice" even for upcoming APEX versions, where implementation of page level on-demand process will probably be introduced. I hope you remember that as of version 3.2, we can only define on-demand processes on the application level. 5—instance This parameter represents the APEX session ID, and should almost always be left null (personally, I never encountered the need to set it otherwise). In this case, it will be populated with the result of $v('pInstance') or its earliest versions. 6—proc This String parameter allows us to invoke a stored or packaged procedure on the database as part of the AJAX process. The common behavior of the APEX AJAX framework is to use the application level On Demand PL/SQL Anonymous Block process as the logic of the AJAX server-side component. In this case, the on-demand process is named through the third parameter—req—using the keyword APPLICATION_PROCESS, and this parameter—proc—should be left null. The parameter will be populated with its default value of 'wwv_flow.show'(the single quotes are part of the syntax, as this is a String parameter). However, the APEX AJAX framework also allows us to invoke an external (to APEX) stored (or packaged) procedure as the logic of the AJAX server side. In this case, we can utilize an already existing logic in the database. Moreover, we can benefit from the "regular" advantages of stored procedures, such as a pre-complied code, for better performance, or the option to use wrapped PL/SQL packages, which can protect our business logic better (the APEX on-demand PL/SQL process can be accessed on the database level as clear text). The parameter should be formatted as a URL and can be in the form of a relative URL. In this case, the system will complete the relative URL into a full path URL based on the current window.location.href property. As with all stored or packaged procedures that we wish to use in our APEX application, the user (and in the case of using DAD, the APEX public user) should have the proper privileges on the stored procedure. In case the stored procedure, or the packaged procedure, doesn't have a public synonym defined for it then the procedure name should be qualified with the owner schema. For example, with inline code we can use: '#OWNER#.my_package.my_proc' For external code, you should retrieve the owner and make it available on the page (e.g. assign it to a JavaScript global variable) or define a public synonym for the owner schema and package. 7—queryString This parameter allows us to add parameters to the stored (packaged) procedure that we named in the previous parameter—proc. As we are ultimately dealing with constructing a URL, that will be POSTed to the server, this parameter should take the form of POST parameters in a query string—pairs of name=value, delimited by ampersand (&). Let's assume that my_proc has two parameters: p_arg1 and p_arg2. In this case, the queryString parameter should be set similar to the following: 'p_arg1=Hello&p_arg2=World' As we are talking about components of a URL, the values should be escaped so their code will be a legal URL. You can use the APEX built-in JavaScript function htmldb_Get_escape() to do that. If you are using the req parameter to invoke an APEX on-demand process with your AJAX call, the proc and queryString parameters should be left null. In this case, you can close the htmldb_Get() syntax right after the page parameter. If, on the other hand, you are invoking a stored (packaged) procedure, the req parameter should be set to null.
Read more
  • 0
  • 0
  • 4164

article-image-request-flow-kohana-3
Packt
12 Sep 2011
12 min read
Save for later

Request Flow in Kohana 3

Packt
12 Sep 2011
12 min read
  (For more resources on this topic, see here.) The reader can benefit from the previous article on Routing in Kohana 3.   Hierarchy is King in Kohana Kohana is layered in more ways than one. First, it has a cascading files system. This means the framework loads files for each of it’s core parts in a hierarchical order, which is explained in more detail in just a bit. Next, Kohana allows for controllers to initiate requests, making the application workflow follow a hierarchical design pattern. These features are the foundation of HMVC, which essentially is a cascading filesystem, flexible routing and request handling, the ability to execute sub-requests combined with a standard MVC pattern. The framework manages locating and loading the right file by using a core method named Kohana::find_file(). This method searches the filesystem in a predetermined order to load the proper class first. The order the method searches in is (with default paths): Application path (/application) Modules (/modules) as ordered in bootstrap.php System path (/system) Cascading filesystem As the framework loads, it creates a merged filesystem based on the order of loading described above. One of the benefits of loading files this way is the ease to overload classes that would be loaded later in the flow. We never have to, nor should we, alter a file in the system directory. We can override the default behavior of any method by overloading it in the application directory. Another great advantage is the consistency this mechanism offers. We know the exact load order for every class in any application, making it much easier to create custom code and know exactly where it needs to live. This image shows an example application being merged into the final file structure that will be used when completing a request. We can see how some classes in the application layer are overriding files in the modules. This makes it easier to visualize how modules extend and enhance the framework by building on the system core. Our application then sits on top of the system and module files, and then can build and extend the functionality of the module and system layers. Kohana also makes it easy to load third-party libraries, referred to as vendor libraries, into the filesystem. Each of the three layers has five basic folders into which Kohana looks: Classes (/classes) contain all autoloaded class files. This directory includes our Controller, Models, and their supporting classes. Autoloading allows us to use classes without having to include them manually. Any classes inside this directory will automatically be searched and loaded when they are used. Config files (/config) are files containing arrays that can be parsed and loaded using the core method Kohana::config(). Some config files are required to configure and properly load modules, while others may be created by us to make our application easier to maintain, or to keep vendor libraries tidy by moving config data to the framework. Config files are the only files in the cascading filesystem that are not overloaded; all config files are merged with their parent files. Internationalization files (/i18n) make it much easier to create language files that work with our applications to deliver the proper content that best suits the language of our users. Messages (/messages) are much like configuration files, in that they are arrays that are loaded by a core Kohana method. Kohana:: message() parses and returns the messages for a specific array. This functionality is very useful when creating forms and actions for our applications. View files (/views) are the presentation layer of our applications, where view files and template files live.   Request flow in Kohana Now that we have seen how the framework merges files to create a set of files to load on request, it is a good place to see the flow of the files in Kohana. Remember that controllers can invoke requests, making a bit of a loop between controllers, models, and views, but the frameworks always runs in the same order, beginning with the index.php file. The index.php file sets the path to the application, modules, and system directories and saves them to as constants that are then defined for global use. These constants are APPPATH, MODPATH, and SYSPATH, and they hold the paths for the application, modules, and system paths respectively. After the error-reporting levels are set, Kohana looks to see if the install.php file exists. If the install file is not found, Kohana takes the next step in loading the framework by loading the core Kohana class. Next, the index file looks for the application’s Kohana class, first in the application directory, then in the system path. This is the first example of Kohana looking for our files before it looks for its own. The last thing the index file does is bootstrap our application, by requiring the bootstrap.php file and loading it. You probably remember having to configure the bootstrap file when we installed Kohana. This is the file in which we set our base URL and modules; however, it is a bit more important than just basic installation and configuration. The boostrap begins by setting a some basic environment settings, like the default timezone and locale. Next, it enables the autoloader, and defines the application environment. This tells the framework whether our application is in a production or development environment, allowing it to make decisions based on its environment-specific settings. Next, the default options are set and Kohana is initialized, with the Kohana::init() method being called. After Kohana’s initialization, it sets up logging, configuration reading, and then modules. Modules are loaded defined using an array, with the module name as the key, and the path to the module as the value. The modules load order is listed in this array, and are all subject to the same rules and conventions as core and application code. Each module is added to the cascading file system as described above, allowing files to override any that may be added later when the system files are merged. Modules can contain their own init files, named init.php, that act similar to the application bootstrap, adding routes specific to the modules for our application to use. The last thing the bootstrap does in a normal request flow is to set the routes for the application. Kohana ships with a default route that loads the index action in the welcome controller. The Route object’s set method accepts an array that defines the name, URI, and defaults for the parameters set for the URI. By setting default controllers, actions, and params, we can have dynamic URLs that have default values if none are passed. If no controller or action is passed in the URI on a vanilla Kohana install, the welcome controller will be loaded, and the index action invoked as outlined in the array passed to the Route::set() method in the boostrap. Once all the application routes are set via the Route::set() method and init.php files residing in modules, Request::instance() is invoked, setting the request loop into action. As the Request object processes the request, it looks through routes until it finds the right controller to load. The request object then instantiates the controller, passing the request to the controller for it to use. The Controller::before() method is then called, which acts much like a constructor. By being called first, the before() method allows any logic that need to be performed before a controller action is run to execute. Once the before method is complete, the object continues to load the requested functions, just like when a constructor is complete. The controller action, a method in the controller class, is then called, and once complete, it returns the request response. The action method is where the business logic for the request will reside. Once the action is complete, the Controller::after() method is called, much like the destructor of a standard PHP class. Because of the hierarchical structure of Kohana, any controller can initiate a new request, making it possible for other controllers to be loaded, invoking more controller actions, which generate request responses. Once all the requests have been fulfilled, Kohana renders the final request response. The Kohana request flow can seem like it is long and complex, but it can also be looked at as very clean and organized. By using a front controller design pattern, all requests are handled by just one file: index.php. Each and every request that is handled by our applications will begin with this one file. From there the application is bootstrapped, and then the controller designed to handle the specific request is found, executed, and displayed. Although, as we have seen, there is more that is happening, for most of our applications, this simple way of looking at the request flow will make it easy to create powerful web applications using Kohana.   Using the Request object The request flow in Kohana is interesting, and it is easy to see how it can be powerful on a high level, but the best way to understand HMVC and routing in Kohana is to look at some actual code, and see what the resulting outcome is for real world scenarios. Kohana’s Request object determines the proper controller to invoke, and acts as a wrapper for the response. If we look at the Template Controller that we are extending in our Application Controller for the case study site, we can follow the inheritance path back to Kohana’s template controller, and see the request response. One of the best ways to understand what is happening inside the framework is to drill down through the filesystem and look at the actual code. One of the great advantages of open sources frameworks is the ability to read the code that makes the library run. Opening the welcome controller located at application/classes/controller/welcome.php, we see the following class declaration: class Controller_Welcome extends Controller_Application The first thing we see in the base controller class is that it extends another Controller, and then we see the declaration of an object property named $request. This variable holds the Kohana_Request object, the class that created the original controller call. In the constructor, we can see that the Kohana_Request object is being type-hinted for the argument, and it is setting the $request object property on instantiation. All that is left in the base Controller class is the before() and after() methods with no functionality. We can then open our Application Controller, located at application/classes/controller/application.php. The class declaration in this controller looks like this: abstract class Controller_Application extends Controller_Template In this file, we can see the before() method loading the template view into the template variable, and in the after() method, we see the Request obeject ($this->request) having the response body set, ready to be rendered. This class, in turn, extends the Template Controller. The Template Controller is part of the Kohana system. Since we have not created any controllers in our application or modules the original template controller that ships with Kohana is being loaded. It is located at system/classes/controller/template.php. The class declaration in this controller looks like: abstract class Controller_Template extends Kohana_Controller_Template Here things take a twist, and for the first time, we are going to have to leave the /classes/controller/ structure to find an inherited class. The Kohana_Controller_Template class lives in system/classes/kohana/controller/template.php. The class is fairly short and simple, and it has this class declaration: abstract class Kohana_Controller_Template extends Controller This controller (system/classes/controller.php) is the base controller that all requested controller classes must extend. Examining this class will let us see the Request class enter the Controller loop and the template view get sent to the Request object as the response. Walking through the Welcome Controller’s heritage is a great way of seeing how the Request object loads a controller, and how the parent classes all contribute to the request flow in Kohana. It may seem like pointless complexity at first, however, the benefits of transparent extension are very powerful, and Kohana makes the mechanisms work all behind the scenes. But one question still remains: How is the request object aware of the controllers and routes? Athough dissecting Kohana’s Request Class could be a article unto itself, a lot can be answered by looking at the contstructor in the system/classes/kohana/request.php file. The constructor is given the URI, and then stores object properties that the object will later use to execute the request. The Request class does have a couple of key methods that can be very helpful. The first is Request::controller(), which returns the name of the controller for the request, and the other is Request::action(), which similarly returns the name of the action for the request. After loading the routes, the method then iterates through the routes, determines any matches for the URI, and begins setting the controller, action, and parameters for the route. If there are not matches for optional segments of the route, the defaults are stored in the object properties. When the Request object’s execute() method is called, the request is processed, and the response is returned. This happens by first processing the before() method, then the controller action being requested, then the after() method for the class, followed by any other requests until all have completed. The topic of initiating a request from within a controller has arisen a few times, and is the best way to illustrate the Hierarchical aspect of HMVC. Let’s take a look at this process by creating a controller method that initiates a new request, and see how it completes.  
Read more
  • 0
  • 0
  • 4149
Modal Close icon
Modal Close icon