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

How-To Tutorials

7019 Articles
article-image-moodle-19-math-quizzes-part-1
Packt
30 Nov 2009
5 min read
Save for later

Moodle 1.9 Math Quizzes: Part 1

Packt
30 Nov 2009
5 min read
As good as the Moodle quiz module is at recognizing the correctness of our students' answers, we quickly run into problems when we need Moodle to recognize, for example, that 3a+2b is exactly the same as 2b+3a . To accomplish this, we're going to need a Computer Algebra System (CAS). The Maxima system (more on this later) has been successfully integrated into Moodle, thanks to the work carried out by Chris Sangwin and Alex Billingsley at the University of Birmingham in the UK. In this article, we will also learn how to perform these tasks: Install and integrate STACK into Moodle Create questions that can be automatically marked using STACK Let's start by adding numeric questions into the course question bank. Creating quizzes Creating a quiz in Moodle is a two-stage process. First, we add our questions to the question bank (each course has its own question bank). Once we've added questions to the question bank, we can add a quiz activity to the course and then choose questions to add to it from the question bank. What are the advantages of having a two-stage process? I worked in much the same way creating quizzes before I started with Moodle. My bookshelf of math books was my question bank, and I would take questions from there to add into my quizzes. Here are just a few of the advantages: If there is a particular point you want to reinforce, then it's easy to include the same question in different quizzes throughout your course. It's easy to share your questions with other Moodle courses. For example, questions on the Pythagorean Theorem are relevant to pure math, mechanics, engineering, and physics. Questions can be exported from and imported into the question bank. This means converting questions over to Moodle is a job that can be shared between colleagues. Here's a basic Pythagorean Theorem question I converted over to Moodle: Question types However, I don't want to convert just this single question over to Moodle; I also want to have questions similar to this one but with different numbers. I want those numbers chosen randomly by Moodle, so I don't have to keep thinking up different numbers each time I set the quiz. The question type I need is Calculated, which we'll learn about in the next section. Calculated question type Let's learn how to add a calculated question to the course question bank now: Return to your course's front page, and click on Questions in the course Administration block: The course Question bank is displayed. From the Create new question drop-down menu, choose Calculated: Give the question a name. Make sure it's a name that you (and, potentially, your colleagues) can recognize when it's in the question bank. Don't call it '1', 'i', or 'a)' because you don't know where it will appear in the quiz. Now, supply the question text: Notice that I have used placeholders in the text, {a} and {b}. We will be configuring Moodle to replace those with numbers shortly. Scroll down to the Answer box. We need to enter the correct calculation into the Correct Answer Formula edit box (don't include a '=' in your answer): The students need to give the correct answer (exactly), but don't worry about the Tolerance setting: leave it set to 0.01. Set the Grade to 100%. I want the students to give their answers to three significant figures, and to that end I needed to click on the Correct answer shows drop-down menu, set that to 3, and change the Format to significant figures: Scroll down to the bottom of the page, and click on the Next Page button. You are now taken to the Choose dataset properties page. The numbers for the variables {a} and {b} will be chosen from a dataset. I want to use my own datasets for each variable. Select will use a new shared dataset for both drop-downs: Click on the Next Page button. You are taken to the Edit the datasets page. Now, we can specify the range of values for {a} and {b}: We need to add numbers to this dataset. I want to add 20 possible pairs of numbers for {a} and {b}. Scroll down to the Add box, select 20 items from the item(s) drop-down menu and click on the Add button: Twenty pairs of numbers are now added to the dataset. Moodle will choose pairs of numbers in this dataset when the student is presented with the question. If you want to alter any of the numbers Moodle has automatically generated for us, you can do so in the second-half of the page. Scroll down to the very bottom of the page, and click on the Save changes button. Our new calculated question is now added to the question bank: To recap, we have seen that creating a calculated question is a two-step process. First, we need to specify the question text. The question text contains variables that Moodle will then replace with random values when the quiz is taken. Then, we need to specify datasets for each of the variables, from which Moodle will choose the values when the quiz is taken. We can have Moodle choose the numbers for us, or we can select our own.
Read more
  • 0
  • 0
  • 3658

article-image-facelets-components-jsf-12
Packt
30 Nov 2009
12 min read
Save for later

Facelets Components in JSF 1.2

Packt
30 Nov 2009
12 min read
One of the more advanced features of the Facelets framework is the ability to define complex templates containing dynamic nested content. What is a template?The Merriam-Webster dictionary defines the word "template" as "a gauge, pattern, or mold (as a thin plate or board) used as a guide to the form of a piece being made" and as "something that establishes or serves as a pattern." In the context of user interface design for the Web, a template can be thought of as an abstraction of a set of pages in the web application.A template does not define content, but rather it defines placeholders for content, and provides the layout, orientation, flow, structure, and logical organization of the elements on the page. We can also think of templates as documents with "blanks" that will be filled in with real data and user interface controls at request time. One of the benefits of templating is the separation of content from presentation, making the maintenance of the views in our web application much easier. The <ui:insert> tag has a name attribute that is used to specify a dynamic content region that will be inserted by the template client. When Facelets renders a UI composition template, it attempts to substitute any <ui:insert> tags in the Facelets template document with corresponding <ui:define> tags from the Facelets template client document. Conceptually, the Facelets composition template transformation process can be visualized as follows: In this scenario, the browser requests a Facelets template client document in our JSF application. This document contains two <ui:define> tags that specify named content elements and references a Facelets template document using the <ui:composition> tag's template attribute. The Facelets template document contains two <ui:insert> tags that have the same names as the <ui:define> tags in the client document, and three <ui:include> tags for the header, footer, and navigation menu. This is a good example of the excellent support that Facelets provides for the Composite View design pattern. Facelets transforms the template client document by merging any content it defines using <ui:define> tags with the content insertion points specified in the Facelets template document using the <ui:insert> tag. The result of merging the Facelets template client document with the Facelets template document is rendered in the browser as a composite view. While this concept may seem a bit complicated at first, it is actually a powerful feature of the Facelets view defi nition framework that can greatly simplify user interface templating in a web application. In fact, the Facelets composition template document can itself be a template client by referencing another composition template. In this way, a complex hierarchy of templates can be used to construct a flexible, multi-layered presentation tier for a JSF application. Without the Facelets templating system, we would have to copy and paste view elements such as headers, footers, and menus from one page to the next to achieve a consistent look and feel across our web application. Facelets templating enables us to define our look and feel in one document and to reuse it across multiple pages. Therefore, if we decide to change the look and feel, we only have to update one document and the change is immediately propagated to all the views of the JSF application. Let's look at some examples of how to use the Facelets templating feature. A simple Facelets template The following is an example of a simple Facelets template. It simply renders a message within an HTML <h2> element. Facelets will replace the "unnamed" <ui:insert> tag (without the name attribute) in the template document with the content of the <ui:composition> tag from the template client document. template01.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Facelets template example</title><link rel="stylesheet" type="text/css" href="/css/style.css" /></head><body><h2><ui:insert /></h2></body></html> A simple Facelets template client Let's look at a simple example of Facelets templating. The following page is a Facelets template client document. (Remember: you can identify a Facelets template client by looking for the existence of the template attribute on the <ui:composition> tag.) The <ui:composition> tag simply contains the text Hello World. templateClient01.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:composition example</title></head><body><ui:composition template="/WEB-INF/templates/template01.jsf">Hello World</ui:composition><ui:debug /></body></html> The following screenshot displays the result of the Facelets UI composition template transformation when the browser requests templateClient01.jsf. Another simple Facelets template client The following Facelets template client example demonstrates how a template can be reused across multiple pages in the JSF application: templateClient01a.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:composition example</title></head><body><ui:composition template="/WEB-INF/templates/template01.jsf">How are you today?</ui:composition><ui:debug /></body></html> The following screenshot displays the result of the Facelets UI composition template transformation when the browser requests templateClient01a.jsf: A more complex Facelets template The Facelets template in the previous example is quite simple and does not demonstrate some of the more advanced capabilities of Facelets templating. In particular, the template in the previous example only has a single <ui:insert> tag, with no name attribute specified. The behavior of the unnamed <ui:insert> tag is to include any content in the referencing template client page. In more complex templates, multiple <ui:insert> tags can be used to enable template client documents to defi ne several custom content elements that will be inserted throughout the template. The following Facelets template document declares three named <ui:insert> elements. Notice carefully where these tags are located. template02.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title><ui:insert name="title" /></title><link rel="stylesheet" type="text/css" href="/css/style.css" /></head><body><ui:include src="/WEB-INF/includes/header.jsf" /><h2><ui:insert name="header" /></h2><ui:insert name="content" /><ui:include src="/WEB-INF/includes/footer.jsf" /></body></html> In the following example, the template client document defines three content elements named title, header, and content using the <ui:define> tag. Their position in the client document is not important because the template document determines where this content will be positioned. templateClient02.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:composition example</title></head><body><ui:composition template="/WEB-INF/templates/template02.jsf"><ui:define name="title">Facelet template example</ui:define><ui:define name="header">Hello World</ui:define><ui:define name="content">Page content goes here.</ui:define></ui:composition><ui:debug /></body></html> The following screenshot displays the result of a more complex Facelets UI composition template transformation when the browser requests the page named templateClient02.jsf. The next example demonstrates reusing a more advanced Facelets UI composition template. At this stage, we should have a good understanding of the basic concepts of Facelets templating and reuse. templateClient02a.jsf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:composition example</title></head><body>Facelets Components[ 78 ]<ui:composition template="/WEB-INF/templates/template02.jsf"><ui:define name="title">Facelet template example</ui:define><ui:define name="header">Thanks for visiting!</ui:define><ui:define name="content">We hope you enjoyed our site.</ui:define></ui:composition><ui:debug /></body></html> The next screenshot displays the result of the Facelets UI composition transformation when the browser requests templateClient02a.jsf. We can follow this pattern to make a number of JSF pages reuse the template in this manner to achieve a consistent look and feel across our web application. Decorating the user interface The Facelets framework supports the definition of smaller, reusable view elements that can be combined at runtime using the Facelets UI tag library. Some of these tags, such as the <ui:composition> and <ui:component> tags, trim their surrounding content. This behavior is desirable when including content from one complete XHTML document within another complete XHTML document. There are cases, however, when we do not want Facelets to trim the content outside the Facelets tag, such as when we are decorating content on one page with additional JSF or HTML markup defi ned in another page. For example, suppose there is a section of content in our XHTML document that we want to wrap or "decorate" with an HTML <div> element defined in another Facelets page. In this scenario, we want all the content on the page to be displayed, and we are simply surrounding part of the content with additional markup defined in another Facelets template. Facelets provides the <ui:decoration> tag for this purpose. Decorating content on a Facelets page The following example demonstrates how to decorate content on a Facelets page with markup from another Facelets page using the <ui:decoration> tag. The <ui:decoration> tag has a template attribute and behaves like the <ui:composition> tag. Facelets templating typically uses the <ui:composition>. It references a Facelets template document that contains markup to be included in the current document. The main difference between the <ui:composition> tag and the <ui:decoration> tag is that Facelets trims the content outside the <ui:composition> tag but does not trim the content outside the <ui:decoration> tag. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>ui:decorate example</title><link rel="stylesheet" type="text/css" href="css/style.css" /></head><body>Text before will stay.<ui:decorate template="/WEB-INF/templates/box.jsf"><span class="header">Information Box</span><p>This is the first line of information.</p><p>This is the second line of information.</p><p>This is the third line of information.</p></ui:decorate>Text after will stay.<ui:debug /></body></html> Creating a Facelets decoration Let's examine the Facelets decoration template referenced by the previous example. The following source code demonstrates how to create a Facelets template to provide the decoration that will surround the content on another page. As we are using a <ui:composition> tag, only the content inside this tag will be used. In this example, we declare an HTML <div> element with the "box" CSS style class that contains a single Facelets <ui:insert> tag. When Facelets renders the above Facelets page, it encounters the <ui:decorate> tag that references the box.jsf page. The <ui:decorate> tag will be merged together with the associated decoration template and then rendered in the view. In this scenario, Facelets will insert the child content of the <ui:decorate> tag into the Facelets decoration template where the <ui:insert> tag is declared. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Box</title></head><body><ui:composition><div class="box"><ui:insert /></div></ui:composition></body></html> The result is that our content is surrounded or "decorated" by the <div> element. Any text before or after the <ui:decoration> is still rendered on the page, as shown in the next screenshot: The included decoration is rendered as is, and is not nested inside a UI component as demonstrated in the following Facelets debug page:
Read more
  • 0
  • 0
  • 4033

article-image-report-components-nav-2009-part-2
Packt
30 Nov 2009
6 min read
Save for later

Report components in NAV 2009: Part 2

Packt
30 Nov 2009
6 min read
Data item Sections Earlier in our discussion on reports, we referred to the primary components of a report. The Triggers and Properties we have reviewed so far are the data processing components. Next in the report processing sequence are Sections. In Classic RD reports, Sections are the output layout and formatting components. In RTC reports, Sections have a much more limited, but still critically important, role. In the process of creating the initial report design, you may be entering data either completely manually as we've done in our example work, or you may use the Classic Report Wizard. If you use the Wizard, you will end up with Sections defined suitable for Classic Client Report processing. Those Sections may be only rough draft equivalents of what you may want your final report to look like, but they are a suitable starting place for the Classic RD layout work, if that were the tool you were going to use. If you are creating your report completely manually, that is by not using the Wizard, you may also find it appropriate to define Sections to the point that the Classic Client could print a basic, readable report. In our case, we are focusing our production report development effort on the RoleTailored Client, so we will invest minimal effort on Classic Client compatible report layouts. We might do just enough to allow test report runs for data examination purposes and logic flow debugging. However, creating basic Section layouts provides us with another benefit relative to our VS RD layout work, especially if we can create them using the Report Wizard, because all the fields to be used by VS RD must be specified in the Sections. Creating RTC reports via the Classic Report Wizard Let's look at the RTC report development flow again. The preceding image is very similar to the one we studied earlier in this articles, but this flowchart only shows the steps that are pertinent to VS RD. In Step 6 of this flow, there is an option to Create Layout Suggestion in the Visual Studio Report Designer as shown in the following screenshot: When you choose Create Layout Suggestion, the C/SIDE Report Designer will invoke a process that transforms the layout in Sections to a layout in the Visual Studio Report Designer. If a VS RD layout previously existed, the newly created layout will overwrite it. Therefore, this option will normally be used only once, in the initial stages of report design. Let's experiment by using the Report Wizard to create a simple report listing the gifts received by ICAN. We will access the Report Wizard in the Object Designer. Click on Reports | New, then fill in the Wizard screen as shown in the following image. Then click on OK and choose fields to display in the report as shown in the following screenshot. Click on Next, then choose the sorting order (that is index or key) that starts with Donor ID. Click on Next again and choose to Group the data by Donor ID. Click on Next again and choose to create totals for the Estimated Value field. One more, click on Next and choose the List Style for the report, then click on Finish. At this point, you will have generated a Classic Client report using the Report Wizard. If you View | Sections, you should see a C/SIDE report layout that looks much like the following screenshot. Let's save our newly generated report so that, if we need to, we can come back to this point as a checkpoint. Click on File | Save As and assign the report to ID 50002 with the Name of Gifts by Donor. Now click on Tools | Create Layout Suggestion. The process of transforming the Classic Report Layout to a Visual Studio Report Designer Layout will take a few seconds. When the report layout transformation process completes, you should see a screen that looks very similar to the following screenshot. The primary data layout portion of the same VS RD screen is shown in the next image. Compare this to the Classic RD data layout we just looked at a couple of steps ago. You will see some similarities and some considerable differences. Without doing anything else, let's save the VS RD layout we just created for the RoleTailored Client, then run both versions of the report to see the differences in the generated results. To save the VS RD layout, start by simply exiting the VS Report Designer. Once the VS RD screen closes, you will see the following question. Respond by clicking Yes. Then, when you exit the Classic Report Designer, you will see this question. Respond by clicking Yes. You will then be presented with the following message. Again, click on Yes. If there were an error in the RDLC created within the VS RD (such as an incorrect variable name used), an error message similar to the following would display. Since, hopefully, we didn't get such an error message, we can proceed to test both the Classic Client and the RoleTailored Client versions of our generated report. We can test the Classic Client (or C/SIDE RD) version of Report 50002 from the same Object Designer screen where we did our initial design work. Highlight the line for Report 50002 and click on the Run button. You should see the following screen: If we were running this as users, we might want to make a selection of specific Donors here on which to report. As we are just testing, simply click on Preview to see our report onscreen. The report will then appear, looking like the following: As you can see, with minimum development effort (and a minimum of technical knowledge), we have designed and created a report listing Gifts by Donor with subtotals by Donor. The report has proper page and column headings. Not only that, but the report was initiated withs a Request Form allowing application of filters. Close the Classic Client report; now let's run the RTC version. Just like we could do with Pages, we will run our Report test from the Windows Run option. Click on Run and enter the command to run Report 50002, as shown in the next screenshot. Click on OK. If the RoleTailored Client is not active, after a short pause, it will be activated. Then the Request Page will appear. Compare the look and contents of this Request Page with the one we saw previously for the Classic Client. As before, click on Preview and view the report. Of course, this time we're looking at the RTC version. This method of automatic transformation is very useful for getting an initial base for a new report or, obviously, for the complete generation process for a simple report where the requirements for layout are not too restrictive.
Read more
  • 0
  • 0
  • 2556

article-image-user-interface-design-icefaces-18-part-2
Packt
30 Nov 2009
11 min read
Save for later

User Interface Design in ICEfaces 1.8: Part 2

Packt
30 Nov 2009
11 min read
Facelets templating To implement the layout design, we use the Facelets templating that is officially a part of the JSF specification since release 2.0. This article will only have a look at certain parts of the Facelets technology. So, we will not discuss how to configure a web project to use Facelets. You can study the source code examples of this article, or have a look at the developer documentation (https://facelets.dev.java.net/nonav/docs/dev/docbook.html) and the articles section of the Facelets wiki (http://wiki.java.net/bin/view/Projects/FaceletsArticles)for further details. The page template First of all, we define a page template that follows our mockup design. For this, we reuse the HelloWorld(Facelets) application. You can import the WAR file now if you did not create a Facelets project. For importing a WAR file, use the menu File | Import | Web | WAR file. In the dialog box, click on the Browse button and select the corresponding WAR file. Click on the Finish button to start the import. The run configuration is done. However, you do not have to configure the Jetty server again. Instead, it can be simply selected as your target. We start coding with a new XHTML file in the WebContent folder. Use the menu File | New | Other | Web | HTML Page and click on the Next button. Use page-template.xhtml for File name in the next dialog. Click on the Next button again and choose New ICEfaces Facelets.xhtml File (.xhtml). Click on the Finish button to create the file. The ICEfaces plugin creates this code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title> <ui:insert name="title"> Default title </ui:insert> </title> </head> <body> <div id="header"> <ui:include src="/header.xhtml"> <ui:param name="param_name" value="param_value"/> </ui:include> </div> <div id="content"> <ice:form> </ice:form> </div> </body> </html> The structure of the page is almost pure HTML. This is an advantage when using Facelets. The handling of pages is easier and can even be done with a standard HTML editor. The generated code is not what we need. If you try to run this, you will get an error because the header.xhtml file is missing in the project. So, we delete the code between the <body> tags and add the basic structure for the templating. The changed code looks like this: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title> <ui:insert name="title"> Default title </ui:insert> </title> </head> <body> <table align="center" cellpadding="0" cellspacing="0"> <tr><td><!-- header --></td></tr> <tr><td><!-- main navigation --></td></tr> <tr><td><!-- content --></td></tr> <tr><td><!-- footer --></td></tr> </table> </body> </html> We change the <body> part to a table structure. You may wonder why we use a <table> for the layout, and even the align attribute, when there is a <div> tag and CSS. The answer is pragmatism. We do not follow the doctrine because we want to get a clean code and keep things simple. If you have a look at the insufficient CSS support of the Internet Explorer family and the necessary waste of time to get things running, it makes no sense to do so. The CSS support in Internet Explorer is a good example of the violation of user expectations. We define four rows in the table to follow our layout design. You may have recognized that the <title> tag still has its <ui:insert> definition. This is the Facelets tag we use to tell the templating where we want to insert our page-specific code. To separate the different insert areas from each other, the <ui:insert> has a name attribute. We substitute the comments with the <ui:insert> definitions, so that the templating can do the replacements: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title> <ui:insert name="title"> Default title </ui:insert> </title> </head> <body> <table align="center" cellpadding="0" cellspacing="0"> <tr><td><ui:insert name="header"/></td></tr> <tr><td><ui:insert name="mainNavigation"/></td></tr> <tr><td><ui:insert name="content"/></td></tr> <tr><td><ui:insert name="footer"/></td></tr> </table> </body> </html> The <ui:insert> tag allows us to set defaults that are used if we do not define something for replacement. Everything defined between <ui:insert> and </ui:insert> will then be shown instead. We will use this to define a standard behavior of a page that can be overwritten, if necessary. Additionally, this allows us to give hints in the rendering output if something that should be defined in a page is missing. Here is the code showing both aspects: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <ice:outputStyle href="/xmlhttp/css/royale/royale.css" /> <title> <ui:insert name="title"> Please, define a title. </ui:insert> </title> </head> <body> <table align="center" cellpadding="0" cellspacing="0"> <tr><td> <ui:insert name="header"> <ice:graphicImage url="/logo.png" /> </ui:insert> </td></tr> <tr><td> <ui:insert name="mainNavigation"> <ice:form> <ice:menuBar noIcons="true"> <ice:menuItem value="Menu 1"/> <ice:menuItem value="Menu 2"/> <ice:menuItem value="Menu 3"/> </ice:menuBar> </ice:form> </ui:insert> </td></tr> <tr><td> <ui:insert name="content"> Please, define some content. </ui:insert> </td></tr> <tr><td> <ui:insert name="footer"> <ice:outputText value="&#169; 2009 by The ICEcubes." /> </ui:insert> </td></tr> </table> </body> </html> The header, the main navigation, and the footer now have defaults. For the page title and the page content, there are messages that ask for an explicit definition. The header has a reference to an image. Add any image you like to the WebContent and adapt the url attribute of the <ice:graphicImage> tag, if necessary. The example project for this article will show the ICEcube logo. It is the logo that is shown in the mockup above. The <ice:menuBar> tag has to be surrounded by a <ice:form> tag, so that the JSF actions of the menu entries can be processed. Additionally, we need a reference to one of the ICEfaces default skins in the <head> tag to get a correct menu presentation. We take the Royale skin here. If you do not know what the Royale skin looks like, you can have a look at the ICEfaces Component Showcase (http://component-showcase.icefaces.org) and select it in the combo box on the top left. After your selection, all components present themselves in this skin definition. Using the template A productive page template has a lot more to define and is also different in its structure. References to your own CSS, JavaScript, or FavIcon files are missing here. The page template would be unmaintainable soon if we were to manage the pull-down menu this way. However, we will primarily look at the basics here. So, we keep the page template for now. Next, we adapt the existing ICEfacesPage1.xhtml to use the page template for its rendering. Here is the original code: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title> <ui:insert name="title"> Default title </ui:insert> </title> </head> <body> <div id="header"> <!-- <ui:include src="/header.xhtml" > <ui:param name="param_name" value="param_value" /> </ui:include> --> </div> <div id="content"> <ice:form> <ice:outputText value="Hello World!"/> <!-- drop ICEfaces components here --> </ice:form> </div> </body> </html> We keep the Hello World! output and use the new page template to give some decoration to it. First of all, we need a reference to the page template so that the templating knows that it has to manage the page. As the page template defines the page structure, we no longer need a <head> tag definition. You may recognize <ui:insert> in the <title> tag. This is indeed the code we normally use in a page template. Facelets has rendered the content in between because it did not find a replacement tag. Theoretically, you are free to define such statements in any location of your code. However, this is not recommended. Facelets has a look at the complete code base and matches pairs of corresponding name attribute definitions between <ui:insert name="..."> and <ui:define name="..."> tags. Here is the adapted code: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <body> <ui:composition template="/page-template.xhtml"> <div id="content"> <ice:form> <ice:outputText value="Hello World!"/> </ice:form> </div> </ui:composition> </body> </html> This code creates the following output: We can see our friendly reminders for the missing title and the missing content. The header, the main navigation, and the footer are rendered as expected. The structure of the template seems to be valid, although we recognize that a CSS fle is necessary to define some space between the rows of our layout table. However, something is wrong. Any idea what it is? If you have a look at the hello-world.xhtml again, you can find our Hello World! output; but this cannot be found in the rendering result. As we use the page template, we have to tell the templating where something has to be rendered in the page. However, we did not do this for our Hello World! output. The following code defines the missing <ui:define> tag and skips the <div> and <ice:form> tags that are not really necessary here: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <body> <ui:composition template="/page-template.xhtml"> <ui:define name="title"> Hello World on Facelets </ui:define> <ui:define name="content"> <ice:outputText value="Hello World!"/> </ui:define> </ui:composition> </body> </html>
Read more
  • 0
  • 0
  • 2540

article-image-report-components-nav-2009-part-1
Packt
30 Nov 2009
13 min read
Save for later

Report components in NAV 2009: Part 1

Packt
30 Nov 2009
13 min read
Report components overview What we generally refer to as the report or report object is technically referred to as a Report Description. The Report Description is the information describing the layout for the planned output and processing logic to be followed when processing the data. Report Descriptions are stored in the database in the same way as other table or form/page descriptions. As with pages, we will use the term "report" whether we mean the output, the description, or the object. Reports share some attributes with pages including aspects of the designer, features of various controls, some triggers, and even some of the properties. Where those parallels exist, we should take notice of them. The consistency of any toolset, including NAV, makes it easier to learn and to use. This applies to developers as well as to the users. The overall structure of an NAV RTC Report consists of the following elements. Any particular report may utilize only a small number of the possible elements (for example, Section Triggers are not used by the RTC), but many different combinations are feasible and logical. Report Properties Report Triggers Data Items Data Item Properties Data Item Triggers Data Item Sections Section Triggers Data Field Controls Visual Studio Layout VS Controls VS Control Properties Request Page Request Page Properties Request Page Triggers Request Page Controls Request Page Control Properties Request Page Control Triggers The components of a report description A report description consists of a number of primary components, each of which in turn is made up of secondary components. The primary components Report Properties and Triggers and Data Item Properties and Triggers define the data flow and overall logic for processing the data. These are all designed in the C/SIDE Report Designer. A subordinate set of primary components, Data Field Controls and Working Storage, are defined within the DataItem Sections, which are also designed in the C/SIDE Report Designer. Data Fields are defined in this article as the fields contained in the DataItems (that is application tables). Working Storage (also referred to as Working Data) fields are defined in this article as the data elements that are created within a report (or other object) for use in that object. Working Storage data elements are not permanently stored in the database. These components constitute the data elements that will be made available to the Visual Studio Report Designer (VS RD). The VS RD cannot access any data elements that have not been defined within the Report Sections (each of which must be associated with a DataItem). The Report Layout  is designed in the VS RD using the data elements made available to the VS RD by the C/SIDE RD, defined in the DataItem Sections. The Report Layout includes the Page Header, Body, and Page Footer. In most cases, the Body of the report is based on a layout table. Note that the VS RD layout table is a data grid used for layout purposes and is not the same as a table of data stored in the NAV database. This terminology is confusing. When the NAV Help files regarding reports refer to a table, you will have to read very carefully to determine which meaning for "table" is intended. Within the Report Body, there can be none, one, or more Detail rows. There can also be Header and Footer rows. The Detail rows are the definition of the primary, repeating data display. A report layout may also include one or more Group rows, used to group and total data that is displayed in the Detail row(s). All of the report formatting is controlled in the Report Layout. The Font, field positioning, visibility options (including expand/collapse sections), dynamic sorting, and graphics are all defined as part of the Report Layout. The same is true for pagination control, headings and footers, some totaling, column-width control, and a number of other display details. Of course, if the display target changes dramatically in the future versions of NAV, for example, from a desktop workstation display to a browser supporting cellular phone, then the appearance of the Report Layout will change dramatically as well. One of the advantages of SSRS is to support such a level of flexibility. But, if you expect that degree of variability in output devices, you will have design accordingly. There is another primary functional component of a report description, the Request Page. It displays as a page when a report is invoked. The purpose of the Report Request Page is to allow users to enter information to control the report. Control information entered through a Request Page may include filters, control dates, other control parameters, and specifi cations as well as defining which available formatting or processing options to use for this instance of the report (that is for this run). The Request Page appears once at the beginning of a report at run time. Report Data Flow One of the principal advantages of the NAV report is its built-in data flow structure. At the beginning of any report, you must define the data item(s), the tables that the report will process. It is possible to create a working report that has no data items, but that situation normally calls for a codeunit to be used. There are rare exceptions to this, such as a report created for the purposes of processing only, perhaps to control branching or choice of objects to be run subsequently. In that case, you might have no data item, just a set of logic whose data flow is totally self-controlled. Normally in a report, NAV automatically creates a data flow process for each data item. This automatically created data flow provides specific triggers and processing events: Preceding the data For each record of the data Following the end of the data The underlying "black-box" report logic (the part we can't see or affect) loops through the named tables, reading and processing one record at a time. That flow is automatic, that is we don't have to program it. Therefore, any time we need a process that steps through a set of data one record at a time, it is quite likely we will use a report object. If you've ever worked with some of the legacy report writers or the RPG programming language, it is likely that you will recognize this looping behavior. That recognition may allow you to understand how to take advantage of NAV reports more quickly. The reference to a database table in a report is referred to as a Data Item. One of the capabilities of the report data flow structure is the ability to nest data items. If Data Item 2 is nested within Data Item 1 and related to Data Item 1, then for each record in Data Item 1, all of the related records in Data Item 2 will be processed. The next screenshot shows the data item definition screen. This example uses tables from our ICAN system. The design is for a report to list all the Gifts by Donor for each Donor Type. Thus Donor Type is the primary table (DataItem1). For each Donor Type, we want to list all the Donors that have given Gifts to ICAN (DataItem2). And for each Donor of each Donor Type, we want to list their Gifts which are recorded in the Gift Ledger (DataItem3). On the Data Item screen, we initially enter the table name Donor, as you see in the following screenshot. The Data Item Name, to which the C/AL code will refer, is DataItem1 in our example here. When we enter the second table, Donor, then we click on the right arrow at the bottom of the screen. That will cause the selected data item to be indented relative to the data item above (the "superior" data item). That causes the nesting of the processing of the indented data item within the processing of the superior data item. In this instance, we have renamed the Data Items just for the purpose of our example, in order to illustrate data flow within a report. The normal default behavior would be for the Name in the right column to default to the table name shown in the left column (for example, the Name for Donor would be displayed as < Donor > by default). This default Data Item Name would only need to be changed if the same table appeared twice within the Data Item list. For the second instance of Donor, for example, you could simply give it the Name Donor2. For each record in the superior data item, the indented data item will be fully processed. Which records are actually processed in the indented table will depend on the filters, and the defined relationships between the superior and indented tables. In other words, the visible indentation is only part of the necessary definition. We'll review the rest of it shortly. For our example, we enter a third table, Gift Ledger, and enter our example name of DataItem3. The following chart shows the data flow for this Data Item structure. The chart boxes are intended to show the nesting that results from the indenting of the Data Items in the preceding screenshot. The Donor Data Item is indented under the Donor Type Data Item. That means for every processed Donor Type record, all of the selected Donor records will be processed. That same logic applies to the Donor records and Gift Ledger records (that is, for each Donor record processed, all selected Gift records are processed). The blocks visually illustrate how the data item nesting controls the data flow. As you can see, the full range of processing for DataItem2 occurs for each DataItem1 record. In turn, the full range of processing for DataItem3 occurs for each DataItem2 record. In Classic Client reporting, the formatting and output for each record processed happened in sequence as the last step in processing that record. In other words, once a record was read and processed, it was rendered for output presentation before the next record was read. In the NAV 2009 Role Tailored Client, report processing occurs in two separate steps, the first tied primarily to what has been designed in the Classic RD, the second tied to what has been designed in the VS RD. The processing of data represented in the preceding image occurs in the first step, yielding a complete dataset containing all the data that is to be rendered for output. This intermediate dataset is a flattened version of the hierarchically structured dataset represented in the Classic RD. Each record in the new dataset contains all the fields from the sections (parent, child, grandchild, and so on) "de-normalized" into a completely flat data structure. This structure also includes Grouping, Filtering, Formatting, MultiLanguage, and other control information required to allow the Visual Studio Report Viewer to properly render the defined report. That flattened dataset is then handed off to the Visual Studio Microsoft Report Viewer. The Microsoft Report Viewer provides the new NAV 2009 reporting capabilities such as various types of graphics, interactive sorting and expand/collapse sections, output to PDF and Excel, and other advanced reporting features based on RDLC created by the VS RD design work. The elements of a report Earlier we reviewed a list of the elements of a Report object. Now we're going to learn about each of those elements. Our goal here is to understand how the pieces of the report puzzle fit together to form a useful, coherent whole. Following that, we will do some development work for our ICAN system to apply some of what we've reviewed. Report properties The Classic RD Report Properties are shown in the following screenshot. Some of these properties have essentially the same purpose as those in pages and other objects. Many of these Report Property settings only apply to Classic reports and are replaced by equivalent Report Properties in the Visual Studio RD. ID: The unique report object number. Name: The name by which this report is referred to within C/AL code. Caption: The name that is displayed for this report; Caption defaults to Name. CaptionML: The Caption translation for a defined alternative language. ShowPrintStatus: If this property is set to Yes and the ProcessingOnly property is set to No, then a Report Progress window, including a Cancel button, is displayed. When ProcessingOnly is set to Yes, if you want a Report Progress Window, you must create your own dialog box. UseReqForm: Determines if a Request Page should be displayed to allow the user the choice of Sort Sequence and entry of filters and other requested control information. UseSystemPrinter: Determines if the default printer for the report should be the defined system printer, or if NAV should check for a setup-defined User/Report printer definition. ProcessingOnly: This should be set to Yes when the report object is being used only to process data and no report output is to be generated. If this property is set to Yes, then that overrides any other property selections that would apply in a report-generating situation. TransactionType: This can be in one of four basic options: Browse, Snapshot, UpdateNoLocks, and Update. These control the record locking behavior to be applied in this report. The default is UpdateNoLocks. This property is generally only used by advanced developers. Description: This is for internal documentation; it is not used often. TopMargin, BottomMargin, LeftMargin, RightMargin: Does not apply to an RTC report. There are applicable VS RD properties. HorzGrid, VertGrid: Does not apply to an RTC report. VS RD layout has its own grid for control positioning. Permissions: This provides report-specific setting of permissions, which are the rights to access data, subdivided into Read, Insert, Modify, and Delete. This allows the developer to define report and processing permissions that override the user-by-user permissions security setup. The following printer-specific properties do not apply to an RTC report. Several can be overridden by user selections made at run time. Orientation: There is an applicable VS RD property PaperSize: There is an applicable VS RD property PaperSourceFirstPage, PaperSourceOtherPages: This is controlled in Page Setup for RTC reports DeviceFontName: This is controlled by the Report Viewer The Visual Studio RD Report Properties are shown in the following screenshot: Report triggers The following screenshot shows the Report triggers available in a report: Documentation(): Documentation is technically not a trigger, but a section which serves only the purpose of containing whatever documentation you care to put there. No C/AL code is in a Documentation section. You have no format restrictions, other than common sense and your defined practices. OnInitReport(): It executes once when the report is opened. OnPreReport(): It executes once after the Request Page completes. All the Data Item processing follows this trigger. OnPostReport(): If the report is completed normally, this trigger executes once at the end of all of the other report processing. All the Data Item processing precedes this trigger. OnCreateHyperlink(): It does not apply to an RTC report. OnHyperlink(): It does not apply to an RTC report. There are general explanations of Report Triggers in the online C/SIDE Reference Guide (Help); you should also review those explanations.
Read more
  • 0
  • 0
  • 3411

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

Navigating Your Site using CodeIgniter 1.7: Part 2

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

Apache MyFaces Trinidad 1.2 Web Application Groundwork: Part 2

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

article-image-moodle-19-math-quizzes-part-2
Packt
30 Nov 2009
4 min read
Save for later

Moodle 1.9 Math Quizzes: Part 2

Packt
30 Nov 2009
4 min read
Adding a math quiz Once we've added a question or two to the question bank, we can add a quiz to our course. I want a simple quiz where each student is allowed one attempt with no help along the way. Let's see how to achieve this now: Return to your course's front page, choose a topic, click on the Add an activity drop-down menu, and select Quiz from the list. Give the quiz a name (this will appear on the course's front page) and, if you wish, you can specify a short introduction: Scroll down to the Attempts box. Set Attempts allowed to 1 and Adaptive mode to No: Scroll down to the bottom of the page, and click the Save and display button. A split screen page is displayed with the course question bank on the right and the (currently empty) quiz on the left: To add questions from the question bank to the quiz, simply select them and click on the Add to quiz button: The questions are now added to the quiz. You'll now see them listed on the left-hand side of the page: To preview the quiz, click on the Preview tab at the top of the page: That's it! The quiz is now configured. Recall that I set Adaptive mode to No. Adaptive mode adds a Submit button to each question, allowing students (with some suitable feedback from me) to learn from their mistakes as they work through the quiz. Try experimenting with this setting. See how your students behave with the Submit button. For example, don't let them think that they can guess a multiple choice answer until they eventually get it right. Remind them that they'll be penalized for each wrong answer. Encouraging students as they attempt the quiz You've seen that there are a lot of settings I've simply ignored as I've configured this quiz. Return to your course's front page, and click on Questions from the course administration block to open the course Question bank. Click on the edit icon next to the numerical question we configured earlier in this article. (Have you spotted that you can tell what type of question it is from the icon on the far-right? Hover the mouse pointer over the icon.): Remember how I mentioned that I'd started filling out feedback? I'm going to finish doing that now in this question by giving some General feedback: When you are happy with your feedback, remember to scroll to the bottom of the page and click on the Save changes button. Now, return to your course's front page, turn editing on, and click on the update icon next to the quiz we added in the previous section: On the quiz configuration page, scroll down to the Attempts section and set Adaptive mode to Yes: Scroll to the bottom of the page, and click on the Save changes button. Preview the quiz now, and notice that under each question there is a Submit button. Experiment with entering both correct and incorrect responses. Click on the Submit button, and see how Moodle reacts by giving the student our feedback. Remember: if you are planning to use Adaptive mode, then it's worth reminding your students that they will be penalized if they get an answer wrong! Reporting quiz results What's great about a Moodle quiz is the detailed reporting Moodle provides for us. Here is an example of the report page for my quiz once a student has attempted it. (In fact, this is a colleague of mine helping me to check that my feedback is understandable!): Such reporting not only allows us to see what our students have been up to, but I also find it an invaluable tool for determining the success of my teaching. Once someone has attempted your quiz, you can no longer modify it (add or remove questions). You will need to delete the attempts to unlock the quiz.
Read more
  • 0
  • 0
  • 1883

article-image-introducing-business-activity-monitoring
Packt
30 Nov 2009
7 min read
Save for later

Introducing Business Activity Monitoring

Packt
30 Nov 2009
7 min read
Introducing Business Activity Monitoring Typically, an organization's processes span multiple systems, channels, applications, departments, and external partners. In this case, how do we monitor such processes? What is the current state of the organizational processes? What is the benchmark for poorly-performing processes and exceptional processes? Most of the time, organizations are unable to answer such questions, or only have a vague idea for various reasons. Either they are monitoring the process with a very limited scope, or the mechanisms for monitoring the process are not in place to allow such details to be available. We rarely find organizations with process owners having an end-to-end view of a process. The big picture of a process is not available to the decision makers on a real-time basis. Also, we have seen that a BPM cycle involves more than just automating a business process. Although modeling and analysis of the process plays an important part before a process is executed, the benefit is further highlighted by using Business Rules technology for added agility of the enterprise. One important factor that closes the loop for BPM is the aspect of monitoring the process on a continuous basis to pinpoint bottlenecks, as the process is executing within a business, and acts as a feedback for potential process improvement exercise. The need to monitor an organization's business processes, especially as part of a larger BPM initiatives, is gaining considerable acceptability and demand. Such monitoring is the primary job of BAM. What is BAM? BAM allows a business to monitor its business processes, and related business events being generated in real-time, and provides an assessment of business process health based on pre-defined KPIs. This allows greater operational visibility of the business to relevant process owners for assessment and decision-making via real-time information dashboards. BAM also allows users to take actions based on information available on the dashboards. Typically, systems providing BAM capabilities use business events to capture information from varied sources such as ERP, workflow, BPM, legacy systems, external partners, and suppliers. These data sources provide the necessary business measures, which are evaluated by the BAM against set KPIs, and provide the information in a user-friendly dashboard for the users. BPM, SOA, and BAM BPM, SOA, and BAM can be used as independent, isolated technologies. However, their benefits are compounded for a business if used together in a complementary fashion. As we can see in the following reference architecture, BAM works along with the services and process components to capture event-related information from a business and IT perspective, for analysis and reporting purposes. In this case, SOA enables an organization to have a robust and flexible IT infrastructure that can help it easily achieve its BAM goals by allowing events and data from different services to be available to BAM for decision-making and realtime analysis. In an SOA-based solution, the business events will be inputs for BAM that are provided from the services layer. The linkage is via the BPM route, or through an event-based integration layer provided by an ESB. We can refer to this relationship between BAM and SOA as being Service Oriented Activity Monitoring (SOAM), as today's organizational setup will provide this event information to various BAM services interfaces exposed by the business applications in an enterprise. In case of BPM, the business process describes the key activities required to fulfill the specified business action and its associated KPIs. These actions are executed as transactions using an orchestration engine and the underlying service layer. These transaction occurrences result in multiple process events to be created for each step within a transaction. BAM's primary focus is on capturing, analyzing, and reporting on the transactions and events created by the process running over the SOA platform. In case of BPM, the business process describes the key activities required to fulfill the specified business action and its associated KPIs. These actions are executed as transactions using an orchestration engine and the underlying service layer. These transaction occurrences result in multiple process events to be created for each step within a transaction. BAM's primary focus is on capturing, analyzing, and reporting on the transactions and events created by the process running over the SOA platform. BAM usually looks at collecting information about a process based on the following attributes: Quantity or Volume of Transactions or Events: One of the primary areas covered by BAM is the volume of events generated by a process. This is not just an IT metric, but more of a business-related metric to help business stakeholders analyze information points such as the number of orders shipped in a day, the number of trades made during trading hours, the number of helpdesk tickets closed by a call centre, and so on. Usually, we will define these KPIs in a process definition, and use BAM to raise alerts to the portfolio manager if the process is exceeding those values, for example, "Send an alert as soon as the stock portfolio value decreases more than 3% ". Time Bound Events: In this case, the BAM concentrates on time-related metrics such as helpdesk ticket process cycle time for high priority issues, general process cycle times, supply-related waiting time, and so on. Again, based on certain thresholds, alerts can be sent out, or the reports can be viewed by the management in real-time using customized dashboards. Faults: These are situations where the process is not running well. This could be due to a hardware fault, or a process related issue such as deadlocks, or some other issue. BAM helps in these scenarios by helping to identify areas of problems, and providing important metrics with respect to frequencies of such errors and their potential damage on process performance, and other dimensions such as cost, schedules, and so on. User Defined Events and Conditions: Apart from the general dimensions of volume, time, and errors in a process, a business user might want to define KPIs around specific business issues that need analysis. For example, for compliance requirements, a bank might be required to keep track of all high-value transactions to prevent money laundering. During implementation, the business analysts can define this KPI in the process model, which will then be implemented mostly by a rules engine, and the events generated will be used by BAM to provide statistical reports and dashboards based on the frequency of these transactions, specific regions and user types involved in such transactions, and so on. The real value of BAM, however, does not come only from analysis of individual events, and exceptions generated during process execution. BAM provides a mechanism to correlate aggregated process events to help with a cause and effect analysis, pattern matching, and so on, which provides immense value to today's businesses. Although not in the scope of this article, another area which is gaining a lot of attention in this area is Complex Event Processing or CEP. This can be a perfect vehicle for implementing BAM in an enterprise in order to solve complex business issues. CEP is based on a concept of analyzing a set of specific events from a range of possible events, and identifying patterns that could be meaningful for an organization. Among the many applications of CEP, one example we can use is that of 'Algorithmic Trading', where CEP can be used to analyze a huge amount of market data, assess favorable patterns for trading, and initiate trading in a market based on this. A lot of banks are using this technology for performing low-value trades, and assessing risk positions simultaneously. CEP then records this information as a 'fingerprint', and maintains a history to use when deciding whether to execute similar trades in the future. As it gathers more experience and intelligence, the BAM tool supporting CEP can start to refine its predictive capabilities, and conduct more efficient calculations.
Read more
  • 0
  • 0
  • 2685

article-image-linux-e-mail-busting-spam-spamassassin
Packt
30 Nov 2009
13 min read
Save for later

Linux E-mail: Busting Spam with SpamAssassin

Packt
30 Nov 2009
13 min read
Spam, or unsolicited commercial e-mail (UCE) as it is sometimes called, is the scourge of the Internet. Spam has increased relentlessly over the last ten years and now accounts for over half of all Internet bandwidth. One in six consumers have acted on spam e-mails, so there is a strong business case for keeping spam out of your users' inboxes. There are a variety of different spam solutions, ranging from outsourcing your spam entirely to no action at all. However, if you have your own e-mail server, you can add spam filtering very easily. SpamAssassin is a very popular open source anti-spam tool. It won a Linux New Media Award-2006 as the "Best Linux-based Anti-spam Solution", and is considered by many to be the best free, open source, anti-spam tool, and better than many commercial products. In fact, several commercial products and services are based on SpamAssassin or previous versions of it. Why filter e-mail If you don't receive any spam, there may be no need to filter spam. However, once one spam message has been received, it is invariably followed by many more. Spammers can sometimes detect if a spam e-mail is viewed, using techniques such as Web bugs, which are tiny images in HTML e-mails that are fetched from web servers, and then know that an e-mail address is valid and vulnerable. If spam is filtered, the initial e-mail may never get seen, and consequently the spammer may not then target the e-mail address with further spam. Despite legal efforts against spam, it is actually on the increase. In Europe and the US, the recent legislation against spam (Directive 2002/58/EC and bill number S.877 respectively) has had little effect and spam is still on the increase in both regions. The main reason for this is that spam is a very good business model. It is very cheap to send spam, as little as one thousandth of a cent per e-mail, and it takes a very low hit rate before a profit is made. The spammer needs to turn just one spam in a hundred thousand or so into a sale to make a profit. As a result, there are many spammers and spam is used to promote a wide range of goods. Spamming costs are also negligible due to use of malware that uses innocent computers to send spam on their behalf. In contrast, the costs of spam to the recipient are remarkably high. Estimates have varied, from 10 cents per spam received, through 1,000 dollars per employee per year, up to a total cost of 140 billion dollars globally in 2007 alone. This cost is mainly labor—distracting people from their work by clogging their inboxes and forcing them to deal with many extra e-mails. Spam interferes with day-to-day work and can include material that is offensive to most people. Companies have a duty to protect their employees from such content. Spam filtering is a very cheap way of minimizing the costs and protecting the workforce. Spam is a moving target Spam isn't static. It changes on a day-to-day basis, as spammers add new methods to their arsenal and anti-spammers develop countermeasures. Due to this, the anti-spam tools that work best are those that are updated frequently. It's a similar predicament to antivirus software—virus definitions need to be updated regularly or new viruses won't be detected. SpamAssassin is regularly updated. In addition to new releases of the software, there is a vigorous community creating, critiquing, and testing new anti-spam rules. These rules can be downloaded automatically for up-to-date protection against spam. Let's discuss some of the measures used by SpamAssassin to fight spam: Open relays: These are e-mail servers that allow spammers to send e-mails even though they are not connected to the owner of the server in any way. To counter this, the anti-spam community has developed blocklists, also known as blacklists, which can be used by anti-spam software to detect spam. Any e-mail that has passed through a server on a blocklist is treated more suspiciously than one that has not. SpamAssassin uses a number of blocklists to test e-mails. Keyword filters: These are useful tools against spam. Spammers tend to repeat the same words and phrases again and again. Rules to detect these phrases are used extensively by SpamAssassin. These make up the bulk of the tests, and the user community rules mentioned previously is normally of this form. They allow specific words, phrases, or sequences of letters, numbers, and punctuation to be detected. Blacklists and whitelists: These are used to list known senders of spam and sources of good e-mail respectively. E-mails from an address on a blacklist are probably spam and are treated accordingly, while e-mails from addresses on a whitelist will be less likely to be treated as spam. SpamAssassin allows the user to enter blacklists and whitelists manually, and also builds up an automatic whitelist and blacklist based on the e-mails that it processes. Statistical filters: These are automated systems that give the probability that an e-mail is spam. This filtration is based on what the filter has seen previously as both spam and non-spam. They generally work by finding words that are present in one type of e-mail but not the other, and using this knowledge to determine which type a new e-mail is. SpamAssassin has a statistical filter called the Bayesian filter that can be very effective in improving detection rates. Content databases: These are mass e-mail detection systems. A lot of e-mail servers receive and submit e-mails to central servers. If the same e-mail is sent to thousands of recipients, it is probably a spam. The content databases prevent confidential e-mails from being sent to the server, by using a technique called hashing that also lowers the amount of data sent to the server. SpamAssassin can integrate with several content databases, notably Vipul's Razor (http://razor.sourceforge.net), Pyzor (http://sourceforge.net/apps/trac/pyzor/), and the Distributed Checksum Clearinghouse, that is, DCC (http://www.rhyolite.com/dcc/). URL blocklists: These are similar to open relay blocklists, but list the websites used by spammers. In nearly all spams, a web address is given. A database of these is built so that spam e-mails can be quickly detected. This is a very efficient and effective tool against spam. By default, SpamAssassin uses Spam URI Realtime BlockLists (SURBLs), without any further configuration required. Spam filtering options Spam can be filtered on the server or the client. The two approaches are explained next. In the first scenario, spam is filtered on the client. Mail is processed by the MTA. The e-mail is then placed in the appropriate user's inbox. The e-mail client reads all new e-mail from the inbox. The e-mail client then passes the e-mail to the filter. When the filter returns the results, the client can display the valid e-mail and either discard spam or file it in a separate folder. In this approach, the spam filtering is always done by the client and is always done when new e-mail is processed. Often when the user may be present, so he or she may either experience a delay before e-mail is visible or there may be a period where spam e-mail is present in the inbox before the client software can filter the spam from view. The amount of spam filtering that can be performed on the client may be limited. In particular, the network tests such as open relay blocklists or SURBLs might be too time consuming or complex to perform on the user's PC. As spam is a moving target, updating many client PCs can become a difficult administrative task. In the second scenario, the spam filtering is performed on the e-mail server. Incoming e-mail is received by the MTA. It is then passed on to the spam filter. The results are then sent back to the MTA. Depending on the results, the MTA places the e-mail in the appropriate user's inbox (4a), or in a separate folder for spam (4b). The e-mail client accesses e-mails in the user's inbox and it can also access the spam folder if required. This approach has several advantages: The spam filtering is done when the e-mail is received, which may be any time of the day. The user is less likely to be inconvenienced by delays. The server can specialize in spam filtering. It may use external services such as open relay blocklists, online content databases, and SURBLs. Configuration is centralized, which will ease setup (for example, firewalls may need to be configured to use online spam tests) and also maintenance (updating of rules or software). On the other hand, the disadvantages include: A single point of failure now exists. However, with care, a broken spam filtering service can be configured around. If the service is not available, e-mail will still be delivered but spam will not be filtered. All spam must be processed by one service. If this service is not scalable, large volumes of e-mail may affect mail delivery times, resulting in poor or intermittent filtering, or possibly even the loss of e-mail service. Introduction to SpamAssassin Spam filtering actually involves two phases—detecting the spam and then doing something with it. SpamAssassin is a spam detector and it modifies the e-mail it processes by putting in headers to mark whether it is spam. It is up to the MTA or the mail delivery agent in the e-mail system to react to the headers that SpamAssassin creates in an e-mail, to filter it out. However, it's possible that another part of the e-mail system could perform this task. The previous figure gives a schematic representation of SpamAssassin. At the heart of SpamAssassin is its Rules Engine that determines which rules are called. Rules trigger whether the various tests are used, including the Bayesian Filter, the network tests, and the auto-whitelists. SpamAssassin uses various databases to do its work, and these are shown too. The rules and scores are text files. Default rules and scores are included in the SpamAssassin distribution and, as we will see, both system administrators and users can add rules or change the scores of existing rules by adding them to files in specific locations. The Bayesian filter (which is a major part of SpamAssassin, and will be covered later) uses a database of statistical data based on previous spam and non-spam e-mails. The Auto-Blacklist/Whitelist also creates its own database. Downloading and installing SpamAssassin SpamAssassin is slightly different from most of the software that is used in this book. It is written in a language called Perl, which has its own distribution method called CPAN (Comprehensive Perl Archive Network). CPAN is a large website of Perl software (normally, Perl modules), and the term CPAN is also the name of the software used to download those modules and install them. Though SpamAssassin is provided as a package by many Linux distributions, we strongly recommend that you install it from source rather than use a package. This way, you will get the latest version of SpamAssassin rather than the one that was current when your Linux distributer created its release. Most Perl users will build Perl modules using CPAN and experience no difficulties. CPAN can automatically locate and install any dependencies (other components that are required to make the desired component work properly). From a Perl point of view, using CPAN to install Perl modules is like using the rpm or apt-get commands in Linux. The basics are very simple and, once a system is configured, it generally works every time. However, learning and configuring a new way of installing software may put off some people. A SpamAssassin release is distributed in source form, but administrators of Red Hat Package Manager (RPM) based systems can easily convert the latest SpamAssassin release into rpm format and then the regular rpm command can be used to install the package. The Debian repository is updated fairly quickly when SpamAssassin is updated and the regular apt-get commands can be used to install SpamAssassin. We strongly advise you to install via apt-get, CPAN, or using the rpmbuild command as described next, in preference to using an RPM provided by a distributor. As SpamAssassin is a Perl Module, it appears on CPAN first. In fact, it is only released when it arrives at CPAN. Users of CPAN can download the latest version of SpamAssassin literally minutes after it has been released. Support is also easier to obtain if SpamAssassin is built from source. Some distributors make unusual decisions when creating their RPM of SpamAssassin or may modify certain default values. These make obtaining support more difficult. RPMs also take time to be delivered. Distributors need time to build and test new versions of software before they release them, and most software packages are not updated as quickly as SpamAssassin. So, Linux distributions may not provide the latest software, and what is provided can be several versions out of date. Using CPAN The prerequisites for installing SpamAssassin 3.2.5 using CPAN are as follows: Perl version 5.6.1 or later: Most modern Linux distributions will include this as a part of the base package. Several Perl modules: The current version of SpamAssassin needs the Digest::SHA1, HTML::Parser, and the Net::DNS modules. CPAN will install these if you configure it to follow dependencies, but there are many additional Perl modules that are optional and should be installed to get the best spam detection. CPAN will issue warnings with the module names, which will enable you to identify and install them. C compiler: This may not be installed by default and may have to be added using the rpm command. The compiler used will normally be called gcc. Internet connection: CPAN will attempt to download the modules using HTTP or FTP, so the network should be configured to allow this. Configuring CPAN If you've used CPAN before, you can skip to the next section, Installing SpamAssassin Using CPAN. If a proxy server is required for Internet traffic, CPAN (and other Perl modules and scripts) will use the http_proxy environment variable. If the proxy requires a username and password, these need to be specified using environment variables. As CPAN is normally run as root, these commands should be entered as root: # HTTP_proxy=http://proxy.name:80# export HTTP_proxy# HTTP_proxy_user=username# export HTTP_proxy_user# HTTP_proxy_pass=password# export HTTP_proxy_pass Next, enter this command: # perl -MCPAN -e shell If the output is similar to the following, the CPAN module is already installed and configured, and you can skip to the next section, Installing SpamAssassin Using CPAN. cpan shell -- CPAN exploration and modules installation (v1.7601)ReadLine support enabled If the output prompts for manual configuration, as shown next, the CPAN module is installed but not configured. Are you ready for manual configuration? [yes] During configuration, the CPAN Perl module prompts for answers to around 30 questions. For most of the questions, selecting the default value is the best response. This initial configuration must be completed before the CPAN Perl module can be used. The questions are mainly about the location of various utilities, and the defaults can be chosen by pressing Enter. The only question for which we should change the default is the one about building prerequisite modules. If we configure CPAN to follow dependencies, it will install the required modules without prompting. Policy on building prerequisites (follow, ask or ignore)? [ask] follow Once CPAN is configured, exit the shell by typing exit and pressing Enter. We are now ready to use CPAN to install SpamAssassin.
Read more
  • 0
  • 0
  • 1942
article-image-ways-improve-performance-your-server-modsecurity-25
Packt
30 Nov 2009
13 min read
Save for later

Ways to improve performance of your server in ModSecurity 2.5

Packt
30 Nov 2009
13 min read
A typical HTTP request To get a better picture of the possible delay incurred when using a web application firewall, it helps to understand the anatomy of a typical HTTP request, and what processing time a typical web page download will incur. This will help us compare any added ModSecurity processing time to the overall time for the entire request. When a user visits a web page, his browser first connects to the server and downloads the main resource requested by the user (for example, an .html file). It then parses the downloaded file to discover any additional files, such as images or scripts, that it must download to be able to render the page. Therefore, from the point of view of a web browser, the following sequence of events happens for each file: Connect to web server. Request required file. Wait for server to start serving file. Download file. Each of these steps adds latency, or delay, to the request. A typical download time for a web page is on the order of hundreds of milliseconds per file for a home cable/DSL user. This can be slower or faster, depending on the speed of the connection and the geographical distance between the client and server. If ModSecurity adds any delay to the page request, it will be to the server processing time, or in other words the time from when the client has connected to the server to when the last byte of content has been sent out to the client. Another aspect that needs to be kept in mind is that ModSecurity will increase the memory usage of Apache. In what is probably the most common Apache configuration, known as "prefork", Apache starts one new child process for each active connection to the server. This means that the number of Apache instances increases and decreases depending on the number of client connections to the server.As the total memory usage of Apache depends on the number of child processes running and the memory usage of each child process, we should look at the way ModSecurity affects the memory usage of Apache. A real-world performance test In this section we will run a performance test on a real web server running Apache 2.2.8 on a Fedora Linux server (kernel 2.6.25). The server has an Intel Xeon 2.33 GHz dual-core processor and 2 GB of RAM. We will start out benchmarking the server when it is running just Apache without having ModSecurity enabled. We will then run our tests with ModSecurity enabled but without any rules loaded. Finally, we will test ModSecurity with a ruleset loaded so that we can draw conclusions about how the performance is affected. The rules we will be using come supplied with ModSecurity and are called the "core ruleset". The core ruleset The ModSecurity core ruleset contains over 120 rules and is shipped with the default ModSecurity source distribution (it's contained in the rules sub-directory). This ruleset is designed to provide "out of the box" protection against some of the most common web attacks used today. Here are some of the things that the core ruleset protects against: Suspicious HTTP requests (for example, missing User-Agent or Accept headers) SQL injection Cross-Site Scripting (XSS) Remote code injection File disclosure We will examine these methods of attack, but for now, let's use the core ruleset and examine how enabling it impacts the performance of your web service. Installing the core ruleset To install the core ruleset, create a new sub-directory named modsec under your Apache conf directory (the location will vary depending on your distribution). Then copy all the .conf files from the rules sub-directory of the source distribution to the new modsec directory: mkdir /etc/httpd/conf/modseccp/home/download/modsecurity-apache/rules/modsecurity_crs_*.conf /etc/httpd/conf/modsec Finally, enter the following line in your httpd.conf file and restart Apache to make it read the new rule files: # Enable ModSecurity core rulesetInclude conf/modsecurity/*.conf Putting the core rules in a separate directory makes it easy to disable them—all you have to do is comment out the above Include line in httpd.conf, restart Apache, and the rules will be disabled. Making sure it works The core ruleset contains a file named modsecurity_crs_10_config.conf. This file contains some of the basic configuration directives needed to turn on the rule engine and configure request and response body access. Since we have already configured these directives, we do not want this file to conflict with our existing configuration, and so we need to disable this. To do this, we simply need to rename the file so that it has a different extension as Apache only loads *.conf files with the Include directive we used above: $ mv modsecurity_crs_10_config.conf modsecurity_crs_10_config.conf.disabled Once we have restarted Apache, we can test that the core ruleset is loaded by attempting to access an URL that it should block. For example, try surfing to http://yourserver/ftp.exe and you should get the error message Method Not Implemented, ensuring that the core rules are loaded. Performance testing basics So what effect does loading the core ruleset have on web application response time and how do we measure this? We could measure the response time for a single request with and without the core ruleset loaded, but this wouldn't have any statistical significance—it could happen that just as one of the requests was being processed, the server started to execute a processor-intensive scheduled task, causing a delayed response time. The best way to compare the response times is to issue a large number of requests and look at the average time it takes for the server to respond. An excellent tool—and the one we are going to use to benchmark the server in the following tests—is called httperf. Written by David Mosberger of Hewlett Packard Research Labs, httperf allows you to simulate high workloads against a web server and obtain statistical data on the performance of the server. You can obtain the program at http://www.hpl.hp.com/research/linux/httperf/ where you'll also find a useful manual page in the PDF file format and a link to the research paper published together with the first version of the tool. Using httperf We'll run httperf with the options --hog (use as many TCP ports as needed), --uri/index.html (request the static web page index.html) and we'll use --num-conn 1000 (initiate a total of 1000 connections). We will be varying the number of requests per second (specified using --rate) to see how the server responds under different workloads. This is what the typical output from httperf looks like when run with the above options: $ ./httperf --hog --server=bytelayer.com --uri /index.html --num-conn1000 --rate 50Total: connections 1000 requests 1000 replies 1000 test-duration20.386 sConnection rate: 49.1 conn/s (20.4 ms/conn, <=30 concurrentconnections)Connection time [ms]: min 404.1 avg 408.2 max 591.3 median 404.5stddev 16.9Connection time [ms]: connect 102.3Connection length [replies/conn]: 1.000Request rate: 49.1 req/s (20.4 ms/req)Request size [B]: 95.0Reply rate [replies/s]: min 46.0 avg 49.0 max 50.0 stddev 2.0 (4samples)Reply time [ms]: response 103.1 transfer 202.9Reply size [B]: header 244.0 content 19531.0 footer 0.0 (total19775.0)Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0CPU time [s]: user 2.37 system 17.14 (user 11.6% system 84.1% total95.7%)Net I/O: 951.9 KB/s (7.8*10^6 bps)Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 The output shows us the number of TCP connections httperf initiated per second ("Connection rate"), the rate at which it requested files from the server ("Request rate"), and the actual reply rate that the server was able to provide ("Reply rate"). We also get statistics on the reply time—the "reply time – response" is the time taken from when the first byte of the request was sent to the server to when the first byte of the reply was received—in this case around 103 milliseconds. The transfer time is the time to receive the entire response from the server. The page we will be requesting in this case, index.html, is 20 KB in size which is a pretty average size for an HTML document. httperf requests the page one time per connection and doesn't follow any links in the page to download additional embedded content or script files, so the number of such links in the page is of no relevance to our test. Getting a baseline: Testing without ModSecurity When running benchmarking tests like this one, it's always important to get a baseline result so that you know the performance of your server when the component you're measuring is not involved. In our case, we will run the tests against the server when ModSecurity is disabled. This will allow us to tell which impact, if any, running with ModSecurity enabled has on the server. Response time The following chart shows the response time, in milliseconds, of the server when it is running without ModSecurity. The number of requests per second is on the horizontal axis: As we can see, the server consistently delivers response times of around 300 milliseconds until we reach about 75 requests per second. Above this, the response time starts increasing, and at around 500 requests per second the response time is almost a second per request. This data is what we will use for comparison purposes when looking at the response time of the server after we enable ModSecurity. Memory usage Finding the memory usage on a Linux system can be quite tricky. Simply running the Linux top utility and looking at the amount of free memory doesn't quite cut it, and the reason is that Linux tries to use almost all free memory as a disk cache. So even on a system with several gigabytes of memory and no memory-hungry processes, you might see a free memory count of only 50 MB or so. Another problem is that Apache uses many child processes, and to accurately measure the memory usage of Apache we need to sum the memory usage of each child process. What we need is a way to measure the memory usage of all the Apache child processes so that we can see how much memory the web server truly uses. To solve this, here is a small shell script that I have written that runs the ps command to find all the Apache processes. It then passes the PID of each Apache process to pmap to find the memory usage, and finally uses awk to extract the memory usage (in KB) for summation. The result is that the memory usage of Apache is printed to the terminal. The actual shell command is only one long line, but I've put it into a file called apache_mem.sh to make it easier to use: #!/bin/sh# apache_mem.sh# Calculate the Apache memory usageps -ef | grep httpd | grep ^apache | awk '{ print $2 }' | xargs pmap -x | grep 'total kB' | awk '{ print $3 }' | awk '{ sum += $1 } END { print sum }' Now, let's use this script to look at the memory usage of all of the Apache processes while we are running our performance test. The following graph shows the memory usage of Apache as the number of requests per second increases: Apache starts out consuming about 300 MB of memory. Memory usage grows steadily and at about 150 requests per second it starts climbing more rapidly. At 500 requests per second, the memory usage is over 2.4 GB—more than the amount of physical RAM of the server. The fact that this is possible is because of the virtual memory architecture that Linux (and all modern operating systems) use. When there is no more physical RAM available, the kernel starts swapping memory pages out to disk, which allows it to continue operating. However, since reading and writing to a hard drive is much slower than to memory, this starts slowing down the server significantly, as evidenced by the increase in response time seen in the previous graph. CPU usage In both of the tests above, the server's CPU usage was consistently around 1 to 2%, no matter what the request rate was. You might have expected a graph of CPU usage in the previous and subsequent tests, but while I measured the CPU usage in each test, it turned out to run at this low utilization rate for all tests, so a graph would not be very useful. Suffice it to say that in these tests, CPU usage was not a factor. ModSecurity without any loaded rules Now, let's enable ModSecurity—but without loading any rules—and see what happens to the response time and memory usage. Both SecRequestBodyAccess and SecResponseBodyAccess were set to On, so if there is any performance penalty associated with buffering requests and responses, we should see this now that we are running ModSecurity without any rules. The following graph shows the response time of Apache with ModSecurity enabled: We can see that the response time graph looks very similar to the response time graph we got when ModSecurity was disabled. The response time starts increasing at around 75 requests per second, and once we pass 350 requests per second, things really start going downhill. The memory usage graph is also almost identical to the previous one: Apache uses around 1.3 MB extra per child process when ModSecurity is loaded, which equals a total increase of memory usage of 26 MB for this particular setup. Compared to the total amount of memory Apache uses when the server is idle (around 300 MB) this equals an increase of about 10%. Mod Security with the core ruleset loaded Now for the really interesting test we'll run httperf against ModSecurity with the core ruleset loaded and look at what that does to the response time and memory usage. Response time The following graph shows the server response time with the core ruleset loaded: At first, the response time is around 340 ms, which is about 35 ms slower than in previous tests. Once the request rate gets above 50, the server response time starts deteriorating. As the request rates grows, the response time gets worse and worse, reaching a full 5 seconds at 100 requests per second. I have capped the graph at 100 requests per second, as the server performance has already deteriorated enough at this point to allow us to see the trend. We see that the point at which memory usage starts increasing has gone down from 75 to 50 requests per second now that we have enabled the core ruleset. This equals a reduction in the maximum number of requests per second the server can handle of 33%.
Read more
  • 0
  • 0
  • 20675

article-image-business-process-orchestration-soa
Packt
30 Nov 2009
7 min read
Save for later

Business Process Orchestration for SOA

Packt
30 Nov 2009
7 min read
Process Orchestration can simply be defined as the coordination of events and activities in a process at technical levels, to help achieve objectives laid down by the business. From an SOA perspective, orchestration involves direction and management of multiple component services to create a composite application or an end-to-end process. While orchestration tends to imply a single central engine performing the coordination act, another overlapping concept of choreography applies to sharing this coordination activity across multiple autonomous systems. BPM Architecture and Role of Business Process Orchestration While we are covering orchestration  for SOA, it is worthwhile to also discuss reference architecture for BPM, to understand how all components of technology fit together for modeling, executing, monitoring, and optimizing a business process. Following an architecture-lead approach, as always, is a good way to initially guide BPM projects. It is not necessary to implement all aspects of this architecture from day one, but as we mature with our BPM implementation, its coverage can be increased to gain maximum value. From the perspective of this article, this reference architecture provides an understanding of how process execution and orchestration is a core activity in bridging the abstract business models and underlying SOA infrastructure. If you look at the following architecture for BPM, you will realize that it is divided into layers and groups. The vertical right side covers the aspects of modeling the processes, business rules, and services. The horizontal stack starts with the presentation layer, which allows multiple channels through which a company's customers, employees, and partners can interact. It could be a web portal, a hand-held device, and so on. These channels are supported by the process orchestration layer, which assists in orchestrating different aspects of a business process to provide information to respective users in a channel. In this layer, we will have a process engine that will take inputs from the presentation layer and interface with underlying technologies and services to complete an end-to-end process. This layer will be responsible for ensuring that information is gathered from all sources at the right time, to enable a smooth process flow. The requirements for process orchestration will be fed by the activities performed by the business modeling team and the development teams, working on the process models using standards such as BPMN and BPEL. The orchestration layer will then interface with what we call 'Enterprise Services', which could be business services, technical services, or utility services, available either as basic services, or a composition of multiple services required to support the process orchestration. To enable access to these enterprise-level services, we will have an integration layer or an Enterprise Service Bus, which will provide a standards-based interface to multiple systems within or outside the organization, and also human service providers. We also have a layer of data management services that will be different high-level data sources that the BPM landscape will use. An example is a service registry to manage multiple services or metadata, which will manage information about all of the available data sources in the landscape to which this process has access. On the vertical left side, we have the monitoring services, which will capture all the events generated by the process to help in analyzing the process performance against key performance indicators laid down by the business. As we move ahead in this article, we will use this reference architecture to understand how various technology components fit together. Let us now go ahead with an example to see how we can orchestrate a process using Oracle BPEL Process Manager. Executing BPEL Processes in BPEL Process Manager One of the fundamental benefits of using a BPM system for modeling a business process – in this case the Oracle suite of products – is to allow models created using BPMN at the business level to be executed, and to automate manual processes. It also allows a business to evaluate gaps in current processes and identify the remedial actions that can be implemented quickly using the execution engine. When working on the example for the 'Portfolio Account Opening' process, we created the business process model using BPMN, analyzed the process, converted the BPMN model into a process blueprint to be shared by the development teams, filled the technical gaps, and enriched and finally deployed the process to the BPEL Process Manager. Let us take the next step in understanding how our deployed process will work, and the functionality it offers to the users working on this process. Our aim is to make you aware of how process-driven SOA works for an end-to-end process. This explanation assumes that you have some working knowledge of BPEL constructs such as activities, partnerlinks and so on. XSD and WSDL are used with in the JDeveloper environment to create and deploy BPEL processes. For a detailed understanding of BPEL and its complex constructs, you may want to refer to these resources. For our case, we will use a simplistic representation of information, tasks and moving from one task to another. Let us go through a series of steps to trigger an instance of the account opening process: Initiation of the Process Instance First, let us initiate the services related to SOA Suite. You can open them by selecting Start SOA suite from the Program menu. After the SOA suite services have started, we will open the SOA Launch Console, which provides a dashboard for all tools under the SOA suite that can be accessed from this location. To open the console, you can either enter the URL, which is typically http://localhost:8888; unless you have specified something specific during your installation. You can also access the console from the Program menu and select SOA Launch Console. The following screenshot shows what the SOA Suite console looks like. And As you can see, it provides, in addition to from all the product literature and technical guides, links to the main components of the SOA suite including BPEL Control, which is highlighted in the image. Open the Oracle BPEL Process Manager administration interface by clicking the BPEL Control link to access the details of the account opening process we deployed earlier. The first screen we see is the Process Dashboard, which provides us with the information on the currently-deployed processes in the database. As we can see, we have our 'Portfolio Account Opening Process'. There are currently some instances of the processes already running, and some instances have completed recently. To test the flow of the process and its behavior, trigger a new process instance for the deployed process through this console. To do this, click on the 'Portfolio_Account_Opening_Process' link on the dashboard to access details of our deployed process, and initiate a new instance. In a production environment, this step could be automated through a customized graphical interface. We will use the BPEL Process Manager to initiate this test process. As you can see, the BPEL process Portfolio_Account_Opening_Process has been deployed from the development environment inside the BPEL Process Manager. To initiate the process instance, we have used a simple string as the input. In this case, we will just start the process by providing Open Account as the payload string, and posting the XML message to initiate the process instance. To check whether the process instance has started, we can view the visual flow for the instance by clicking the visual flow link. The following visual flow shows that we have triggered the instance of the process, and it has reached a stage where the bank has received the application.
Read more
  • 0
  • 0
  • 5335

article-image-polygon-modeling-handgun-using-blender-3d-249-part-1
Packt
30 Nov 2009
3 min read
Save for later

Polygon Modeling of a Handgun using Blender 3D 2.49: Part 1

Packt
30 Nov 2009
3 min read
With the base model created, we will be able to analyze the shape of our model and evaluate the next steps of the project. We can even decide to make changes to the project because new ideas may appear when we see the object in 3D rather than in 2D. Starting with a background image The first step to start the modeling is to add the reference image as the background of the Blender 3D view. To do that, we can go to the View menu in the 3D view and choose Background Image. The background image in Blender appears only when we are at an orthogonal or Camera view. The background image is a simple black and white drawing of the weapon, but it will be a great reference for modeling. Before we go any further, it's important to point out a few things about the Background Image menu. We can make some adjustments to the image if it doesn't fit our Blender view: Use: With this button turned on, we will use the image as a background. If you want to hide the image, just turn it off and the image will disappear. Blend: The blend slider will control the transparency of the image. If you feel that the image is actually blocking your view of the whole model, making it a bit transparent may help. Size: As the name says, we can control the scale of the image. X and Y offset: With this option, we will be able to move the image in the X or Y axis to place it in a specific location. After clicking on the Use button, just hit the load button and choose the image to be used as a reference. Since you don't have the image used in this example, visit the Packt web site and download the project files from Support. If you've never used a reference image in Blender, it is important to note that the reference images appear only in 3D view when we are using the orthographic view or the camera view mode. It works only in the top, right, left, front, and other orthographic views. If you hit 5 and change the view to perspective, the image will disappear. By using the middle mouse button or the scroll to rotate the view, the image disappears. However, it's still there and we can see the image again by changing the view to an orthogonal or camera view. Make the image more transparent by using the Blend control. It will help in focusing on the model instead of the image. A value of 0.25 will be enough to help in the modeling without causing confusion.
Read more
  • 0
  • 0
  • 3319
article-image-tabs-jquery-ui-17
Packt
30 Nov 2009
7 min read
Save for later

Tabs in jQuery UI 1.7

Packt
30 Nov 2009
7 min read
The UI tabs widget is used to toggle visibility across a set of different elements, each element containing content that can be accessed by clicking on its heading which appears as an individual tab. The tabs are structured so that they line up next to each other, whereas the content sections are layered on top of each other, with only the top one visible. Clicking a tab will highlight the tab and bring its associated content panel to the top of the stack. Only one content panel can be open at a time. The following screenshot shows the different components of a set of UI tabs: A basic tab implementation The structure of the underlying HTML elements, on which tabs are based, is rigid and widgets require a certain number of elements for them to work. The tabs must be created from a list element (ordered or unordered) and each list item must contain an <a> element. Each link will need to have a corresponding element with a specified id that it is associated with the link's href attribute. We'll clarify the exact structure of these elements after our first example. In a new file in your text editor, create the following page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="development-bundle/themes/smoothness/ui.all.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Tabs Example 1</title> </head> <body> <div id="myTabs"> <ul> <li><a href="#a">Tab 1</a></li> <li><a href="#b">Tab 2</a></li> </ul> <div id="a">This is the content panel linked to the first tab,  it is shown by default.</div> <div id="b">This content is linked to the second tab and will be shown when its tab is clicked.</div> </div> <script type="text/javascript" src="development-bundle/jquery-1.3.2.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.core.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.tabs.js"></script> <script type="text/javascript"> $(function(){ $("#myTabs").tabs(); }); </script> </body></html> Save the code as tabs1.html in your jqueryui working folder. Let's review what was used. The following script and CSS resources are needed for the default tab widget instantiation: ui.all.css jquery-1.3.2.js ui.core.js ui.tabs.js A tab widget consists of several standard HTML elements arranged in a specific manner (these can be either hardcoded into the page, or added dynamically, or can be a mixture of both depending on the requirements of your implementation). An outer container element, which the tabs method is called on A list element( <ul> or <ol>) An <a> element for each tab An element for the content of each tab The first two elements within the outer container make the clickable tab headings, which are used to show the content section that is associated with the tab. Each tab should include a list item containing the link. The href attribute of the link should be set as a fragment identifier, prefixed with #. It should match the id attribute of the element that forms the content section, with which it is associated. The content sections of each tab are created by the elements. The id attribute is required and will be targeted by its corresponding element. We've used elements in this example as the content panels for each tab, but other elements, such as elements can also be used. The elements discussed so far, along with their required attributes, are the minimum that are required from the underlying markup.We link to several <script> resources from the library at the bottom of the <body> before its closing tag. Loading scripts last, after stylesheets and page elements is a proven technique for improving performance. After linking first to jQuery, we link to the ui.core.js file that is required by all components (except the effects, which have their own core file). We then link to the component's source file that in this case is ui.tabs.js.After the three required script files from the library, we can turn to our custom < script> element in which we add the code that creates the tabs. We simply use the $(function(){}); shortcut to execute our code when the document is ready. We then call the tabs() widget method on the jQuery object, representing our tabs container element (the <ul> with an id of myTabs).When we run this file in a browser, we should see the tabs as they appeared in the first screenshot of this article(without the annotations of course). Tab CSS framework classes Using Firebug for Firefox (or another generic DOM explorer) we can see that a variety of class names are added to the different underlying HTML elements that the tabs widget is created from, as shown in the following screenshot: Let's review these briefly. To the outer container < div> the following class names are added: Class name Purpose ui-tabs Allows tab-specific structural CSS to be applied. ui-widget Sets generic font styles that are inherited by nested elements. ui-widget-content Provides theme-specific styles. ui-corner-all Applies rounded corners to container. The first element within the container is the < ul> element. This element receives the following class names: Class name Purpose ui-tabs-nav Allows tab-specific structural CSS to be applied. ui-helper-reset Neutralizes browser-specific styles applied to <ul> elements. ui-helper-clearfix Applies the clear-fix as this element has children that are floated. ui-widget-header Provides theme-specific styles. ui-corner-all Applies rounded corners. The individual < li> elements are given the following class names: Class name Purpose ui-state-default Applies theme-specific styles. ui-corner-top Applies rounded corners to the top edges of the elements. ui-tabs-selected This is only applied to the active tab. On page load of the default implementation this will be the first tab. Selecting another tab will remove this class from the currently selected tab and apply it to the new tab. ui-state-active Applies theme-specific styles to the currently selected tab. This class name will be added to the tab that is currently selected, just like the previous class name. The reason there are two class names is that ui-tabs-selected provides the functional CSS, while ui-state-active provides the visual, decorative styles. The < a> elements within each < li> are not given any class names, but they still have both structural and theme-specific styles applied to them by the framework. Finally, the elements that hold each tab's content are given the following class names: Class name Purpose ui-tabs-panel Applies structural CSS to the content panels ui-widget-content Applies theme-specific styles ui-corner-bottom Applied rounded corners to the bottom edges of the content panels All of these classes are added to the underlying elements automatically by the library, we don't need to manually add them when coding the page. As these tables illustrate, the CSS framework supplies the complete set of both structural CSS styles that control how the tabs function and theme-specific styles that control how the tabs appear, but not how they function. We can easily see which selectors we'll need to override if we wish to tweak the appearance of the widget, which is what we'll do in the following section.
Read more
  • 0
  • 0
  • 4260

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

Navigating Your Site using CodeIgniter 1.7: Part 1

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