From 51db38c9423a1d3bf476bb30054cf3288ee16c88 Mon Sep 17 00:00:00 2001 From: xue <> Date: Tue, 3 Apr 2007 21:43:22 +0000 Subject: Added blog-tutorial. --- .../protected/pages/Day1/CreateContact.page | 181 +++++++++++++++++++++ .../blog-tutorial/protected/pages/Day1/Setup.page | 161 ++++++++++++++++++ .../protected/pages/Day1/ShareLayout.page | 178 ++++++++++++++++++++ .../protected/pages/Day1/directories.gif | Bin 0 -> 3611 bytes .../protected/pages/Day1/directories2.gif | Bin 0 -> 4147 bytes .../protected/pages/Day1/directories3.gif | Bin 0 -> 3531 bytes .../blog-tutorial/protected/pages/Day1/output.gif | Bin 0 -> 15045 bytes 7 files changed, 520 insertions(+) create mode 100644 demos/blog-tutorial/protected/pages/Day1/CreateContact.page create mode 100644 demos/blog-tutorial/protected/pages/Day1/Setup.page create mode 100644 demos/blog-tutorial/protected/pages/Day1/ShareLayout.page create mode 100644 demos/blog-tutorial/protected/pages/Day1/directories.gif create mode 100644 demos/blog-tutorial/protected/pages/Day1/directories2.gif create mode 100644 demos/blog-tutorial/protected/pages/Day1/directories3.gif create mode 100644 demos/blog-tutorial/protected/pages/Day1/output.gif (limited to 'demos/blog-tutorial/protected/pages/Day1') diff --git a/demos/blog-tutorial/protected/pages/Day1/CreateContact.page b/demos/blog-tutorial/protected/pages/Day1/CreateContact.page new file mode 100644 index 00000000..07adbe93 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day1/CreateContact.page @@ -0,0 +1,181 @@ + + +

Creating Contact Page

+ +

+We have created a default page Home.page using the PRADO command line tool. The page is relatively static because it does not containt dynamic content. In this section, we will create an interactive page named Contact. +

+ +

+The purpose of the Contact page is to collect feedback from Web users of our blog system. To achieve this goal, we plan to present users a feedback form to fill with. In this form, we will require users to provide their name, email address and feedback content. After the form is filled and submitted, an email containing the feedback will be sent to the site administrator. +

+ +

+To create the Contact page, we need two files under the pages directory: the page template file Contact.page and the page class file Contact.php. +

+ + + + +A page must have either a template file (extension .page) or a class file, or both: +

+ + +
+ + +

Creating Page Template

+ +

+We first create the template file for the Contact page. +

+ +

+We use template to organize the presentational layout of the feedback form. In the template, we use textboxes to collect user's name, email and feedback. And we use validators to ensure that the user provides all these information before submitting the feedback form. The whole template looks like the following: +

+ + + +My Blog - Contact + +

Contact

+

Please fill out the following form to let me know your feedback on my blog. Thanks!

+ +<com:TForm> + + ...textbox and validator for user's name... + + ...textbox and validators for user's email... + + ...textbox and validator for user's feedback content... + + <com:TButton Text="Submit" OnClick="submitButtonClicked" /> + +</com:TForm> + + + +
+ +

+The template looks very similar to a normal HTML page. The main difference is that the template contains a few <com:> tags. Each <com:> tag refers to a control whose properties are being initialized with name-value pairs in the tag. For example, the <com:TButton> refers to the TButton control which displays a button that users can click on to submit the feedback form. For complete template syntax, please refer to the Quickstart Tutorial. +

+ + +PRADO provides a control for every type of HTML input. For example, TTextBox displays a text input field, TDropDownList displays a combobox. Each control is a component that may be accessed in code as an object with configurable properties. + + +

+The following template shows the detail about "...textbox and validators for user's email..." in the above. +

+ + +Your Email: +<com:TRequiredFieldValidator + ControlToValidate="Email" + ErrorMessage="Please provide your email address." + Display="Dynamic" + /> +<com:TEmailAddressValidator + ControlToValidate="Email" + ErrorMessage="You entered an invalid email address." + Display="Dynamic" + /> +
+<com:TTextBox ID="Email" /> +
+
+ +

+Three controls are used here: +

+ + + + +Writing templates with plain text editors could be tedious and not intuitive for designers. To ease this situation, PRADO has included in the releases an Adobe Dreamweaver extension that supports auto-completing PRADO tags (e.g. including control names, property names, event names, etc.) in Dreamweaver. + + + +

Creating Page Class

+ +

+We now create the page class Contact.php. The reason we need a page class is because we need to respond to the feedback that the user submits. + +

+Notice in the template we have the following line. The template essentially states that when a user clicks on the button, it should call the submitButtonClicked() method. Here OnClick is the name of the user click event, and the method must be defined in the page class. +

+ + + <com:TButton Text="Submit" OnClick="submitButtonClicked" /> + + +

+We thus write down the page class as follows: +

+ + +IsValid) // check if input validation is successful + { + // obtain the user name, email, feedback from the textboxes + $name = $this->Name->Text; + $email = $this->Email->Text; + $feedback = $this->Feedback->Text; + + // send an email to administrator with the above information + $this->mailFeedback($name, $email, $feedback); + } + } + + protected function mailFeedback($name, $email, $feedback) + { + // implementation of sending the feedback email + } +} +?> + + +

+The above code is largely self-explanatory. In fact, we just show the event-driven programming scheme. In the event handler submitButtonClicked(), we retrieve the user's input. For example, $this->Name->Text returns the Text property value of the Name control which is the textbox collecting user's name information. +

+ + +Page class name must be the same as the file name. This is also a requirement for writing any PRADO component class. + + + +

Testing

+ +

+Our newly created Contact can be tested via the URL http://hostname/blog/index.php?page=Contact. If we click on the submit button without entering any information, we will see error messages appearing next to the corresponding textboxes. If we enter all required information, the method mailFeedback() will be invoked. +

+ + + +

+A further enhancement to this page is to show some confirmation message on the page after the user submits feedback. And possibly, the browser may be redirected to another page if the submission is successful. We will leave these tasks to our readers. +

+ + +Each validator represents a validation rule. A single input control can be associated with one or multiple validators. Validators perform validation on both client side and server side. On the client side, namely the browser, validation is done using javascript; on the server side, validation is done using PHP code. Client-side validation can be turned off, while server-side validation cannot. This ensures user inputs are always checked by the specified validation rules. + + +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day1/Setup.page b/demos/blog-tutorial/protected/pages/Day1/Setup.page new file mode 100644 index 00000000..ee4744f5 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day1/Setup.page @@ -0,0 +1,161 @@ + + +

Initial Setup

+ +

+We start by setting up the directories and the files that are required by most PRADO applications. We use the PRADO command line tool to achieve this goal. +

+ +

+Assume blog is the name of the directory to hold the whole blog system, and the URL to access this folder is http://hostname/blog/ (replace hostname with the actual host name). +

+ +

+Under the blog directory, we run the PRADO command line tool with the following command (replace path/to with the actual path to the PRADO framework installation): +

+ +php path/to/prado-cli.php -c . + + +

+Running the above command creates the following directories and files: +

+ + + +

+We now have a skeleton PRADO application accessible via the URL http://hostname/blog/index.php which brings up a Web page showing "Welcome to PRADO". +

+ +

+It is beneficial to learn more details about the directories and files we just created. +

+ + +

Initial Files

+ +

The Entry Script

+ +

+Every PRADO application has an entry script, often named as index.php. In most cases, it is the only PHP script that is directly accessible by Web users. This reduces the risk of allowing Web users to execute unwanted scripts on the server. +

+ +

+The main purpose of the entry script is to initialize the PRADO application and have it handle user requests. The entry script usually contains the following PHP statements, +

+ + +run(); +?> + + + +The name of the entry script does not need to be index.php. It can be any name as long as the Web server can tell that the script is a PHP 5 script. For example, on some shared hosting environments, one may need to name the script as index.php5 so that it can be properly handled by the Web server. + + +

Application Configuration

+

+The optional XML file application.xml contains the application configuration. Its main purpose is to customize in a configurable fashion the application instance created in the entry script. For example, we may enable the logging feature for our blog system with the help of application configuration. +

+ +

+The file application.xml we have now is nearly empty. In fact, we may safely remove it because the application at the moment uses only default settings of PRADO. As we move forward, we will refer back constantly and show how to configure our application in application.xml. +

+ + +

Homepage

+ +

+The homepage (also called default page) Home.page is the only page created by the PRADO command line tool. It is the content in this file that shows up in the browser when visiting the URL http://hostname/blog/index.php. +

+ +

+Content in the file Home.page uses the PRADO template format, which is mostly like HTML enhanced with a few PRADO-specific tags. For example, in Home.page we see the following pure HTML content: +

+ + + + + Welcome to PRADO + + +

Welcome to PRADO!

+ + +
+ + +

Initial Directories

+ +

The protected Directory

+ +

+The protected directory, also known as the application base path, is the root directory holding pages, templates, configurations, data, etc. The name protected indicates this directory should be hidden from Web users, because files under this directory often contain sensitive data. +

+ +

+Different Web servers have different ways of "protecting" a directory. For Apache httpd server, the easiest way is to place under the directory a file named .htaccess with the content deny from all. +

+ + +

The protected/runtime and assets Directories

+ +

+The protected/runtime and assets directories are the two directories that must be set writable by the Web server process. The runtime directory stores sensitive data (e.g. parsed application configuration) generated when running a PRADO application, while the assets directory stores published resources (e.g. image files, javascript files). +

+ + +It is safe to remove files and directories under protected/runtime and assets. In fact, developers are recommended to do this cleanup work when they upgrade their PRADO installation. + + + +

The pages Directory

+ +

+The pages directory is the root page directory holding all pages in a PRADO application. It bears an analogy to the htdocs directory for the Apache httpd Web server. +

+ +

+We already see how to access the homepage. To access an arbitrary page located under pages, use the URL http://hostname/blog/index.php?page=path.to.PageName. According to this URL, PRADO will look for a page named PageName under the directory pages/path/to. The URL we used to access the homepage previously is equivalent to http://hostname/blog/index.php?page=Home. +

+ + +

Customization

+ +

+It is possible to customize the name and location of the files and directories described above. +

+ +

+For example, to improve security, one may want to move the whole protected directory to somewhere else that is not a Web folder. To do so, use the following PHP statement to create the application instance in the entry script: +

+ + +$application = new TApplication( 'path/to/protected' ); + + +

+To change the location of the root page directory and change the name of homepage, one can specify it in the application configuration application.xml as follows: +

+ + + + + + + +

+As you learn more about PRADO, you will see that PRADO is such a flexible framework that it allows you to customize nearly every aspect. We will describe more customization techniques as we continue with our tutorial. +

+ +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day1/ShareLayout.page b/demos/blog-tutorial/protected/pages/Day1/ShareLayout.page new file mode 100644 index 00000000..548cec1c --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day1/ShareLayout.page @@ -0,0 +1,178 @@ + + +

Sharing Common Layout

+ +

+In this section, we will use the master/content feature of PRADO to share common layout among pages. Common layout refers to the area that is the same or largely the same for a set of pages. For example, in our blog system, all pages will share the same header, footer and side-bar containing shortcut links. A straightforward implementation is to repeat the common layout in every page. However, this approach is prone to error and is hard to maintain. The master/content feature allows us to treat the common layout as a control which centralizes the logic and presentation of the common layout for every page. +

+ + +It is also possible to share common layout via template inclusion, which is like PHP file inclusion. The drawback of template inclusion is that it is not self-contained and does not carry a class to contain the logic for the common layout. + + + +

Creating Master Control

+ +

+We now create the master control MainLayout to represent the common layout shared by our blog pages. The MainLayout control is a template control extending from TTemplateControl. It requires a template file MainLayout.tpl and a class file MainLayout.php located under the same directory. To facilitate maintenance, we create a new directory protected/layouts to hold them. +

+ + + +

+For the moment, MainLayout only contains a simple header and a footer, as shown in the following. In future, we will add a side-bar to it. Readers are also encouraged to enhance the layout with other features. +

+ + + +<com:THead /> + +<com:TForm> + + + +
+<com:TContentPlaceHolder ID="Main" /> +
+ + + +</com:TForm> + + +
+ +

+The above shows the content in the template file MainLayout.tpl. Three new tags are used: +

+ + +

+The class file MainLayout.php is very simple: +

+ + + + + + +The file extension name for page templates is .page, while for non-page templates it is .tpl. This is to differentiate pages from other controls. They both use the same template syntax. For pages, their class files are optional (default to TPage), while for non-page controls, their class files are mandatory. Similar to Java, the name of a class file must be the same as the class name. Be careful about the case-sensitivity on Linux/Unix systems. + + + +

Using Master Control

+

+To use the newly created master control, we will modify Home.page and Contact.page. In particular, we need to remove the header and footer from them because the master control will be responsible for displaying them; and we need to tell the two pages that they should use MainLayout as their master. +

+ +

+The following shows the content in Contact.page after the change: +

+ + +<%@ MasterClass="Application.layouts.MainLayout" Title="My Blog - Contact" %> + +<com:TContent ID="Main"> + +

Contact

+

Please fill out the following form to let me know your feedback on my blog. Thanks!

+ +...textbox and validator for user's name... + +...textbox and validators for user's email... + +...textbox and validator for user's feedback content... + +<com:TButton Text="Submit" OnClick="submitButtonClicked" /> + +</com:TContent> +
+ +

+Content enclosed within the <com:TContent> tag will be inserted into the place that is reserved by <com:TContentPlaceHolder> in the master template. +

+ + +It is possible to have multiple TContentPlaceHolder's in a master template and multiple TContent's in a content template. They are matched to each other by their ID values. It is also possible to make a content template the master of another content template by placing a TContentPlaceHolder in the former. This is called nested master. + + +

+Besides <com:TContent>, we also see another new tag <%@ %> in the above, which is called template control tag. It contains name-value pairs which are used to initialize the corresponding properties for the template owner, namely, the Contact page. +

+ +

+By setting MasterClass property as Application.layouts.MainLayout, we instruct the Contact page to use MainLayout as its master. Here, we are using the namespace format to refer to the MainLayout class. +

+ + +Namespace format is widely used in PRADO programming. It is used together with path aliases. PRADO defines two path aliases: System refers to the framework directory of the PRADO installation, and Application refers to the protected directory. The namespace Application.layouts.MainLayout can thus be translated as protected/layouts/MainLayout which is exactly the file name (without the extension .php) for the MainLayout class. + + + +

Alternative Ways of Specifying Master

+ +

+There are several additional ways to specify the master class for a page. +

+ +

+We can specify master in code like the following to enable dynamic change of layout: +

+ + +MasterClass='Path.To.NewLayout'; + } + + // ... +} +?> + + +

+In the above, we specify MasterClass in the onPreInit() method which is inherited from TPage. The method is invoked by PRADO right after the page instance is created. We thus can dynamically determine the layout to use when the page is requested. For example, when the page is requested by a registered user we use layout A, and layout B is used if a guest user is requesting the page. +

+ +

+We can also specify master in application configuration or page configuration. The following shows the updated application configuration for our blog system: +

+ + + + + + + + + + + + + + +

+By doing so, we save the trouble of specifying master in every page template. If we decide to use a different master for the pages, we only need to change the application configuration. For this reason, in our blog system we will use this approach to specify master. +

+ + +There is an order determining which master is acutally applied when it is specified in multiple places. In particular, onPreInit() takes precedence over page template over application/page configuration. Therefore, if we specify MainLayout in the application/page configuration and we specify SpecialLayout in Contact.page, the effective master would be the latter. + + +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day1/directories.gif b/demos/blog-tutorial/protected/pages/Day1/directories.gif new file mode 100644 index 00000000..884e15bc Binary files /dev/null and b/demos/blog-tutorial/protected/pages/Day1/directories.gif differ diff --git a/demos/blog-tutorial/protected/pages/Day1/directories2.gif b/demos/blog-tutorial/protected/pages/Day1/directories2.gif new file mode 100644 index 00000000..edf264d0 Binary files /dev/null and b/demos/blog-tutorial/protected/pages/Day1/directories2.gif differ diff --git a/demos/blog-tutorial/protected/pages/Day1/directories3.gif b/demos/blog-tutorial/protected/pages/Day1/directories3.gif new file mode 100644 index 00000000..3451935f Binary files /dev/null and b/demos/blog-tutorial/protected/pages/Day1/directories3.gif differ diff --git a/demos/blog-tutorial/protected/pages/Day1/output.gif b/demos/blog-tutorial/protected/pages/Day1/output.gif new file mode 100644 index 00000000..f3ece514 Binary files /dev/null and b/demos/blog-tutorial/protected/pages/Day1/output.gif differ -- cgit v1.2.3