From 45b0fe42a979d444d547a5248eb2e9e915aaf16a Mon Sep 17 00:00:00 2001
From: wei <>
Date: Sun, 14 Jan 2007 02:10:24 +0000
Subject: Add "block-content" to allow user comments on block level elements in
quickstart docs.
---
.../pages/ActiveControls/ActiveButton.page | 30 +-
.../pages/ActiveControls/ActiveCheckBox.page | 6 +-
.../ActiveControls/ActiveCustomValidator.page | 6 +-
.../protected/pages/ActiveControls/Home.page | 30 +-
.../pages/ActiveControls/Introduction.page | 2 +-
.../protected/pages/Advanced/Assets.page | 26 +-
.../quickstart/protected/pages/Advanced/Auth.page | 38 +--
.../protected/pages/Advanced/Collections.page | 58 ++--
.../quickstart/protected/pages/Advanced/Error.page | 32 +-
.../quickstart/protected/pages/Advanced/I18N.page | 146 ++++-----
.../protected/pages/Advanced/Logging.page | 26 +-
.../protected/pages/Advanced/MasterContent.page | 22 +-
.../protected/pages/Advanced/Performance.page | 38 +--
.../pages/Advanced/Samples/I18N/Home.de.page | 2 +-
.../pages/Advanced/Samples/I18N/Home.es.page | 2 +-
.../pages/Advanced/Samples/I18N/Home.fr.page | 2 +-
.../pages/Advanced/Samples/I18N/Home.page | 2 +-
.../pages/Advanced/Samples/I18N/Home.pl.page | 2 +-
.../pages/Advanced/Samples/I18N/Home.zh.page | 2 +-
.../pages/Advanced/Samples/I18N/zh_TW/Home.page | 2 +-
.../protected/pages/Advanced/Scripts.page | 104 +++----
.../protected/pages/Advanced/Scripts1.page | 22 +-
.../protected/pages/Advanced/Scripts2.page | 80 ++---
.../protected/pages/Advanced/Scripts3.page | 12 +-
.../protected/pages/Advanced/Security.page | 38 +--
.../quickstart/protected/pages/Advanced/State.page | 26 +-
.../protected/pages/Advanced/Themes.page | 26 +-
.../protected/pages/Configurations/AppConfig.page | 14 +-
.../protected/pages/Configurations/Overview.page | 4 +-
.../protected/pages/Configurations/PageConfig.page | 12 +-
.../protected/pages/Configurations/Templates1.page | 44 +--
.../protected/pages/Configurations/Templates2.page | 46 +--
.../protected/pages/Configurations/Templates3.page | 50 +--
.../protected/pages/Configurations/UrlMapping.page | 36 +--
.../protected/pages/Controls/Button.page | 4 +-
.../protected/pages/Controls/CheckBox.page | 4 +-
.../protected/pages/Controls/ClientScript.page | 21 +-
.../protected/pages/Controls/ColorPicker.page | 2 +-
.../quickstart/protected/pages/Controls/Data.page | 2 +-
.../protected/pages/Controls/DataGrid.page | 68 ++--
.../protected/pages/Controls/DataList.page | 26 +-
.../protected/pages/Controls/DatePicker.page | 30 +-
.../protected/pages/Controls/Expression.page | 8 +-
.../protected/pages/Controls/FileUpload.page | 10 +-
.../quickstart/protected/pages/Controls/Head.page | 2 +-
.../protected/pages/Controls/HiddenField.page | 4 +-
.../protected/pages/Controls/HtmlArea.page | 10 +-
.../protected/pages/Controls/HyperLink.page | 2 +-
.../quickstart/protected/pages/Controls/Image.page | 2 +-
.../protected/pages/Controls/ImageButton.page | 2 +-
.../protected/pages/Controls/ImageMap.page | 8 +-
.../protected/pages/Controls/InlineFrame.page | 8 +-
.../protected/pages/Controls/JavascriptLogger.page | 12 +-
.../quickstart/protected/pages/Controls/Label.page | 2 +-
.../protected/pages/Controls/LinkButton.page | 2 +-
.../quickstart/protected/pages/Controls/List.page | 30 +-
.../protected/pages/Controls/Literal.page | 8 +-
.../protected/pages/Controls/MultiView.page | 14 +-
.../protected/pages/Controls/NewControl.page | 58 ++--
.../protected/pages/Controls/OutputCache.page | 20 +-
.../quickstart/protected/pages/Controls/Pager.page | 14 +-
.../quickstart/protected/pages/Controls/Panel.page | 2 +-
.../protected/pages/Controls/PlaceHolder.page | 2 +-
.../protected/pages/Controls/RadioButton.page | 2 +-
.../protected/pages/Controls/Repeater.page | 26 +-
.../protected/pages/Controls/SafeHtml.page | 6 +-
.../protected/pages/Controls/Standard.page | 2 +-
.../protected/pages/Controls/Statements.page | 12 +-
.../quickstart/protected/pages/Controls/Table.page | 2 +-
.../protected/pages/Controls/TextBox.page | 2 +-
.../protected/pages/Controls/TextHighlighter.page | 8 +-
.../protected/pages/Controls/Validation.page | 72 ++---
.../protected/pages/Controls/Wizard.page | 30 +-
.../protected/pages/Database/ActiveRecord.page | 139 ++++-----
demos/quickstart/protected/pages/Database/DAO.page | 70 ++---
.../protected/pages/Database/SqlMap.page | 84 ++---
.../protected/pages/Fundamentals/Applications.page | 20 +-
.../protected/pages/Fundamentals/Architecture.page | 4 +-
.../protected/pages/Fundamentals/Components.page | 52 ++--
.../protected/pages/Fundamentals/Controls.page | 22 +-
.../protected/pages/Fundamentals/Hangman.page | 7 +-
.../protected/pages/Fundamentals/Modules.page | 20 +-
.../protected/pages/Fundamentals/Pages.page | 8 +-
.../protected/pages/Fundamentals/Services.page | 16 +-
.../protected/pages/GettingStarted/AboutPrado.page | 32 +-
.../pages/GettingStarted/CommandLine.page | 26 +-
.../protected/pages/GettingStarted/HelloWorld.page | 41 +--
.../pages/GettingStarted/Installation.page | 17 +-
.../pages/GettingStarted/Introduction.page | 8 +-
.../protected/pages/GettingStarted/Upgrading.page | 31 +-
.../protected/pages/Services/SoapService.page | 76 +++--
.../protected/pages/Tutorial/AjaxChat.page | 264 ++++++++--------
.../pages/Tutorial/CurrencyConverter.page | 343 +++++++++++----------
93 files changed, 1430 insertions(+), 1377 deletions(-)
(limited to 'demos/quickstart/protected/pages')
diff --git a/demos/quickstart/protected/pages/ActiveControls/ActiveButton.page b/demos/quickstart/protected/pages/ActiveControls/ActiveButton.page
index adf50d22..c80c22dc 100644
--- a/demos/quickstart/protected/pages/ActiveControls/ActiveButton.page
+++ b/demos/quickstart/protected/pages/ActiveControls/ActiveButton.page
@@ -1,9 +1,9 @@
TActiveButton is the active control counter part to
+ TActiveButton is the active control counter part to
TButton.
When a TActiveButton is clicked, rather than a normal post back request a
callback request is initiated. The OnCallback event is raised
@@ -11,29 +11,29 @@ during a callback request and it is raise after
the OnClick event.
When the ActiveControl.EnableUpdate property is true,
+ When the ActiveControl.EnableUpdate property is true,
changing the Text property during a callback request will update
the button's caption on the client-side. Since the OnCallback event is raised only during a callback request,
+ Since the OnCallback event is raised only during a callback request,
the OnCallback event handler can be used to handle logic specifically
related to callback requests. The OnClick event handler is raised
when ever the button is clicked, even if javascript is disabled. The following example the use of both the OnClick and OnCallback
+ The following example the use of both the OnClick and OnCallback
events of an TActiveButton. The class diagram for TActiveButton is illustrated in the figure below.
+ The class diagram for TActiveButton is illustrated in the figure below.
Most active control that can perform callback request have a similar structure.
TActiveButton is an extension of TButton
+ TActiveButton is an extension of TButton
and implements two additional interfaces ICallbackEventHandler and
IActiveControl. The TActiveButton contains an instance of
TBaseActiveCallbackControl
@@ -41,24 +41,24 @@ available through the ActiveControl property of TActiveButton.
The following example set the callback parameter of the TActiveButton when
a callback request is dispatched.
In the OnCallback event handler method, the CallbackParameter
+ In the OnCallback event handler method, the CallbackParameter
is available in the $param object. With in the ActiveControl property is an instance of
+ With in the ActiveControl property is an instance of
TCallbackClientSide available
as a property ClientSide of TActiveButton.
The ClientSide property contains sub-properties, such as RequestTimeOut,
@@ -68,7 +68,7 @@ The following example demonstrates the toggling of a "loading" indicator
when the client-side is making a callback request.
The example loads the "effects" javascript library using the
+ The example loads the "effects" javascript library using the
TClientScript component.
The ClientSide.OnLoading property value contains
javascript statement that uses the "effects" library to show the "Loading..."
diff --git a/demos/quickstart/protected/pages/ActiveControls/ActiveCheckBox.page b/demos/quickstart/protected/pages/ActiveControls/ActiveCheckBox.page
index d66c48f5..5b34492a 100644
--- a/demos/quickstart/protected/pages/ActiveControls/ActiveCheckBox.page
+++ b/demos/quickstart/protected/pages/ActiveControls/ActiveCheckBox.page
@@ -1,9 +1,9 @@
+
TActiveCheckBox is the active control counter part to
TCheckbox. The AutoPostBack
property of TActiveCheckBox is set to true by default.
@@ -11,7 +11,7 @@
OnCallback event is raise after the OnCheckedChanged event.
+
The Text and Checked properties of TActiveCheckBox
can be changed during a callback request. The TextAlign property
of TActiveCheckBox can not be changed during
diff --git a/demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page b/demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page
index f97ea40d..d723cbac 100644
--- a/demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page
+++ b/demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page
@@ -1,15 +1,15 @@
Performs custom validation using only server-side OnServerValidate
+ Performs custom validation using only server-side OnServerValidate
validation event. The client-side uses callbacks to raise
onServerValidate event. The ClientValidationFunction property
is disabled and will throw an exception if trying to set this property.
Beware that the onServerValidate may be
+ Beware that the onServerValidate may be
raised when the control to validate on the client side
changes value, that is, the server validation may be called many times.
diff --git a/demos/quickstart/protected/pages/ActiveControls/Home.page b/demos/quickstart/protected/pages/ActiveControls/Home.page
index 5b8c40a2..289c7c1c 100644
--- a/demos/quickstart/protected/pages/ActiveControls/Home.page
+++ b/demos/quickstart/protected/pages/ActiveControls/Home.page
@@ -1,7 +1,7 @@
See the Introduction
+ See the Introduction
for a quick overview of the concept behind active controls (AJAX enabled controls).
Most active controls have a property of
ActiveControl and
@@ -13,14 +13,14 @@ during a callback request. Active controls is reliant on a collection
of javascript classes.
For a quick demo of active controls, try the
+ For a quick demo of active controls, try the
TActiveButton control. See also the later part of the Current Converter tutorial for a more indepth example.
* the tutorial for this control is not completed yet. * the tutorial for this control is not completed yet. The following table shows the Active Controls that can trigger a
callback event and whether the control will raise a PostBack event
if Javascript was disabled on the client's browser. The following classes provide the basic infrastructure classes required to
+ The following classes provide the basic infrastructure classes required to
realize the active controls.
+
Assets are resource files (such as images, sounds, videos, CSS stylesheets, javascripts, etc.) that belong to specific component classes. Assets are meant to be provided to Web users. For better reusability and easier deployment of the corresponding component classes, assets should reside together with the component class files . For example, a toggle button may use two images, stored in file down.gif and up.gif, to show different toggle states. If we require the image files be stored under images directory under the Web server document root, it would be inconvenient for the users of the toggle button component, because each time they develop or deploy a new application, they would have to manually copy the image files to that specific directory. To eliminate this requirement, a directory relative to the component class file should be used for storing the image files. A common strategy is to use the directory containing the component class file to store the asset files.
+
Because directories containing component class files are normally inaccessible by Web users, PRADO implements an asset publishing scheme to make available the assets to Web users. An asset, after being published, will have a URL by which Web users can retrieve the asset file.
+
PRADO provides several methods for publishing assets or directories containing assets:
+
BE AWARE: Be very careful with assets publishing, because it gives Web users access to files that were previously inaccessible to them. Make sure that you do not publish files that do not want Web users to see.
+
Asset publishing is managed by the System.Web.TAssetManager module. By default, all published asset files are stored under the [AppEntryPath]/assets directory, where AppEntryPath refers to the directory containing the application entry script. Make sure the assets directory is writable by the Web server process. You may change this directory to another by configuring the BasePath and BaseUrl properties of the TAssetManager module in application configuration,
+
PRADO uses caching techniques to ensure the efficiency of asset publishing. Publishing an asset essentially requires file copy operation, which is expensive. To save unnecessary file copy operations, System.Web.TAssetManager only publishes an asset when it has a newer file modification time than the published file. When an application runs under the Performance mode, such timestamp checking is also omitted.
+
ADVISORY: Do not overuse asset publishing. The asset concept is mainly used to help better reuse and redistribute component classes. Normally, you should not use asset publishing for resources that are not bound to any component in an application. For example, you should not use asset publishing for images that are mainly used as design elements (e.g. logos, background images, etc.) Let Web server to directly serve these images will help improve the performance of your application.
+
We now use the toggle button example to explain the usage of assets. The control uses two image files up.gif and down.gif, which are stored under the directory containing the control class file. When the button is in Up state, we would like to show the up.gif image. This can be done as follows,
+
In the above, the call $this->getAsset('up.gif') will publish the up.gif image file and return a URL for the published image file. The URL is then rendered as the src attribute of the HTML image tag.
+
To redistribute ToggleButton, simply pack together the class file and the image files. Users of ToggleButton merely need to unpack the file, and they can use it right away, without worrying about where to copy the image files to.
+
Authentication is a process of verifying whether someone is who he claims he is. It usually involves a username and a password, but may include any other methods of demonstrating identity, such as a smart card, fingerprints, etc.
+
Authorization is finding out if the person, once identified, is permitted to manipulate specific resources. This is usually determined by finding out if that person is of a particular role that has access to the resources.
+
PRADO provides an extensible authentication/authorization framework. As described in application lifecycles, TApplication reserves several lifecycles for modules responsible for authentication and authorization. PRADO provides the TAuthManager module for such purposes. Developers can plug in their own auth modules easily. TAuthManager is designed to be used together with TUserManager module, which implements a read-only user database.
+
When a page request occurs, TAuthManager will try to restore user information from session. If no user information is found, the user is considered as an anonymous or guest user. To facilitate user identity verification, TAuthManager provides two commonly used methods: login() and logout(). A user is logged in (verified) if his username and password entries match a record in the user database managed by TUserManager. A user is logged out if his user information is cleared from session and he needs to re-login if he makes new page requests.
+
During Authorization application lifecycle, which occurs after Authentication lifecycle, TAuthManager will verify if the current user has access to the requested page according to a set of authorization rules. The authorization is role-based, i.e., a user has access to a page if 1) the page explicitly states that the user has access; 2) or the user is of a particular role that has access to the page. If the user does not have access to the page, TAuthManager will redirect user browser to the login page which is specified by LoginPage property.
+
To enable PRADO auth framework, add the TAuthManager module and TUserManager module to application configuration,
+
In the above, the UserManager property of TAuthManager is set to the users module which is TUserManager. Developers may replace it with a different user management module that is derived from TUserManager.
+
Authorization rules for pages are specified in page configurations as follows,
+
An authorization rule can be either an allow rule or a deny rule. Each rule consists of four optional properties:
+
When a page request is being processed, a list of authorization rules may be available. However, only the first effective rule matching the current user will render the authorization result.
+
In the above example, anonymous users will be denied from posting to PageID1 and PageID2, while User1 and User2 and all users of role Role1 can access the two pages (in both get and post methods).
+
As aforementioned, TUserManager implements a read-only user database. The user information are specified in either application configuration or an external XML file.
+
We have seen in the above example that two users are specified in the application configuration. Complete syntax of specifying the user and role information is as follows,
+
where the roles attribute in user element is optional. User roles can be specified in either the user element or in a separate role element.
+
Collection is a basic data structure in programming. In traditional PHP programming, array is used widely to represent collection data structure. A PHP array is a mix of cardinal-indexed array and hash table.
+
To enable object-oriented manipulation of collections, PRADO provides a set of powerful collection classes. Among them, the TList and TMap are the most fundamental and usually serve as the base classes for other collection classes. Since many PRADO components have properties that are of collection type, it is very important for developers to master the usage of PRADO collection classes.
+
A TList object represents a cardinal-indexed array, i.e., an array (object) with the index 0, 1, 2, ...
+
TList may be used like a PHP array. For example,
+
To obtain the number of items in the list, use the Count property. Note, do not use count($list), as it always returns 1.
+
In addition, TList implements a few commonly used convenient methods for manipulating the data in a list. These include
+
As aforementioned, many PRADO component properties are based on TList or TList-derived collection classes. These properties all share the above usages.
+
For example, TControl (the base class for all PRADO controls) has a property called Controls which represents the collection of child controls. The type of Controls is TControlCollection which extends TList. Therefore, to append a new child control, we can use the following,
+
To traverse through the child controls, we can use,
+
Another example is the Items property, available in list controls, TRepeater, TDataList and TDataGrid. In these controls, the ancestor class of Items is TList.
+
Often, we want to extend TList to perform additional operations for each addition or removal of an item. The only methods that the child class needs to override are insertAt() and removeAt(). For example, to ensure the list only contains items that are of TControl type, we can override insertAt() as follows,
+
A TMap object represents a hash table (or we say string-indexed array).
+
Similar to TList, TMap may be used like an array,
+
The Count property gives the number of items in the map while the Keys property returns a list of keys used in the map.
+
The following methods are provided by TMap for convenience,
+
TAttributeCollection is a special class extending from TMap. It is mainly used by the Attributes property of TControl.
+
Note, in the above $collection does NOT have a Label property.
+
Unlike TMap, keys in TAttributeCollection are case-insensitive. Therefore, $collection->Label is equivalent to $collection->LABEL.
+
Because of the above new features, when dealing with the Attributes property of controls, we may take advantage of the subproperty concept and configure control attribute values in a template as follows,
+
which adds an attribute named onclick to the TButton control.
+
PRADO provides a complete error handling and reporting framework based on the PHP 5 exception mechanism.
+
Errors occur in a PRADO application may be classified into three categories: those caused by PHP script parsing, those caused by wrong code (such as calling an undefined function, setting an unknown property), and those caused by improper use of the Web application by client users (such as attempting to access restricted pages). PRADO is unable to deal with the first category of errors because they cannot be caught in PHP code. PRADO provides an exception hierarchy to deal with the second and third categories.
+
All errors in PRADO applications are represented as exceptions. The base class for all PRADO exceptions is TException. It provides the message internationalization functionality to all system exceptions. An error message may be translated into different languages according to the user browser's language preference.
+
Exceptions raised due to improper usage of the PRADO framework inherit from TSystemException, which can be one of the following exception classes:
+
Errors due to improper usage of the Web application by client users inherit from TApplicationException.
+
Raising exceptions in PRADO has no difference than raising a normal PHP exception. The only thing matters is to raise the right exception. In general, exceptions meant to be shown to application users should use THttpException, while exceptions shown to developers should use other exception classes.
+
Exceptions raised during the runtime of PRADO applications are captured by System.Exceptions.TErrorHandler module. Different output templates are used to display the captured exceptions. THttpException is assumed to contain error messages that are meant for application end users and thus uses a specific group of templates. For all other exceptions, a common template shown as follows is used for presenting the exceptions.
+
Developers can customize the presentation of exception messages. By default, all error output templates are stored under framework/Exceptions/templates. The location can be changed by configuring TErrorHandler in application configuration,
+
THttpException uses a set of templates that are differentiated according to different StatusCode property value of THttpException. StatusCode has the same meaning as the status code in HTTP protocol. For example, a status code equal to 404 means the requested URL is not found on the server. The StatusCode value is used to select which output template to use. The output template files use the following naming convention:
+
where status code refers to the StatusCode property value of THttpException, and language code must be a valid language such as en, zh, fr, etc. When a THttpException is raised, PRADO will select an appropriate template for displaying the exception message. PRADO will first locate a template file whose name contains the status code and whose language is preferred by the client browser window. If such a template is not present, it will look for a template that has the same status code but without language code.
+
The naming convention for the template files used for all other exceptions is as follows,
+
Again, if the preferred language is not found, PRADO will try to use exception.html, instead.
Many web application built with PHP will not have internationalization in mind when it was first written. It may be that it was not intended for use in languages and cultures. Internationalization is an important aspect due to the increase adoption of the Internet in many non-English speaking countries. The process of internationalization and localization will contain difficulties. Below are some general guidelines to internationalize an existing application. Many web application built with PHP will not have internationalization in mind when it was first written. It may be that it was not intended for use in languages and cultures. Internationalization is an important aspect due to the increase adoption of the Internet in many non-English speaking countries. The process of internationalization and localization will contain difficulties. Below are some general guidelines to internationalize an existing application. Identify and separate data that varies with culture. The most obvious are text/string/message. Other type of data should also be considered. The following list categorize some examples of culture sensitive data
+ Identify and separate data that varies with culture. The most obvious are text/string/message. Other type of data should also be considered. The following list categorize some examples of culture sensitive data
If possible all manner of text should be isolated and store in a persistence format. These text include, application error messages, hard coded strings in PHP files, emails, static HTML text, and text on form elements (e.g. buttons). If possible all manner of text should be isolated and store in a persistence format. These text include, application error messages, hard coded strings in PHP files, emails, static HTML text, and text on form elements (e.g. buttons). To enable the localization features in PRADO, you need to add a few configuration options in your application configuration.
+ To enable the localization features in PRADO, you need to add a few configuration options in your application configuration.
First you need to include the System.I18N.* namespace to your paths.
Then, if you wish to translate some text in your application, you need to add one translation message data source. Then, if you wish to translate some text in your application, you need to add one translation message data source. Where source in translation is the dot path to a directory
+ Where source in translation is the dot path to a directory
where you are going to store your translate message catalogue. The autosave
attribute if enabled, saves untranslated messages back into the message catalogue.
With cache enabled, translated messages are saved in the application runtime/i18n directory.
The marker value is used to surround any untranslated text.
With the configuration complete, we can now start to localize your application. If you have autosave enabled, after running your application with some localization activity (i.e. translating some text), you will see a directory and a messages.xml created within your source directory. With the configuration complete, we can now start to localize your application. If you have autosave enabled, after running your application with some localization activity (i.e. translating some text), you will see a directory and a messages.xml created within your source directory. The translation message catalogue file, if using type="XLIFF", is a standardized translation message interchange XML format. You can edit the XML file using any UTF-8 aware editor. The format of the XML is something like the following. The translation message catalogue file, if using type="XLIFF", is a standardized translation message interchange XML format. You can edit the XML file using any UTF-8 aware editor. The format of the XML is something like the following. Once globalization is enabled, you can access the globalization settings, such as, Culture, Charset, etc, using Once globalization is enabled, you can access the globalization settings, such as, Culture, Charset, etc, using You also change the way the culture is determined by changing the class attribute in the module configuration. For example, to set the culture that depends on the browser settings, you can use the TGlobalizationAutoDetect class.
- You also change the way the culture is determined by changing the class attribute in the module configuration. For example, to set the culture that depends on the browser settings, you can use the TGlobalizationAutoDetect class.
+ You may also provide your own globalization class to change how the application culture is set.
+ You may also provide your own globalization class to change how the application culture is set.
Lastly, you can change the globalization settings on page by page basis using template control tags. For example, changing the Culture to "zh". The localize function searches for a translated string that matches original from your translation source. First, you need to locate all the hard coded text in PHP that are displayed or sent to the end user. The following example localizes the text of the $sender (assuming, say, the sender is a button). The original code before localization is as follows.
- The localize function searches for a translated string that matches original from your translation source. First, you need to locate all the hard coded text in PHP that are displayed or sent to the end user. The following example localizes the text of the $sender (assuming, say, the sender is a button). The original code before localization is as follows.
+ The hard coded message "Hello, world!" is to be localized using the localize function. The hard coded message "Hello, world!" is to be localized using the localize function. Compound messages can contain variable data. For example, in the message "There are 12 users online.", the integer 12 may change depending on some data in your application. This is difficult to translate because the position of the variable data may be difference for different languages. In addition, different languages have their own rules for plurals (if any) and/or quantifiers. The following example can not be easily translated, because the sentence structure is fixed by hard coding the variable data within message. Compound messages can contain variable data. For example, in the message "There are 12 users online.", the integer 12 may change depending on some data in your application. This is difficult to translate because the position of the variable data may be difference for different languages. In addition, different languages have their own rules for plurals (if any) and/or quantifiers. The following example can not be easily translated, because the sentence structure is fixed by hard coding the variable data within message. Where the second parameter in localize takes an associative array with the key as the substitution to find in the text and replaced it with the associated value.
+ Where the second parameter in localize takes an associative array with the key as the substitution to find in the text and replaced it with the associated value.
The localize function does not solve the problem of localizing languages that have plural forms, the solution is to use TChoiceFormat. The following sample demonstrates the basics of localization in PRADO. The following sample demonstrates the basics of localization in PRADO. Messages and strings can be localized in PHP or in templates.
+ Messages and strings can be localized in PHP or in templates.
To translate a message or string in the template, use TTranslate. TTranslate can also perform string substitution.
+ TTranslate can also perform string substitution.
The Parameters property can be use to add name values pairs for substitution. Substrings in the translation enclosed with "{" and "}" are consider as the
parameter names during substitution lookup. The following example will substitute the substring "{time}" with the value of the parameter attribute "Parameters.time=<%= time() %>".
- A short for TTranslate is also provided using the following syntax. A short for TTranslate is also provided using the following syntax. where string will be translated to different languages according to the end-user's language preference. This syntax can be used with attribute values as well. where string will be translated to different languages according to the end-user's language preference. This syntax can be used with attribute values as well. Formatting localized date and time is straight forward. Formatting localized date and time is straight forward. The Pattern property accepts 4 predefined localized date patterns and 4 predefined localized time patterns.
- The Pattern property accepts 4 predefined localized date patterns and 4 predefined localized time patterns.
The predefined can be used in any combination. If using a combined predefined pattern,
the first pattern must be the date, followed by a space, and lastly the time pattern.
For example, full date pattern with short time pattern. The actual ordering of the
date-time and the actual pattern will be determine automatically from locale data specified
by the Culture property. You can also specify a custom pattern using the following sub-patterns.
+ You can also specify a custom pattern using the following sub-patterns.
The date/time format is specified by means of a string time pattern. In this pattern, all ASCII letters are reserved as pattern letters, which are defined as the following:
- The count of pattern letters determine the format. The count of pattern letters determine the format. (Text): 4 letters uses full form, less than 4, use short or abbreviated form
+ (Text): 4 letters uses full form, less than 4, use short or abbreviated form
if it exists. (e.g., "EEEE" produces "Monday", "EEE" produces "Mon") (Number): the minimum number of digits. Shorter numbers are zero-padded
+ (Number): the minimum number of digits. Shorter numbers are zero-padded
to this amount (e.g. if "m" produces "6", "mm" produces "06"). Year is
handled specially; that is, if the count of 'y' is 2, the Year will be
truncated to 2 digits. (e.g., if "yyyy" produces "1997", "yy" produces "97".)
Unlike other fields, fractional seconds are padded on the right with zero. (Text and Number): 3 or over, use text, otherwise use number. (e.g.,
+ (Text and Number): 3 or over, use text, otherwise use number. (e.g.,
"M" produces "1", "MM" produces "01", "MMM" produces "Jan", and "MMMM"
produces "January".) Any characters in the pattern that are not in the ranges of ['a'..'z']
+ Any characters in the pattern that are not in the ranges of ['a'..'z']
and ['A'..'Z'] will be treated as quoted text. For instance, characters
like ':', '.', ' ', and '@' will appear in the resulting time text
even they are not embraced within single quotes. Examples using the US locale:
+ Examples using the US locale:
- If the Value property is not specified, the current date and time is used. If the Value property is not specified, the current date and time is used. PRADO's Internationalization framework provide localized currency formatting and number formatting. Please note that the TNumberFormat component provides formatting only, it does not perform current conversion or exchange. PRADO's Internationalization framework provide localized currency formatting and number formatting. Please note that the TNumberFormat component provides formatting only, it does not perform current conversion or exchange. Numbers can be formatted as currency, percentage, decimal or scientific
-numbers by specifying the Type attribute. The valid types are:
- Numbers can be formatted as currency, percentage, decimal or scientific
+numbers by specifying the Type attribute. The valid types are: Culture and Currency properties may be specified to format locale specific numbers. Culture and Currency properties may be specified to format locale specific numbers. If someone from US want to see sales figures from a store in
+ If someone from US want to see sales figures from a store in
Germany (say using the EURO currency), formatted using the german
currency, you would need to use the attribute Culture="de_DE" to get
the currency right, e.g. 100,00$. The decimal and grouping separator is
then also from the de_DE locale. This may lead to some confusion because
people from US uses the "," (comma) as thousand separator. Therefore a Currency
attribute is available, so that the output from the following example results in $100.00
- The Pattern property determines the number of digits, thousand grouping
+ The Pattern property determines the number of digits, thousand grouping
positions, the number of decimal points and the decimal position. The actual characters that
are used to represent the decimal points and thousand points are culture specific
and will change automatically according to the Culture property. The valid
-Pattern characters are:
-
For example, consider the Value="1234567.12345" and
with Culture="en_US" (which uses "," for thousand point separator and "." for decimal separators).
- Compound messages, i.e., string substitution, can be accomplished with TTranslateParameter.
+ Compound messages, i.e., string substitution, can be accomplished with TTranslateParameter.
In the following example, the strings "{greeting}" and "{name}" will be replace
with the values of "Hello" and "World", respectively.The substitution string must be enclose with "{" and "}". The parameters can be further translated by using TTranslate.
- Using the localize function or TTranslate component to translate messages does not inform the translator the cardinality of the data required to determine the correct plural structure to use. It only informs them that there is a variable data, the data could be anything. Thus, the translator will be unable to determine with respect to the substitution data the correct plural, language structure or phrase to use . E.g. in English, to translate the sentence, "There are {number} of apples.", the resulting translation should be different depending on the number of apples. Using the localize function or TTranslate component to translate messages does not inform the translator the cardinality of the data required to determine the correct plural structure to use. It only informs them that there is a variable data, the data could be anything. Thus, the translator will be unable to determine with respect to the substitution data the correct plural, language structure or phrase to use . E.g. in English, to translate the sentence, "There are {number} of apples.", the resulting translation should be different depending on the number of apples. The TChoiceFormat component performs message/string choice translation. The following example demonstrated a simple 2 choice message translation. The TChoiceFormat component performs message/string choice translation. The following example demonstrated a simple 2 choice message translation. In the above example, the Value "1" (one), thus the translated string
+ In the above example, the Value "1" (one), thus the translated string
is "One Apple". If the Value was "2", then it will show "Two Apples". The message/string choices are separated by the pipe "|" followed by a set notation of the form. The message/string choices are separated by the pipe "|" followed by a set notation of the form. Any non-empty combinations of the delimiters of square and round brackets are acceptable.
+ Any non-empty combinations of the delimiters of square and round brackets are acceptable.
The string chosen for display depends on the Value property. The Value is evaluated for each set until the Value is found to belong to a particular set.
+
PRADO provides a highly flexible and extensible logging functionality. Messages logged can be classified according to log levels and message categories. Using level and category filters, the messages can be further routed to different destinations, such as files, emails, browser windows, etc. The following diagram shows the basic architecture of PRADO logging mechanism,
+
The following two methods are provided for logging messages in PRADO,
+
The difference between Prado::log() and Prado::trace() is that the latter automatically selects the log level according to the application mode. If the application is in Debug mode, stack trace information is appended to the messages. Prado::trace() is widely used in the core code of the PRADO framework.
+
Messages logged using the above two functions are kept in memory. To make use of the messages, developers need to route them to specific destinations, such as files, emails, or browser windows. The message routing is managed by System.Util.TLogRouter module. When plugged into an application, it can route the messages to different destination in parallel. Currently, PRADO provides three types of routes:
+
To enable message routing, plug in and configure the TLogRouter module in application configuration,
+
In the above, the Levels and Categories specify the log and category filters to selectively retrieve the messages to the corresponding destinations.
+
Messages can be filtered according to their log levels and categories. Each log message is associated with a log level and a category. With levels and categories, developers can selectively retrieve messages that they are interested on.
+
Log levels defined in System.Util.TLogger include : DEBUG, INFO, NOTICE, WARNING, ERROR, ALERT, FATAL. Messages can be filtered according log level criteria. For example, if a filter specifies WARNING and ERROR levels, then only those messages that are of WARNING and ERROR will be returned.
+
Message categories are hierarchical. A category whose name is the prefix of another is said to be the ancestor category of the other category. For example, System.Web category is the ancestor of System.Web.UI and System.Web.UI.WebControls categories. Messages can be selectively retrieved using such hierarchical category filters. For example, if the category filter is System.Web, then all messages in the System.Web are returned. In addition, messages in the child categories, such as System.Web.UI.WebControls, are also returned.
+
By convention, the messages logged in the core code of PRADO are categorized according to the namespace of the corresponding classes. For example, messages logged in TPage will be of category System.Web.UI.TPage.
+
Pages in a Web application often share common portions. For example, all pages of this tutorial application share the same header and footer portions. If we repeatedly put header and footer in every page source file, it will be a maintenance headache if in future we want to something in the header or footer. To solve this problem, PRADO introduces the concept of master and content. It is essentially a decorator pattern, with content being decorated by master.
+
Master and content only apply to template controls (controls extending TTemplateControl or its child classes). A template control can have at most one master control and one or several contents (each represented by a TContent control). Contents will be inserted into the master control at places reserved by TContentPlaceHolder controls. And the presentation of the template control is that of the master control with TContentPlaceHolder replaced by TContent.
+
For example, assume a template control has the following template:
+
which uses MasterControl as its master control. The master control has the following template,
+
Then, the contents are inserted into the master control according to the following diagram, while the resulting parent-child relationship can be shown in the next diagram. Note, the template control discards everything in the template other than the contents, while the master control keeps everything and replaces the content placeholders with the contents according to ID matching.
+
Master is very similar to external templates which are introduced since version 3.0.5. A special include tag is used to include an external template file into a base template.
+
Both master and external template can be used to share common contents among pages. A master is a template control whose template contains the common content and whose class file contains the logic associated with the master. An external template, on the other hand, is a pure template file without any class files.
+
Therefore, use master control if the common content has to be associated with some logic, such as a page header with search box or login box. A master control allows you to specify how the common content should interact with end users. If you use external templates, you will have to put the needed logic in the page or control class who owns the base template.
+
Performancewise, external template is lighter than master as the latter is a self-contained control participating the page lifecycles, while the former is used only when the template is being parsed.
+
Performance of Web applications is affected by many factors. Database access, file system operations, network bandwidth are all potential affecting factors. PRADO tries in every effort to reduce the performance impact caused by the framework.
+
PRADO provides a generic caching technique used by in several core parts of the framework. For example, when caching is enabled, TTemplateManager will save parsed templates in cache and reuse them in the following requests, which saves time for parsing templates. The TThemeManager adopts the similar strategy to deal with theme parsing.
+
Enabling caching is very easy. Simply add the cache module in the application configuration, and PRADO takes care of the rest.
+
Developers can also take advantage of the caching technique in their applications. The Cache property of TApplication returns the plugged-in cache module when it is available. To save and retrieve a data item in cache, use the following commands,
+
where $keyName should be a string that uniquely identifies the data item stored in cache.
+
Including many PHP script files may impact application performance significantly. PRADO classes are stored in different files and when processing a page request, it may require including tens of class files.To alleviate this problem, in each PRADO release, a file named pradolite.php is also included. The file is a merge of all core PRADO class files with comments being stripped off and message logging removed.
+
To use pradolite.php, in your application entry script, replace the inclusion of prado.php with pradolite.php.
+
Application mode also affects application performance. A PRADO application can be in one of the following modes: Off, Debug, Normal and Performance. The Debug mode should mainly be used during application development, while Normal mode is usually used in early stage after an application is deployed to ensure everything works correctly. After the application is proved to work stably for some period, the mode can be switched to Performance to further improve the performance.
+
The difference between Debug, Normal and Performance modes is that under Debug mode, application logs will contain debug information, and under Performance mode, timestamp checking is not performed for cached templates and published assets. Therefore, under Performance mode, application may not run properly if templates or assets are modified. Since Performance mode is mainly used when an application is stable, change of templates or assets are not likely.
+
To switch application mode, configure it in application configuration:
+
By default, PRADO stores page state in hidden fields of the HTML output. The page state could be very large in size if complex controls, such as TDataGrid, is used. To reduce the size of the network transmitted page size, two strategies can be used.
+
First, you may disable viewstate by setting EnableViewState to false for the page or some controls on the page if they do not need user interactions. Viewstate is mainly used to keep track of page state when a user interacts with that page/control.
+
Second, you may use a different page state storage. For example, page state may be stored in session, which essentially stores page state on the server side and thus saves the network transmission time. The StatePersisterClass property of the page determines which state persistence class to use. By default, it uses System.Web.UI.TPageStatePersister to store persistent state in hidden fields. You may modify this property to a persister class of your own, as long as the new persister class implements the IPageStatePersister interface. You may configure this property in several places, such as application configuration or page configuration using <pages> or <page> tags,
+
Note, in the above the SpecialPage will use MyPersister2 as its persister class, while the rest pages will use MyPersister1. Therefore, you can have different state persister strategies for different pages.
+
Server caching techniques are proven to be very effective in improving the performance of PRADO applications. For example, we have observed that by using Zend Optimizer, the RPS (request per second) of a PRADO application can be increased by more than ten times. Of course, this is at the cost of stale output, while PRADO's caching techniques always ensure the correctness of the output.
Die folgenden Merkmale werden von PRADO unterstützt: Las características siguientes son utilizadas por PRADO:
PRADO offrent les fonctionnalités suivantes :
The following features are supported by PRADO: PRADO obsługuje następujące mechanizmy: PRADO支持以下功能: PRADO支持以下功能:
+
If you are a web developer and come from the same place I do, you have probably
used quite a bit of Javascript in your web pages, mostly as UI glue.
+
Until recently, I knew that Javascript had more OO capabilities than I was employing,
but I did not feel like I needed to use it. As the browsers started to support a more
@@ -16,7 +16,7 @@ Quick guide to somewhat advanced JavaScript tour of some OO features
+
As we all start to learn what it takes to write our cool, AJAX applications, we begin
to notice that the Javascript we used to know was really just the tip of the iceberg.
We now see Javascript being used beyond simple UI chores like input validation and frivolous
@@ -25,7 +25,7 @@ Quick guide to somewhat advanced JavaScript tour of some OO features by Serg
hierarchies, patterns, and many other things we got used to seeing only in our server
side code.
+
In many ways we can say that suddenly the bar was put much higher than before. It takes
a heck lot more proficiency to write applications for the new Web and we need to improve
our Javascript skills to get there.
@@ -43,28 +43,28 @@ Quick guide to somewhat advanced JavaScript tour of some OO features by Serg
that before.
+
The purpose of this article is precisely explaining the types of constructs that
many of us are not familiar with yet.
+
JavaScript Object Notation (JSON,) is one of the new
buzzwords popping up around the AJAX theme. JSON, simply put, is a way of
declaring an object in Javascript. Let's see an example right away and note
how simple it is.
+
Let's just add little bit of formatting so it looks more like how we usually find out there:
+
Here we created a reference to an object with two properties (color
and legCount) and a method (communicate.)
It's not hard to figure out that the object's properties and methods
@@ -88,28 +88,28 @@ var myPet =
we can use it like this:
+
You'll see JSON used pretty much everywhere in JS these days, as arguments to functions,
as return values, as server responses (in strings,) etc.
+
This might be unusual to developers that never thought about that, but in JS a function is
also an object. You can pass a function around as an argument to another function just like
you can pass a string, for example. This is extensively used and very handy.
+
Take a look at this example. We will pass functions to another function that will use them.
+
Note that we pass myDog.bark and myCat.meow without appending parenthesis
"()" to them. If we did that we would not be passing
the function, rather we would be calling the method and passing the return value,
undefined in both cases here.
+
If you want to make my lazy cat start barking, you can easily do this:
+
The following two lines in JS do the same thing.
+
As I'm sure you already know, you can access individual items in an array
by using the square brackets:
+
But you are not limited to numeric indices. You can access any member of a JS
object by using its name, in a string. The following example creates an empty
object, and adds some members by name.
+
The above code has identical effect as the following:
+
In many ways, the idea of objects and associative arrays (hashes) in JS are not
distiguishable. The following two lines do the same thing too.
+
The great power of object oriented programming languages derive from the use
of classes. I don't think I would have guessed how classes are defined in JS
using only my previous experience with other languages. Judge for yourself.
+
Let's see how we add a method to our Pet class. We will be using the
prototype property that all classes have. The prototype
property is an object that contains all the members that any object of the class will have.
@@ -233,17 +233,17 @@ alert('This pet is called ' + famousDog.name);
can add methods and properties to and make any object of that class automatically gain this new member.
+
That's when a library like prototype.js comes in
handy. If we are using prototype.js, we can make our code look cleaner (at least in my opinion.)
+
If you have never worked with languages that support closures
you may find the following idiom too funky.
+
Whoa! Let's explain what is going on here before you decide I've gone too
far and navigate to a better article than this one.
+
First of all, in the above example we are using the prototype.js library, which
adds the each function to the Array class. The each function accepts one
argument that is a function object. This function, in turn, will be called once
@@ -286,7 +286,7 @@ myArray.each( function(item, index)
for the current item. Let's call this function our iterator function.
We could have also written the code like this.
+
But then we would not be doing like all the cool kids in school, right?
More seriously, though, this last format is simpler to understand but causes
us to jump around in the code looking for the myIterator function. It's nice
@@ -305,20 +305,20 @@ myArray.each( myIterator );
+
One of the most common troubles we have with JS when we start writing our code
it the use of the this keyword. It could be a real
tripwire.
+
As we mentioned before, a function is also an object in JS, and sometimes we
do not notice that we are passing a function around.
+
Take this code snippet as an example.
+
Because the buttonClicked function is defined outside any object we may tend to
think the this keyword will contain a reference to
the window or document
object (assuming this code is in the middle of an HTML page viewed in a browser.)
+
But when we run this code we see that it works as intended and displays the id of
the clicked button. What happened here is that we made the onclick method of each button contain the
buttonClicked object reference, replacing whatever was there before. Now
whenever the button is clicked, the browser will execute something similar to the following line.
+
That isn't so confusing afterall, is it? But see what happens you start having other
objects to deal with and you want to act on these object upon events like the button's click.
+
So you think, nice, now I can click the Clear button on my page and those three text boxes
will be emptied. Then you try clicking the button only to get a runtime error. The error
will be related to (guess what?) the this keyword.
@@ -385,13 +385,13 @@ clearButton.onclick = myHelper.emptyAllFields;
precisely what's happening. One quick solution would be to rewrite our last line of code.
+
That way we create a brand new function that calls our helper method within the helper object's context.
+
In case you haven't already used it, prototype.js is a
JavaScript library written by Sam Stephenson.
This amazingly well thought and well written piece of standards-compliant code takes a lot of
the burden associated with creating rich, highly interactive web pages that characterize the Web 2.0 off your back.
+
If you tried to use this library recently, you probably noticed that documentation is not one
of its strongest points. As many other developers before me, I got my head around prototype.js by
reading the source code and experimenting with it. I thought it would be nice to take notes while
I learned and share with everybody else.
+
As you read the examples and the reference, developers familiar with the Ruby
programming language will notice an intentional similarity between Ruby's
built-in classes and many of the extensions implemented by this library.
@@ -26,24 +26,24 @@ In case you haven't already used it, protot
+
The $() function is a handy shortcut to the all-too-frequent document.getElementById() function
of the DOM. Like the DOM function, this one returns the element that has the id passed as an argument.
+
Unlike the DOM function, though, this one goes further. You can pass more than one id and
$() will return an Array object with
all the requested elements. The example below should illustrate this.
This is a paragraph This is a paragraph This is another paragraph This is another paragraph
+
Another nice thing about this function is that you can pass either the id string or the element object itself,
which makes this function very useful when creating other functions that can also take either form of argument.
+
The $F() function is a another welcome shortcut. It returns the value of any field input control,
like text boxes or drop-down lists. The function can take as argument either the element id or the element object itself.
The syntax for working with events looks like the code below. The syntax for working with events looks like the code below. Assuming for a moment that we want to observe when a link was clicked,
+ Assuming for a moment that we want to observe when a link was clicked,
we could do the following: If we wanted to get the element that fired the event, we'd do this: If we wanted to get the element that fired the event, we'd do this: If we wanted to observe keystrokes for the entire document, we could do the following: If we wanted to observe keystrokes for the entire document, we could do the following: And lets say we wanted to keep track of what has been typed : And lets say we wanted to keep track of what has been typed : Prototype defines properties inside the event object for some
+ Prototype defines properties inside the event object for some
of the more common keys, so feel free to dig around in Prototype to
see which ones those are. A final note on keypress events; If you'd like to detect a
+ A final note on keypress events; If you'd like to detect a
left click you can use Event.isLeftClick(event). Drag and drop, dynamic element resizing, games, and
+ Drag and drop, dynamic element resizing, games, and
much more all require the ability to track the X and Y location of
the mouse. Prototype makes this fairly simple. The code below tracks
the X and Y position of the mouse and spits out those values into
an input box named mouse. If we wanted to observe the mouse location when it was
+ If we wanted to observe the mouse location when it was
hovering over a certain element, we'd just change the document argument to
the id or element that was relevant. Event.stop(event) will stop the propagation of an event . Event.stop(event) will stop the propagation of an event . Everything has been fairly straight forward so far, but things
+ Everything has been fairly straight forward so far, but things
start getting a little trickier when you need to work with events in
and object-oriented environment. You have to deal with binding and funky
looking syntax that might take a moment to get your head around. Lets look at some code so you can get a better understanding of what I'm talking about. Lets look at some code so you can get a better understanding of what I'm talking about. Whoa! What's going on here? Well, we've defined our a
+ Whoa! What's going on here? Well, we've defined our a
custom class EventDispenser. We're going to be using this class
to setup events for our document. Most of this code is a
rewrite of the code we looked at earlier except this time, we
are working from inside an object. Looking at the initialize method, we can really see how
+ Looking at the initialize method, we can really see how
things are different now. Take a look at the code below: We've got iterators, binding and all sorts of stuff going on.
+ We've got iterators, binding and all sorts of stuff going on.
Lets break down what this chunk of code is doing. First we are hunting for a collection of elements based on
+ First we are hunting for a collection of elements based on
it's CSS selector. This uses the Prototype selector function $$().
After we've found the list items we are dealing with we send
those into an each iteration where we will add our observers. Now looking at the code above, you'll notice the bindEvent function.
+ Now looking at the code above, you'll notice the bindEvent function.
This takes the method before it showTagName and treats it as the
method that will be triggered when, in this case,
someone clicks one of our list items. You'll also notice we pass this as an argument to the bindEvent function.
+ You'll also notice we pass this as an argument to the bindEvent function.
This simply allows us to reference the object in context EventDispenser
inside our function showTagName(event). If the showTagName function
requires additional parameters, you can attach them to the later parameters of bindEvent. For example Moving on, you'll see bind(this) attached to our iterator function.
+ Moving on, you'll see bind(this) attached to our iterator function.
This really has nothing to do with events, it is only here to allow me to
use this inside the iterator. If we did not use bind(this), I could not
reference the method showTagName inside the iterator. Ok, so we'll move on to looking at our methods that actually get
+ Ok, so we'll move on to looking at our methods that actually get
called when an event occurs. Since we've been dealing with showTagName, lets look at it. As you can see, this function accepts one argument--the event.
+ As you can see, this function accepts one argument--the event.
In order for us to get the element which fired the event we need to
pass that argument to Event.element. Now we can manipulate it at will. This covers the most confusing parts of our code. The text above is also
+ This covers the most confusing parts of our code. The text above is also
relevant to the remaining parts of our code. If there is anything about
this you don't understand, feel free to ask questions in the forum. This one threw me for a loop the first time I tried to use it.
+ This one threw me for a loop the first time I tried to use it.
I tried something similar to what I did in the Event.observe
call with the exception of using stopObserving, but nothing seemed
to change. In other words, the code below does NOT work. What's the deal here? The reason this does not work is because there
+ What's the deal here? The reason this does not work is because there
is no pointer to the observer. This means that when we passed this.showTagName
in the Event.observe method before hand, we passed it as an
anonymous function. We can't reference an anonymous function
because it simply does not have a pointer. So how do we get the job done? All we need to do is give the
+ So how do we get the job done? All we need to do is give the
observing function a pointer, or the jargon free version: Set a variable
that points to this.showTagName. Ok, lets change our code a bit. Now we can remove the event listeners from our list like this: Now we can remove the event listeners from our list like this: The dependencies for each library are automatically resolved. Components
+ The dependencies for each library are automatically resolved. Components
that require a particular library will also automatically load the necessary libraries.
For example, if you add a TDatePicker component on the page, the datepicker
and its dependencies will be automatically included on the page. See TClientScript for options of adding
+ See TClientScript for options of adding
your custom Javascript code to the page.
+
Viewstate lies at the heart of PRADO. Viewstate represents data that can be used to restore pages to the state that is last seen by end users before making the current request. By default, PRADO uses hidden fields to store viewstate information.
+
It is extremely important to ensure that viewstate is not tampered by end users. Without protection, malicious users may inject harmful code into viewstate and unwanted instructions may be performed when page state is being restored on server side.
+
To prevent viewstate from being tampered, PRADO enforces viewstate HMAC (Keyed-Hashing for Message Authentication) check before restoring viewstate. Such a check can detect if the viewstate has been tampered or not by end users. Should the viewstate is modified, PRADO will stop restoring the viewstate and return an error message.
+
HMAC check requires a private key that should be secret to end users. Developers can either manually specify a key or let PRADO automatically generate a key. Manually specified key is useful when the application runs on a server farm. To do so, configure TSecurityManager in application configuration,
+
HMAC check does not prevent end users from reading the viewstate content. An added security measure is to encrypt the viewstate information so that end users cannot decipher it. To enable viewstate encryption, set the EnableStateEncryption of pages to true. This can be done in page configurations or in page code. Note, encrypting viewstate may degrade the application performance. A better strategy is to store viewstate on the server side, rather than the default hidden field.
+
Cross site scripting (also known as XSS) occurs when a web application gathers malicious data from a user. Often attackers will inject JavaScript, VBScript, ActiveX, HTML, or Flash into a vulnerable application to fool other application users and gather data from them. For example, a poorly design forum system may display user input in forum posts without any checking. An attacker can then inject a piece of malicious JavaScript code into a post so that when other users read this post, the JavaScript runs unexpectedly on their computers.
+
One of the most important measures to prevent XSS attacks is to check user input before displaying them. One can do HTML-encoding with the user input to achieve this goal. However, in some situations, HTML-encoding may not be preferable because it disables all HTML tags.
+
PRADO incorporates the work of SafeHTML and provides developers with a useful component called TSafeHtml. By enclosing content within a TSafeHtml component tag, the enclosed content are ensured to be safe to end users. In addition, the commonly used TTextBox has a SafeText property which contains user input that are ensured to be safe if displayed directly to end users.
+
Protecting cookies from being attacked is of extreme important, as session IDs are commonly stored in cookies. If one gets hold of a session ID, he essentially owns all relevant session information.
+
There are several countermeasures to prevent cookies from being attacked.
+
PRADO implements a cookie validation scheme that prevents cookies from being modified. In particular, it does HMAC check for the cookie values if cookie validation is enable.
+
Cookie validation is disabled by default. To enable it, configure the THttpRequest module as follows,
+
To make use of cookie validation scheme provided by PRADO, you also need to retrieve cookies through the Cookies collection of THttpRequest by using the following PHP statements,
+
To send cookie data encoded with validation information, create new THttpCookie objects and add them to the Cookies collection of THttpResponse,
+
Web applications often need to remember what an end user has done in previous page requests so that the new page request can be served accordingly. State persistence is to address this problem. Traditionally, if a page needs to keep track of user interactions, it will resort to session, cookie, or hidden fields. PRADO provides a new line of state persistence schemes, including view state, control state, and application state.
+
View state lies at the heart of PRADO. With view state, Web pages become stateful and are capable of restoring pages to the state that end users interacted with before the current page request. Web programming thus resembles to Windows GUI programming, and developers can think continuously without worrying about the round trips between end users and the Web server. For example, with view state, a textbox control is able to detect if the user input changes the content in the textbox.
+
View state is only available to controls. View state of a control can be disabled by setting its EnableViewState property to false. To store a variable in view state, call the following,
+
where $this refers to the control object, Caption is a unique key identifying the $caption variable stored in viewstate. To retrieve the variable back from view state, call the following,
+
Control state is like view state in every aspect except that control state cannot be disabled. Control state is intended to be used for storing crucial state information without which a page or control may not work properly.
+
To store and retrieve a variable in control state, use the following commands,
+
Application state refers to data that is persistent across user sessions and page requests. A typical example of application state is the user visit counter. The counter value is persistent even if the current user session terminates. Note, view state and control state are lost if the user requests for a different page, while session state is lost if the user session terminates.
+
To store and retrieve a variable in application state, use the following commands,
+
PRADO encapsulates the traditional session management in THttpSession module. The module can be accessed from within any component by using $this->Session, where $this refers to the component object.
+
Themes in PRADO provide a way for developers to provide a consistent look-and-feel across an entire web application. A theme contains a list of initial values for properties of various control types. When applying a theme to a page, all controls on that page will receive the corresponding initial property values from the theme. This allows themes to interact with the rich property sets of the various PRADO controls, meaning that themes can be used to specify a large range of presentational properties that other theming methods (e.g. CSS) cannot. For example, themes could be used to specify the default page size of all data grids across an application by specifying a default value for the PageSize property of the TDataGrid control.
+
A theme is a directory consists of skin files, javascript files and CSS files. Any javascript or CSS files contained in a theme will be registered with the page that the theme is applied to. A skin is a set of initial property values for a particular control type. A control type may have one or several skins, each identified by a unique SkinID. When applying a theme to a page, a skin is applied to a control if the control type and the SkinID value both match to those of the skin. Note, if a skin has an empty SkinID value, it will apply to all controls of the particular type whose SkinID is not set or empty. A skin file consists of one or several skins, for one or several control types. A theme is the union of skins defined in all skin files.
+
To use a theme, you need to set the Theme property of the page with the theme name, which is the theme directory name. You may set it in either page configurations or in the constructor or onPreInit() method of the page. You cannot set the property after onPreInit() because by that time, child controls of the page are already created (skins must be applied to controls right after they are created.)
+
To use a particular skin in the theme for a control, set SkinID property of the control in template like following,
+
This will apply the 'Blue' skin to the button. Note, the initial property values specified by the 'Blue' skin will overwrite any existing property values of the button. Use stylesheet theme if you do not want them to be overwritten. To use stylesheet theme, set the StyleSheetTheme property of the page instead of Theme (you can have both StyleSheetTheme and Theme).
+
To use the Javascript files and CSS files contained in a theme, a THead control must be placed on the page template. This is because the theme will register those files with the page and THead is the right place to load those files.
+
It is possible to specify media types of CSS files contained in a theme. By default, a CSS file applies to all media types. If the CSS file is named like mystyle.print.css, it will be applied only to print media type. As another example, mystyle.screen.css applies to screen media only, and mystyle.css applies to all media types.
+
All themes by default must be placed under the [AppEntryPath]/themes directory, where AppEntryPath refers to the directory containing the application entry script. If you want to use a different directory, configure the BasePath and BaseUrl properties of the System.Web.UI.TThemeManager module in application configuration,
+
Creating a theme involves creating the theme directory and writing skin files (and possibly Javascript and CSS files). The name of skin files must be terminated with .skin. The format of skin files are the same as that of control template files. Since skin files do not define parent-child presentational relationship among controls, you cannot place a component tag within another. And any static texts between component tags are discarded. To define the aforementioned 'Blue' skin for TButton, write the following in a skin file,
+
As aforementioned, you can put several skins within a single skin file, or split them into several files. A commonly used strategy is that each skin file only contains skins for one type of controls. For example, Button.skin would contain skins only for the TButton control type.
+
Application configurations are used to specify the global behavior of an application. They include specification of path aliases, namespace usages, module and service configurations, and parameters.
+
Configuration for an application is stored in an XML file named application.xml, which should be located under the application base path. Its format is shown in the following,
-
+
Complete specification of application configurations can be found in the DTD and XSD files.
+
By default without explicit configuration, a PRADO application when running will load a few core modules, such as THttpRequest, THttpResponse, etc. It will also provide the TPageService as a default service. Configuration and usage of these modules and services are covered in individual sections of this tutorial. Note, if your application takes default settings for these modules and service, you do not need to provide an application configuration. However, if these modules or services are not sufficient, or you want to change their behavior by configuring their property values, you will need an application configuration.
+
PRADO uses configurations to glue together components into pages and applications. There are application configurations, page configurations, and templates.
+
Application and page configurations are optional if default values are used. Templates are mainly used by pages and template controls. They are optional, too.
+
Page configurations are mainly used by TPageService to modify or append the application configuration. As the name indicates, a page configuration is associated with a directory storing some page files. It is stored as an XML file named config.xml.
+
When a user requests a page stored under <BasePath>/dir1/dir2, the TPageService will try to parse and load config.xml files under <BasePath>, <BasePath>/dir1 and <BasePath>/dir1/dir2. Paths, modules, and parameters specified in these configuration files will be appended or merged into the existing application configuration. Here <BasePath> is as defined in page service.
+
The format of a page configuration file is as follows,
+
The <paths>, <modules> and <parameters> are similar to those in an application configuration. The <authorization> specifies the authorization rules that apply to the current page directory and all its subdirectories. It will be explained in more detail in future sections. The <pages> element specifies the initial values for the properties of pages. Each <page> element specifies the initial property values for a particular page identified by the id attribute. Initial property values given in the <pages> element apply to all pages in the current directory and all its subdirectories.
+
Complete specification of page configurations can be found in the DTD and XSD files.
+
Templates are used to specify the presentational layout of controls. A template can contain static text, components, or controls that contribute to the ultimate presentation of the associated control. By default, an instance of TTemplateControl or its subclass may automatically load and instantiate a template from a file whose name is the same as the control class name. For page templates, the file name suffix must be .page; for other regular template controls, the suffix is .tpl.
The template format is like HTML, with a few PRADO-specifc tags, including component tags, template control tags, comment tags, dynamic content tags, and dynamic property tags. .
+ The template format is like HTML, with a few PRADO-specifc tags, including component tags, template control tags, comment tags, dynamic content tags, and dynamic property tags. .
+
A component tag specifies a component as part of the body content of the template control. If the component is a control, it usually will become a child or grand child of the template control, and its rendering result will be inserted at the place where it is appearing in the template.
+
The format of a component tag is as follows,
-
+
It is required that component tags nest properly with each other and an opening component tag be paired with a closing tag, similar to that in XML.
+
The following template shows a component tag specifying the Text property and OnClick event of a button control,
-
+
Also note, initial values for properties whose name ends with Template are specially processed. In particular, the initial values are parsed as TTemplate objects. The ItemTemplate property of the TRepeater control is such an example.
+
To deal conveniently with properties taking take big trunk of initial data, the following property initialization tag is introduced,
-
+
When specified in templates, component ID property has special meaning in addition to its normal property definition. A component tag specified with an ID value in template will register the corresponding component to the template owner control. The component can thus be directly accessed from the template control with its ID value. For example, in Home page's template, the following component tag
-
+
Initial values specified via the template control tag are assigned to the corresponding properties when the template control is being constructed. Therefore, you may override these property values in a later stage, such as the Init stage of the control.
+
Template control tag is optional in a template. Each template can contain at most one template control tag. You can place the template control tag anywhere in the template. It is recommended that you place it at the beginning of the template for better visibility.
+
Comment tags are used to put in a template developer comments that will not display to end-users. Contents enclosed within a comment tag will be treated as raw text strings and PRADO will not attempt to parse them. Comment tags cannot be used within property values. The format of comment tags is as follows,
+
Since version 3.0.5, PRADO starts to support external template inclusion. This is accomplished via include tags, where external template files are specified in namespace format and their file name must be terminated as .tpl.
+
External templates will be inserted at the places where the include tags occur in the base template.
+
Note, nested template inclusion is not supported, i.e., you cannot have include tags in an external template.
+
Dynamic content tags are introduced as shortcuts to some commonly used component tags. These tags are mainly used to render contents resulted from evaluating some PHP expressions or statements. They include expression tags, statement tags, databind tags, parameter tags, asset tags and localization tags.
+
An expression tag represents a PHP expression that is evaluated when the template control is in PreRender stage. The expression evaluation result is inserted at the place where the tag resides in the template. The context (namely $this) of the expression is the control owning the template.
+
The format of an expression tag is as follows,
+
For example, the following expression tag will display the current page title at the place,
+
Statement tags are similar to expression tags, except that statement tags contain PHP statements rather than expressions. The output of the PHP statements (using for example echo or print in PHP) are displayed at the place where the statement tag resides in the template. The context (namely $this) of the statements is the control owning the template. The format of statement tags is as follows,
+
The following example displays the current time in Dutch at the place,
+
Databind tags are similar to expression tags, except that the expressions are evaluated only when a dataBind() call is invoked on the controls representing the databind tags. The context (namely $this) of a databind expression is the control owning the template. The format of databind tags is as follows,
+
Parameter tags are used to insert application parameters at the place where they appear in the template. The format of parameter tags is as follows,
+
Note, application parameters are usually defined in application configurations or page directory configurations. The parameters are evaluated when the template is instantiated.
+
Asset tags are used to publish private files and display the corresponding the URLs. For example, if you have an image file that is not Web-accessible and you want to make it visible to end-users, you can use asset tags to publish this file and show the URL to end-users so that they can fetch the published image.
+
The format of asset tags is as follows,
+
where LocalFileName refers to a file path that is relative to the directory containing the current template file. The file path can be a single file or a directory. If the latter, the content in the whole directory will be made accessible by end-users.
+
BE VERY CAUTIOUS when you are using asset tags as it may expose to end-users files that you probably do not want them to see.
+
Localization tags represent localized texts. They are in the following format,
+
where string will be translated to different languages according to the end-user's language preference. Localization tags are in fact shortcuts to the function call Prado::localize(string).
+
Dynamic property tags are very similar to dynamic content tags, except that they are applied to component properties. The purpose of dynamic property tags is to allow more versatile component property configuration. Note, you are not required to use dynamic property tags because what can be done using dynamic property tags can also be done in PHP code. However, using dynamic property tags bring you much more convenience at accomplishing the same tasks. The basic usage of dynamic property tags is as follows,
+
where you may enclose DynamicPropertyTag within single or double quotes for better readability.
+
Like dynamic content tags, we have expression tags, databind tags, parameter tags, asset tags and localization tags. (Note, there is no statement tag here.)
+
An expression tag represents a PHP expression that is evaluated when the control is in PreRender stage. The expression evaluation result is assigned to the corresponding component property. The format of expression tags is as follows,
+
In the expression, $this refers to the control owning the template. The following example specifies a TLabel control whose Text property is initialized as the current page title when the TLabel control is being constructed,
+
Databind tags are similar to expression tags, except that they can only be used with control properties and the expressions are evaluated only when a dataBind() call is invoked on the controls represented by the component tags. In the expression, $this refers to the control owning the template. Databind tags do not apply to all components. They can only be used for controls.
+
The format of databind tags is as follows,
+
Since v3.0.2, expression tags and databind tags can be embedded within static strings. For example, you can write the following in a template,
+
Previously, you would have to use a single expression with string concatenations to achieve the same effect.
+
Parameter tags are used to assign application parameter values to the corresponding component properties. The format of parameter tags is as follows,
+
Note, application parameters are usually defined in application configurations or page directory configurations. The parameters are evaluated when the template is instantiated.
+
Asset tags are used to publish private files and assign the corresponding the URLs to the component properties. For example, if you have an image file that is not Web-accessible and you want to make it visible to end-users, you can use asset tags to publish this file and show the URL to end-users so that they can fetch the published image. The asset tags are evaluated when the template is instantiated.
+
The format of asset tags is as follows,
+
where LocalFileName refers to a file path that is relative to the directory containing the current template file. The file path can be a single file or a directory. If the latter, the content in the whole directory will be made accessible by end-users.
+
BE VERY CAUTIOUS when you are using asset tags as it may expose to end-users files that you probably do not want them to see.
+
Localization tags represent localized texts. They are in the following format,
+
where string will be translated to different languages according to the end-user's language preference. The localization tags are evaluated when the template is instantiated. Localization tags are in fact shortcuts to the function call Prado::localize(string).
Using the TUrlMapping module different URLs can be
+ Using the TUrlMapping module different URLs can be
mapped into any existing Prado pages or services. This allows
the application to use nice looking and friendly URLs.
+
The TUrlMapping module allows aributary URL path to be mapped to a
particular service and page class. This module must be configured
before a service is initialized, thus this module should be configured
@@ -25,9 +25,9 @@ This usually means delcaring the TUrlMapping module before any
Specifying the mappings in the per directory config.xml is not supported.
-
+
To use TUrlMapping, one must set the UrlManager property of the THttpRequest module as the TUrlMapping module ID. See following for an example,
-
+
The above example is part of the application configuration of the blog demo in the PRADO release. It enables recognition of the following URL formats:
+
The ServiceParameter and ServiceID (the default ID is 'page') set the service parameter and service ID, respectively, of the Request module. The service parameter for the TPageService service is the Page class name, e.g., for an URL "index.php?page=Home", "page" is the service ID and the service parameter is "Home". Other services may use the service parameter and ID differently. See Services for further details.
+
TUrlMapping enables recognition of customized URL formats based on a list prespecified of URL patterns. Each pattern is specified in a <url> tag.
+
The Pattern and Parameters attribute
values are regular expression patterns that
determine the mapping criteria. The Pattern property takes
@@ -65,20 +65,20 @@ a regular expression with parameter names enclosed between a left brace '{
and a right brace '}'. The pattens for each parameter can be set
using Parametersattribute collection.
For example,
-
+
In the above example, the pattern contains 3 parameters named "year",
"month" and "day". The pattern for these parameters are,
respectively, "\d{4}" (4 digits), "\d{2}" (2 digits)
@@ -92,7 +92,7 @@ to form a complete regular expression string.
property you need to escape the slash in regular expressions.
- Following from the above pattern example,
+ Following from the above pattern example,
an URL "http://example.com/index.php/articles/2006/07/21" will be matched
and valid. However, "http://example.com/index.php/articles/2006/07/hello" is not
valid since the "day" parameter pattern is not satisfied.
@@ -101,19 +101,19 @@ and valid. However, "http://example.com/index.php/articles/2006/07/hello/index.php/articles/2006/07/21" portion of the URL is considered.
+
The mapped request URL is equivalent to index.php?page=ArticleView&year=2006&month=07&day=21.
The request parameter values are available through the standard Request
object. For example, $this->Request['year'].
The URL mapping are evaluated in order they are place and only the first mapping that matches
+ The URL mapping are evaluated in order they are place and only the first mapping that matches
the URL will be used. Cascaded mapping can be achieved by placing the URL mappings
in particular order. For example, placing the most specific mappings first.
+
Since version 3.0.6, TUrlMapping starts to support constructing customized URL formats. This is achieved by allowing users to extend TUrlMapping class and override the constructUrl method. In the applications, users can still use THttpRequest.constructUrl() or TPageService.constructUrl() to generate PRADO-recognizable URLS. The actual URL construction work is ultimately delegated to the TUrlMapping.constructUrl(), provided it is implemented.
+
TButton creates a click button on a Web page. The button's caption is specified by Text property. A button is used to submit data to a page. TButton raises two server-side events, OnClick and OnCommand, when it is clicked on the client-side. The difference between OnClick and OnCommand events is that the latter event is bubbled up to the button's ancestor controls. An OnCommand event handler can use CommandName and CommandParameter associated with the event to perform specific actions.
+
Clicking on button can trigger form validation, if CausesValidation is true. And the validation may be restricted within a certain group of validator controls according to ValidationGroup.
+
TCheckBox displays a check box on a Web page. A caption can be specified via Text and displayed beside the check box. It can appear either on the right or left of the check box, which is determined by TextAlign. You may further specify attributes applied to the text by using LabelAttributes.
+
To determine whether the check box is checked, test the Checked property. A CheckedChanged event is raised if the state of Checked is changed between posts to the server. If AutoPostBack is true, changing the check box state will cause postback action. And if CausesValidation is also true, upon postback validation will be performed for validators within the specified ValidationGroup.
+
TClientScript allows Javascript code to be insert or linked to the
page template. PRADO is bundled with a large library of Javascript functionality
including effects, AJAX, basic event handlers, and many others. The bundled
@@ -12,13 +12,13 @@ Javascript libraries can be linked to the current page template using the
can be specified using comma delimited string of the name of Javascript library
to include on the page. For following example will include the "ajax" and "effects" library.
- The available bundled libraries included in Prado are
-
+ The available bundled libraries included in Prado are The dependencies for each library are automatically resolved. That is,
+ The dependencies for each library are automatically resolved. That is,
specifying, say the "ajax", will also include the "prado" library. Custom Javascript files can be register using the ScriptUrl property.
+ Custom Javascript files can be register using the ScriptUrl property.
The following example includes the Javascript file "test.js" to the page. In this case, the file
"test.js" is relative the current template you are using. Since the property value is
dynamic asset tag, the file "test.js" will be published
automatically, that is, the file will be copied to the assets directory if necessary.
You can include Javascript files from other servers by specifying the full URL string in
+ You can include Javascript files from other servers by specifying the full URL string in
the ScriptUrl property. Any content within the TClientScript control tag will be considered as
+ Any content within the TClientScript control tag will be considered as
Javascript code and will be rendered where it is declared.
+
TBD
+
TDatagrid is an important control in building complex Web applications. It displays data in a tabular format with rows (also called items) and columns. A row is composed by cells, while columns govern how cells should be displayed according to their association with the columns. Data specified via DataSource or DataSourceID are bound to the rows and feed contents to cells.
+
TDataGrid is highly interactive. Users can sort the data along specified columns, navigate through different pages of the data, and perform actions, such as editing and deleting, on rows of the data.
+
Rows of TDataGrid can be accessed via its Items property. A row (item) can be in one of several modes: browsing, editing and selecting, which affects how cells in the row are displayed. To change an item's mode, modify EditItemIndex or SelectedItemIndex. Note, if an item is in edit mode, then selecting this item will have no effect.
+
Columns of a data grid determine how the associated cells are displayed. For example, cells associated with a TBoundColumn are displayed differently according to their modes. A cell is displayed as a static text if the cell is in browsing mode, a text box if it is in editing mode, and so on.
+
PRADO provides five types of columns:
+
TDataGrid defines different styles applied to its items. For example, AlternatingItemStyle is applied to alternating items (item 2, 4, 6, etc.) Through these properties, one can set CSS style fields or CSS classes for the items.
+
Item styles are applied in a hierarchical way. Styles in higher hierarchy will inherit from styles in lower hierarchy. Starting from the lowest hierarchy, the item styles include item's own style, ItemStyle, AlternatingItemStyle, SelectedItemStyle, and EditItemStyle. Therefore, if background color is set as red in ItemStyle, EditItemStyle will also have red background color, unless it is explicitly set to a different value.
+
TDataGrid provides several events to facilitate manipulation of its items,
+
TDataGrid by default will create a list of columns based on the structure of the bound data. TDataGrid will read the first row of the data, extract the field names of the row, and construct a column for each field. Each column is of type TBoundColumn.
+
The following example displays a list of computer product information using a TDataGrid. Columns are automatically generated. Pay attention to how item styles are specified and inherited. The data are populated into the datagrid using the follow code, which is common among most datagrid applications,
+
Using automatically generated columns gives a quick way of browsing tabular data. In real applications, however, automatically generated columns are often not sufficient because developers have no way customizing their appearance. Manually specified columns are thus more desirable.
+
To manually specify columns, set AutoGenerateColumns to false, and specify the columns in a template like the following,
+
Note, if AutoGenerateColumns is true and there are manually specified columns, the automatically generated columns will be appended to the manually specified columns. Also note, the datagrid's Columns property contains only manually specified columns and no automatically generated ones.
+
The following example uses manually specified columns to show a list of book information,
Pay attention to how item (row) styles and column styles cooperate together to affect the appearance of the cells in the datagrid. Pay attention to how item (row) styles and column styles cooperate together to affect the appearance of the cells in the datagrid.
+
Besides the rich data presentation functionalities as demonstrated in previous section, TDataGrid is also highly user interactive. An import usage of TDataGrid is editing or deleting rows of data. The TBoundColumn can adjust the associated cell presentation according to the mode of datagrid items. When an item is in browsing mode, the cell is displayed with a static text; when the item is in editing mode, a textbox is displayed to collect user inputs. TDataGrid provides TEditCommandColumn for switching item modes. In addition, TButtonColumn offers developers the flexibility of creating arbitrary buttons for various user interactions.
+
The following example shows how to make the previous book information table an interactive one. It allows users to edit and delete book items from the table. Two additional columns are used in the example to allow users interact with the datagrid: TEditCommandColumn and TButtonColumn. In addition,
TDropDownListColumn replaces the previous TTemplateColumn to allow users to select a rating from a dropdown list. Note, it is also possible to use TTemplateColumn to achieve the same task.
+
TDataGrid supports sorting its items according to specific columns. To enable sorting, set AllowSorting to true. This will turn column headers into clickable buttons if their SortExpression property is not empty. When users click on the header buttons, an OnSortCommand event will be raised. Developers can write handlers to respond to the sort command and sort the data according to SortExpression which is specified in the corresponding column.
+
The following example turns the datagrid in Example 2 into a sortable one. Users can click on the link button displayed in the header of any column, and the data will be sorted in ascending order along that column.
+
When dealing with large datasets, paging is helpful in reducing the page size and complexity. TDataGrid has an embedded pager that allows users to specify which page of data they want to see. The pager can be customized via PagerStyle. For example, PagerStyle.Visible determines whether the pager is visible or not; PagerStyle.Position indicates where the pager is displayed; and PagerStyle.Mode specifies what type of pager is displayed, a numeric one or a next-prev one.
+
To enable paging, set AllowPaging to true. The number of rows of data displayed in a page is specified by PageSize, while the index (zero-based) of the page currently showing to users is by CurrentPageIndex. When users click on a pager button, TDataGrid raises OnPageIndexChanged event. Typically, the event handler is written as follows,
+
The following example enables the paging functionality of the datagrid shown in Example 1. In this example, you can set various pager styles interactively to see how they affect the pager display.
+
The paging functionality shown above requires loading all data into memory, even though only a portion of them is displayed in a page. For large datasets, this is inefficient and may not always be feasible. TDataGrid provides custom paging to solve this problem. Custom paging only requires the portion of the data to be displayed to end users.
+
To enable custom paging, set both AllowPaging and AllowCustomPaging to true. Notify TDataGrid the total number of data items (rows) available by setting VirtualItemCount. And respond to the OnPageIndexChanged event. In the event handler, use the NewPageIndex property of the event parameter to fetch the new page of data from data source. For MySQL database, this can be done by using LIMIT clause in an SQL select statement.
+
Besides traditional class inheritance, extensibility of TDataGrid is mainly through developing new datagrid column components. For example, one may want to display an image column. He may use TTemplateColumn to accomplish this task. A better solution is to develop an image column component so that the work can be reused easily in other projects.
+
All datagrid column components must inherit from TDataGridColumn. The main method that needs to be overridden is initializeCell() which creates content for cells in the corresponding column. Since each cell is also in an item (row) and the item can have different types (such as Header, AltneratingItem, etc.), different content may be created according to the item type. For the image column example, one may want to create a TImage control within cells residing in items of Item and AlterantingItem types.
+
In initializeCell(), remember to call the parent implementation, as it initializes cells in items of Header and Footer types.
+
TDataList is used to display or modify a list of data items specified by its DataSource or DataSourceID property. Each data item is displayed by a data list item which is a child control of the data list. The Items property contains the list of all data list items.
+
TDataList displays its items in either a Table or Flow layout, which is specified by the RepeatLayout property. A table layout uses HTML table cells to organize the items while a flow layout uses line breaks to organize the items. When the layout is Table, the table's cellpadding and cellspacing can be adjusted by CellPadding and CellSpacing properties, respectively. And Caption and CaptionAlign can be used to add a table caption with the specified alignment. The number of columns used to display the data list items is specified via RepeatColumns property, while the RepeatDirection governs the order of the items being rendered.
+
Each data list item is created according to one of the seven kinds of templates that developers may specified for a TDataList,
+
Each of the above templates is associated with a style property that is applied to the items using the template. For example, ItemTemplate is associated with a property named AlternatingItemStyle. Through this property, one can set CSS style fields or CSS classes for the data list items.
+
Item styles are applied in a hierarchical way. Style in higher hierarchy will inherit from styles in lower hierarchy. Starting from the lowest hierarchy, the item styles include item's own style, ItemStyle, AlternatingItemStyle, SelectedItemStyle, and EditItemStyle. Therefore, if background color is set as red in ItemStyle, EditItemStyle will also have red background color, unless it is explicitly set to a different value.
+
A data list item can be in normal mode, edit mode or selected mode. Different templates will apply to items of different modes. To change an item's mode, modify EditItemIndex or SelectedItemIndex. Note, if an item is in edit mode, then selecting this item will have no effect.
+
TDataList provides several events to facilitate manipulation of its items,
+
The following example shows how to use TDataList to display tabular data, with different layout and styles.
+
A common use of TDataList is for maintaining tabular data, including browsing, editing, deleting data items. This is enabled by the command events and various item templates of TDataList.
+
The following example displays a computer product information. Users can add new products, modify or delete existing ones. In order to locate the data item for updating or deleting, DataKeys property is used.
+
Be aware, for simplicity, this application does not do any input validation. In real applications, make sure user inputs are valid before saving them into databases.
TDatePicker displays a text box for date input purpose.
+ TDatePicker displays a text box for date input purpose.
When the text box receives focus, a calendar will pop up and users can
pick up from it a date that will be automatically entered into the text box.
The format of the date string displayed in the text box is determined by
the DateFormat property. Valid formats are the combination of the
following tokens:
-
+
The date of the date picker can be set using the Date or Timestamp
properties. The Date property value must be in the same format as the pattern
specified in the DateFormat property. The Timestamp property
only accepts integers such as the Unix timestamp.
-TDatePicker has three Mode to show the date picker popup.
-
+TDatePicker has three Mode to show the date picker popup. The CssClass property can be used to override the CSS class name
+ The CssClass property can be used to override the CSS class name
for the date picker panel. The CalendarStyle property changes the overall calendar style.
-The following CalendarStyle values are available:
- TActiveButton
+TActiveButton
TActiveButton Class Diagram
-TActiveButton Class Diagram
+Adding Client Side Behaviour
+Adding Client Side Behaviour
-TActiveCheckBox
+TActiveCheckBox
TActiveCustomValidator
+TActiveCustomValidator
Active Controls (AJAX enabled Controls)
-Active Controls (AJAX enabled Controls)
+Standard Active Controls
-
+
control. See also the later part of the Active List Controls
+Standard Active Controls
+
control. See also the later part of the Extended Active Controls
-
+
control. See also the later part of the Active Control Abilities
+
Active Control Infrastructure Classes
-Active Control Infrastructure Classes
+
+
Overview of Active Controls
+Overview of Active Controls
TODO:
diff --git a/demos/quickstart/protected/pages/Advanced/Assets.page b/demos/quickstart/protected/pages/Advanced/Assets.page
index 8c7980a6..f8a41bc3 100644
--- a/demos/quickstart/protected/pages/Advanced/Assets.page
+++ b/demos/quickstart/protected/pages/Advanced/Assets.page
@@ -1,31 +1,31 @@
Assets
-Asset Publishing
-
+
-Customization
-Performance
-A Toggle Button Example
-Authentication and Authorization
-How PRADO Auth Framework Works
-Using PRADO Auth Framework
-
+
-
+
-Using TUserManager
-Collections
-Using TList
-
+
Using TList-based component properties
-Extending TList
-Using TMap
-
+
Using of TAttributeCollection
-Error Handling and Reporting
-Exception Classes
-
+
-Raising Exceptions
-Error Capturing and Reporting
-Customizing Error Display
-Internationalization (I18N) and Localization (L10N)
-Separate culture/locale sensitive data
-
+
-Configuration
-What to do with messages.xml?
-Setting and Changing Culture
-Using localize function to translate text within PHP
-Compound Messages
-I18N Components
TTranslate
-TDateFormat
-
+
+TNumberFormat
-
+
-
+Pattern characters are:
+TTranslateParameter
-TChoiceFormat
-
+
-Logging
-Using Logging Functions
-Message Routing
-
+
-Message Filtering
-Master and Content
-Master vs. External Template
-Performance Tuning
-Caching
-Using pradolite.php
-Changing Application Mode
-Reducing Page Size
-Other Techniques
-
+
+
+
+
+
+
+
JSON (JavaScript Object Notation)
-What do you mean? A function is an object too?
-Arrays, items, and object members
-Enough about objects, may I have a class now?
-Functions as arguments, an interesting pattern
-This is this but sometimes this is also that
-Using the $() function
-Using the $F() function
-Basic event handling
-Observing keystrokes
-Getting the coordinates of the mouse pointer
-Stopping Propagation
-Events, Binding, and Objects
-Removing Event Listeners
-Javascript in PRADO, Questions and Answers
How do I include the predefined Javascript libraries?
-
The available packaged libraries included in Prado are
-
+
-Security
Viewstate Protection
-Cross Site Scripting Prevention
-Cookie Attack Prevention
-
+
-Persistent State
-View State
-Control State
-Application State
-Session State
-Themes and Skins
Introduction
-Understanding Themes
-Using Themes
-Theme Storage
-Creating Themes
-Application Configurations
-
+
-Configuration Overview
-Page Configurations
-Templates: Part I
-Component Tags
-Component IDs
-Template Control Tags
A template control tag is used to configure the initial property values of the control owning the template. Its format is as follows,
-Comment Tags
-Include Tags
-Dynamic Content Tags
-Expression Tags
-Statement Tags
-Databind Tags
-Parameter Tags
-Asset Tags
-Localization Tags
-Dynamic Property Tags
-Expression Tags
-Databind Tags
-Parameter Tags
-Asset Tags
-Localization Tags
-
+
-Specifying URL Patterns
-Specifying URL Patterns
+Constructing Customized URLs
-Constructing Customized URLs
+TButton
TCheckBox
TClientScript
Including Bundled Javascript Libraries in Prado
-
+
-Including Custom Javascript Files
-Including Custom Javascript Code Blocks
-TColorPicker
Data Controls
-
+
TDataGrid
-Columns
-
+
Item Styles
-Events
-
+
Using TDataGrid
Automatically Generated Columns
-Manually Specified Columns
-
+
-Interacting with TDataGrid
-Sorting
-Paging
-Custom Paging
-Extending TDataGrid
-TDataList
-
+
-
+
-
TDatePicker
+
-
+The following CalendarStyle values are available:
The InputMode property can be set to "TextBox" or "DropDownList" with +
The InputMode property can be set to "TextBox" or "DropDownList" with default as "TextBox". In DropDownList mode, in addition to the popup date picker, three drop down list (day, month and year) are presented to select the date . When InputMode equals "DropDownList", the order and appearance of the date, month, and year will depend on the pattern specified in DateFormat property.
-The popup date picker can be hidden by specifying ShowCalendar as false. Much of the +
The popup date picker can be hidden by specifying ShowCalendar as false. Much of the text of the popup date picker can be changed to a different language using the Culture property.
-The calendar picker year limit can be set using the FromYear and UpToYear properties +
The calendar picker year limit can be set using the FromYear and UpToYear properties where FromYear is the starting year and UpToYear is the last year selectable. The starting day of the week can be changed by the FirstDayOfWeek property, with 0 as Sunday, 1 as Monday, etc.
-Note 1: If the InputMode is "TextBox", the DateFormat should +
Note 1: If the InputMode is "TextBox", the DateFormat should
only NOT contain MMM
or MMMM
patterns. The
server side date parser will not be able to determine the correct date if MMM
or
MMMM
are used. When InputMode equals "DropDownList", all patterns can be used.
Note 2: When the TDatePicker is used together +
Note 2: When the TDatePicker is used together with a validator, the DateFormat property of the validator must be equal to the DateFormat of the TDatePicker AND must set DataType="Date" on the validator to ensure correct validation. See diff --git a/demos/quickstart/protected/pages/Controls/Expression.page b/demos/quickstart/protected/pages/Controls/Expression.page index 044808c6..71230fba 100644 --- a/demos/quickstart/protected/pages/Controls/Expression.page +++ b/demos/quickstart/protected/pages/Controls/Expression.page @@ -3,18 +3,18 @@
+
TExpression evaluates a PHP expression and displays the evaluation result. To specify the expression to be evaluated, set the Expression property. Note, TExpression evaluates the expression during the rendering control lifecycle.
-+
The context of the expression in a TExpression control is the control itself. That is, $this represents the control object if it is present in the expression. For example, the following template tag will display the title of the page containing the TExpression control.
-+
Be aware, since TExpression allows execution of arbitrary PHP code, in general you should not use it to evaluate expressions submitted by your application users.
diff --git a/demos/quickstart/protected/pages/Controls/FileUpload.page b/demos/quickstart/protected/pages/Controls/FileUpload.page index 404a144e..1f2a2adb 100644 --- a/demos/quickstart/protected/pages/Controls/FileUpload.page +++ b/demos/quickstart/protected/pages/Controls/FileUpload.page @@ -3,22 +3,22 @@+
TFileUpload displays a file upload field on a Web page. Upon postback, the text entered into the field will be treated as the (local) name of the file that is uploaded to the server.
-+
TFileUpload raises an OnFileUpload event when it is post back. The property HasFile indicates whether the file upload is successful or not. If successful, the uploaded file may be saved on the server by calling saveAs() method.
-+
The following properties give the information about the uploaded file:
-+
If the file upload is unsuccessful, the property ErrorCode gives the error code describing the cause of failure. See PHP documentation for a complete explanation of the possible error codes.
diff --git a/demos/quickstart/protected/pages/Controls/Head.page b/demos/quickstart/protected/pages/Controls/Head.page index 227b5282..3ee2d6c0 100644 --- a/demos/quickstart/protected/pages/Controls/Head.page +++ b/demos/quickstart/protected/pages/Controls/Head.page @@ -3,7 +3,7 @@+
TBD
diff --git a/demos/quickstart/protected/pages/Controls/HiddenField.page b/demos/quickstart/protected/pages/Controls/HiddenField.page index aa2e7c87..7564573e 100644 --- a/demos/quickstart/protected/pages/Controls/HiddenField.page +++ b/demos/quickstart/protected/pages/Controls/HiddenField.page @@ -3,10 +3,10 @@+
THiddenField represents a hidden field on a Web page. The value of the hidden field can be accessed via its Value property.
-+
THiddenField raises an OnValueChanged event if its value is changed during postback.
diff --git a/demos/quickstart/protected/pages/Controls/HtmlArea.page b/demos/quickstart/protected/pages/Controls/HtmlArea.page index e40a4444..2b755802 100644 --- a/demos/quickstart/protected/pages/Controls/HtmlArea.page +++ b/demos/quickstart/protected/pages/Controls/HtmlArea.page @@ -3,18 +3,18 @@+
THtmlArea displays a WYSIWYG text input field on a Web page to collect input in HTML format. The text displayed in the THtmlArea control is specified or determined by using the Text property. To adjust the size of the input region, set Width and Height properties instead of Columns and Rows because the latter has no meaning under this situation. To disable the WYSIWYG feature, set EnableVisualEdit to false.
-+
THtmlArea provides the WYSIWYG feature by wrapping the functionalities provided by the TinyMCE project.
-+
The default editor gives only the basic tool bar. To change or add additional tool bars, use the Options property to add additional editor options with each options on a new line. See TinyMCE website for a complete list of options. The following example displays a toolbar specific for HTML table manipulation,
-+
The client-side visual editing capability is supported by Internet Explorer 5.0+ for Windows and Gecko-based browser. If the browser does not support the visual editing, a traditional textarea will be displayed.
diff --git a/demos/quickstart/protected/pages/Controls/HyperLink.page b/demos/quickstart/protected/pages/Controls/HyperLink.page index 9fa6bde3..5861a00f 100644 --- a/demos/quickstart/protected/pages/Controls/HyperLink.page +++ b/demos/quickstart/protected/pages/Controls/HyperLink.page @@ -3,7 +3,7 @@+
THyperLink displays a hyperlink on a page. The hyperlink URL is specified via the NavigateUrl property, and link text is via the Text property. The link target is specified via the Target property. It is also possible to display an image by setting the ImageUrl property. In this case, Text is displayed as the alternate text of the image. If both ImageUrl and Text are empty, the content enclosed within the control tag will be rendered.
+
TImage displays an image on a page. The image is specified via the ImageUrl property which takes a relative or absolute URL to the image file. The alignment of the image displayed is set by the ImageAlign property. To set alternate text or long description of the image, use AlternateText or DescriptionUrl, respectively.
+
TImageButton is also similar to TButton, except that TImageButton displays the button as an image. The image is specified via ImageUrl, and the alternate text is specified by Text. In addition, it is possible to obtain the coordinate of the point where the image is clicked. The coordinate information is contained in the event parameter of the OnClick event (not OnCommand).
+
TImageMap represents an image on a Web page with predefined hotspot regions that can respond differently to users' clicks on them. Depending on the HotSpotMode of the hotspot region, clicking on the hotspot may trigger a postback or navigate to a specified URL.
-+
Each hotspot is described using a THotSpot object and is maintained in the HotSpots collection in TImageMap. A hotspot can be a circle, rectangle, polygon, etc.
-+
Hotspots can be added to TImageMap via its HotSpots property or in a template like the following,
-+
TInlineFrame displays an inline frame (<iframe>) on a Web page. The location of the frame content is specified by the FrameUrl property.
-+
The appearance of a TInlineFrame may be customized with the following properties, in addition to those inherited from TWebControl.
-+
The following samples show TInlineFrame with different property settings. The Google homepage is used as the frame content.
+
TJavascriptLogger provides logging for client-side javascript. It is mainly a wrapper of the Javascript developed at http://gleepglop.com/javascripts/logger/.
-+
To use TJavascriptLogger, simply place the following component tag in a page template.
-+
Then, the client-side Javascript may contain the following statements. When they are executed, they will appear in the logger window.
-+
To toggle the visibility of the logger and console on the browser window, press ALT-D (or CTRL-D on OS X).
diff --git a/demos/quickstart/protected/pages/Controls/Label.page b/demos/quickstart/protected/pages/Controls/Label.page index b7d5b094..794c48de 100644 --- a/demos/quickstart/protected/pages/Controls/Label.page +++ b/demos/quickstart/protected/pages/Controls/Label.page @@ -3,7 +3,7 @@+
TLabel displays a piece of text on a Web page. The text to be displayed is set via its Text property. If Text is empty, content enclosed within the TLabel component tag will be displayed. TLabel may also be used as a form label associated with some control on the form. Since Text is not HTML-encoded when being rendered, make sure it does not contain dangerous characters that you want to avoid.
+
TLinkButton is similar to TButton in every aspect except that TLinkButton is displayed as a hyperlink. The link text is determined by its Text property. If the Text property is empty, then the body content of the button is displayed (therefore, you can enclose a <img> tag within the button body and get an image button.
+
List controls covered in this section all inherit directly or indirectly from TListControl. Therefore, they share the same set of commonly used properties, including,
-+
Since TListControl inherits from TDataBoundControl, these list controls also share a common operation known as databinding. The Items can be populated from preexisting data specified by DataSource or DataSourceID. A function call to dataBind() will cause the data population. For list controls, data can be specified in the following two kinds of format:
-+
TListBox displays a list box that allows single or multiple selection. Set the property SelectionMode as Single to make a single selection list box, and Multiple a multiple selection list box. The number of rows displayed in the box is specified via the Rows property value.
+
TDropDownList displays a dropdown list box that allows users to select a single option from a few prespecified ones.
+
TCheckBoxList displays a list of checkboxes on a Web page. The alignment of the text besides each checkbox can be specified TextAlign. The layout of the checkboxes can be controlled by the following properties:
-+
TRadioButtonList is similar to TCheckBoxList in every aspect except that each TRadioButtonList displays a group of radiobuttons. Only one of the radiobuttions can be selected (TCheckBoxList allows multiple selections.)
+
TBulletedList displays items in a bullet format on a Web page. The style of the bullets can be specified by BulletStyle. When the style is CustomImage, the bullets are displayed as images, which is specified by BulletImageUrl.
-+
TBulletedList displays the item texts in three different modes,
-+
TLiteral displays a static text on a Web page. TLiteral is similar to the TLabel control, except that the TLiteral * control has no style properties, such as BackColor, Font, etc.
-+
The text displayed by TLiteral can be programmatically controlled by setting the Text property. The text displayed may be HTML-encoded if the Encode is true (the default value is false).
-+
TLiteral will render the contents enclosed within its component tag if Text is empty.
-+
Be aware, if Encode is false, make sure Text does not contain unwanted characters that may bring security vulnerabilities.
diff --git a/demos/quickstart/protected/pages/Controls/MultiView.page b/demos/quickstart/protected/pages/Controls/MultiView.page index a22711b6..03dca27e 100644 --- a/demos/quickstart/protected/pages/Controls/MultiView.page +++ b/demos/quickstart/protected/pages/Controls/MultiView.page @@ -3,13 +3,13 @@+
TMultiView serves as a container for a group of TView controls, which can be retrieved by the Views property. Each view contains child controls. TMultiView determines which view and its child controls are visible. At any time, at most one view is visible (called active). To make a view active, set ActiveView or ActiveViewIndex. Note, by default there is no active view.
-+
To add a view to TMultiView, manipulate the Views collection or add it in template as follows,
-+
TMultiView responds to the following command events to manage the visibility of its views.
-+
Upon postback, if the active view index is changed, TMultiView will raise an OnActiveViewChanged event.
-+
The Hangman game is a typical use of TMultiView. The following example demonstrates another usage of TMultiView.
diff --git a/demos/quickstart/protected/pages/Controls/NewControl.page b/demos/quickstart/protected/pages/Controls/NewControl.page index 5662f848..d6cb52c5 100644 --- a/demos/quickstart/protected/pages/Controls/NewControl.page +++ b/demos/quickstart/protected/pages/Controls/NewControl.page @@ -1,39 +1,39 @@+
Writing new controls is often desired by advanced programmers, because they want to reuse the code that they write for dealing with complex presentation and user interactions.
-+
In general, there are two ways of writing new controls: composition of existing controls and extending existing controls. They all require that the new control inherit from TControl or its child classes.
+
Composition is the easiest way of creating new controls. It mainly involves instantiating existing controls, configuring them and making them the constituent components. The properties of the constituent components are exposed through subproperties.
-+
One can compose a new control in two ways. One is to extend TCompositeControl and override the TControl::createChildControls() method. The other is to extend TTemplateControl (or its child classes) and write a control template. The latter is easier to use and can organize the layout constituent components more intuitively, while the former is more efficient because it does not require parsing of the template.
-+
As an example, we show how to create a labeled textbox called LabeledTextBox using the above two approaches. A labeled textbox displays a label besides a textbox. We want reuse the PRADO provided TLabel and TTextBox to accomplish this task.
+
We need two files: a control class file named LabeledTextBox.php and a control template file named LabeledTextBox.tpl. Both must reside under the same directory.
-+
Like creating a PRADO page, we can easily write down the content in the control template file.
-+
The above template specifies a TLabel control named Label and a TTextBox control named TextBox. We would to expose these two controls. This can be done by defining a property for each control in the LabeledTextBox class file. For example, we can define a Label property as follows,
-+
In the above, the method call to ensureChildControls() ensures that both the label and the textbox controls are created (from template) when the Label property is accessed. The TextBox property can be implemented similarly.
+
For a composite control as simple as LabeledTextBox, it is better to create it by extending TCompositeControl and overriding the createChildControls() method, because it does not use templates and thus saves template parsing time.
-+
Complete code for LabeledTextBox is shown as follows,
-+
To use LabeledTextBox control, first we need to include the corresponding class file. Then in a page template, we can write lines like the following,
-+
In the above, Label.Text is a subproperty of LabeledTextBox, which refers to the Text property of the Label property. For other details of using LabeledTextBox, see the above online examples.
+
Extending existing controls is the same as conventional class inheritance. It allows developers to customize existing control classes by overriding their properties, methods, events, or creating new ones.
-+
The difficulty of the task depends on how much an existing class needs to be customized. For example, a simple task could be to customize TLabel control, so that it displays a red label by default. This would merely involves setting the ForeColor property to "red" in the constructor. A difficult task would be to create controls that provide completely innovative functionalities. Usually, this requires the new controls extend from "low level" control classes, such as TControl or TWebControl.
-+
In this section, we mainly introduce the base control classes TControl and TWebControl, showing how they can be customized. We also introduce how to write controls with specific functionalities, such as loading post data, raising post data and databinding with data source.
+
TControl is the base class of all control classes. Two methods are of the most importance for derived control classes:
-+
TWebControl is mainly used as a base class for controls representing HTML elements. It provides a set of properties that are common among HTML elements. It breaks the TControl::render() into the following methods that are more suitable for rendering an HTML element:
-+
When rendering the openning HTML tag, TWebControl calls getTagName() to obtain the tag name. Derived classes may override this method to render different tag names.
+
If a control wants to respond to client-side events and translate them into server side events (called postback events), such as TButton, it has to implement the IPostBackEventHandler interface.
-+
If a control wants to be able to load post data, such as TTextBox, it has to implement the IPostBackDataHandler interface.
-+
If a control wants to get data from some external data source, it can extend TDataBoundControl. TDataBoundControl implements the basic properties and methods that are needed for populating data via databinding. In fact, controls like TListControl, TRepeater are TDataGrid are all derived from it.
+
TOutputCache enables caching a portion of a Web page, also known as partial caching. The content being cached are HTML page source coming from static texts on a PRADO template or rendered by one or several controls on the template. When the cached content is used, controls generating the content are no longer created for the page hierarchy and thus significant savings in page processing time can be achieved. The side-effect, as you might already find out, is that the content displayed may be stale if the cached version is shown to the users.
-+
To use TOutputCache, simply enclose the content to be cached within the TOutputCache component tag on a template (either page or non-page control template), e.g.,
-+
where content to be cached can be static text and/or template tags. If the latter, the rendering results of the template tags will be cached. You can place one or several TOutputCache on a single template and they can be nested.
@@ -23,23 +23,23 @@ where content to be cached can be static text and/or template tags. If the latte TOutputCache stores cached content via PRADO cache modules (e.g. TSqliteCache) and thus requires at least one cache module loaded when the application runs. -+
The validity of the cached content is determined based on two factors: the Duration and the cache dependency. The former specifies the number of seconds that the data can remain valid in cache (defaults to 60s), while the latter specifies conditions that the cached data depends on. If a dependency changes (e.g. relevant data in DB are updated), the cached data will be invalidated and discarded.
-+
There are two ways to specify cache dependency. One may write event handlers to respond to the OnCheckDependency event and set the event parameter's IsValid property to indicate whether the cached data remains valid or not. One can also extend TOutputCache and override its getCacheDependency() method.
-+
The content fetched from cache may be variated with respect to some parameters. TOutputCache supports variation with respect to request parameters, which is specified by VaryByParam property. If a specified request parameter is different, a different version of cached content is used. This is extremely useful if a page's content may be variated according to some GET parameters. The content being cached may also be variated with user sessions if VaryBySession is set true. To variate the cached content by other factors, override calculateCacheKey() method.
-+
Output caches can be nested. An outer cache takes precedence over an inner cache in determining the validity of cached contents. This means, if the content cached by the inner cache expires or is invalidated, while that by the outer cache not, the outer cached content will be used.
-+
By default, TOutputCache is effective only for non-postback page requests and when a cache module is enabled. Do not attempt to address child controls of TOutputCache when the cached content is currently being used. Use ContentCached property to determine whether the content is cached or not.
diff --git a/demos/quickstart/protected/pages/Controls/Pager.page b/demos/quickstart/protected/pages/Controls/Pager.page index 20b33b95..af2e4b0a 100644 --- a/demos/quickstart/protected/pages/Controls/Pager.page +++ b/demos/quickstart/protected/pages/Controls/Pager.page @@ -3,33 +3,33 @@+
TPager creates a pager that provides UI for end-users to interactively specify which page of data to be rendered in a TDataBoundControl-derived control, such as TDataList, TRepeater, TCheckBoxList, etc. The target data-bound control is specified by the ControlToPaginate property, which must be the ID path of the target control reaching from the pager's naming container.
-+
Note, the target data-bound control must have its AllowPaging set to true. Otherwise the pager will be invisible. Also, in case when there is only one page of data available, the pager will also be invisible.
-+
TPager can display one of the following three types of user interface, specified via its Mode property:
-+
These user interfaces may be further customized by configuring the following properties
-+
TPager raises an OnPageIndexChanged event when an end-user interacts with it and specifies a new page (e.g. by clicking on a next page button that would lead to the next page.) Developers may write handlers to respond to this event and obtain the desired new page index from the event parameter's property NewPageIndex. Using this new page index, one can feed a new page of data to the associated data-bound control.
diff --git a/demos/quickstart/protected/pages/Controls/Panel.page b/demos/quickstart/protected/pages/Controls/Panel.page index be36095b..4f4f9b14 100644 --- a/demos/quickstart/protected/pages/Controls/Panel.page +++ b/demos/quickstart/protected/pages/Controls/Panel.page @@ -3,7 +3,7 @@+
TPanel acts as a presentational container for other control. It displays a <div> element on a page. The property Wrap specifies whether the panel's body content should wrap or not, while HorizontalAlign governs how the content is aligned horizontally and Direction indicates the content direction (left to right or right to left). You can set BackImageUrl to give a background image to the panel, and you can set GroupingText so that the panel is displayed as a field set with a legend text. Finally, you can specify a default button to be fired when users press 'return' key within the panel by setting the DefaultButton property.
+
TPlaceHolder reserves a place on a template, where static texts or controls may be dynamically inserted.
diff --git a/demos/quickstart/protected/pages/Controls/RadioButton.page b/demos/quickstart/protected/pages/Controls/RadioButton.page index b40f37bd..bdf5dee2 100644 --- a/demos/quickstart/protected/pages/Controls/RadioButton.page +++ b/demos/quickstart/protected/pages/Controls/RadioButton.page @@ -3,7 +3,7 @@+
TRadioButton is similar to TCheckBox in every aspect, except that TRadioButton displays a radio button on a Web page. The radio button can belong to a specific group specified by GroupName such that only one radio button within that group can be selected at most.
+
TRepeater displays its content defined in templates repeatedly based on the given data specified by the DataSource or DataSourceID property. The repeated contents can be retrieved from the Items property. Each item is created by instantiating a template and each is a child control of the repeater.
-+
Like normal control templates, the repeater templates can contain static text, controls and special tags, which after instantiation, become child contents of the corresponding item. TRepeater defines five templates for different purposes,
-+
To populate data into the repeater items, set DataSource to a valid data object, such as array, TList, TMap, or a database table, and then call dataBind() for the repeater. That is,
-+
Normally, you only need to do this when the page containing the repeater is initially requested. In postbacks, TRepeater is smart enough to remember the previous state, i.e., contents populated with datasource information.The following sample displays tabular data using TRepeater.
-+
TRepeater provides several events to facilitate manipulation of its items,
-+
The following example shows how to use TRepeater to display tabular data.
+
TRepeater can be used in more complex situations. As an example, we show in the following how to use nested repeaters, i.e., repeater in repeater. This is commonly seen in presenting master-detail data. To use a repeater within another repeater, for an item for the outer repeater is created, we need to set the detail data source for the inner repeater. This can be achieved by responding to the OnItemDataBound event of the outer repeater. An OnItemDataBound event is raised each time an outer repeater item completes databinding. In the following example, we exploit another event of repeater called OnItemCreated, which is raised each time a repeater item (and its content) is newly created. We respond to this event by setting different background colors for repeater items to achieve alternating item background display. This saves us from writing an AlternatingItemTemplate for the repeaters.
+
Besides displaying data, TRepeater can also be used to collect data from users. Validation controls can be placed in TRepeater templates to verify that user inputs are valid.
-+
The PRADO component composer demo is a good example of such usage. It uses a repeater to collect the component property and event definitions. Users can also delete or adjust the order of the properties and events, which is implemented by responding to the OnItemCommand event of repeater.
-+
See in the following yet another example showing how to use repeater to collect user inputs.
+
TSafeHtml is a control that strips down all potentially dangerous HTML content. It is mainly a wrapper of the SafeHTML project. According to the SafeHTML project, it tries to safeguard the following situations when the string is to be displayed to end-users:
-+
To use TSafeHtml, simply enclose the content to be secured within the TSafeHtml component tag in a template. The content may consist of both static text and PRADO controls. If the latter, the rendering result of the controls will be secured.
diff --git a/demos/quickstart/protected/pages/Controls/Standard.page b/demos/quickstart/protected/pages/Controls/Standard.page index f19bc07e..6ea2d52a 100644 --- a/demos/quickstart/protected/pages/Controls/Standard.page +++ b/demos/quickstart/protected/pages/Controls/Standard.page @@ -2,7 +2,7 @@* the tutorial for this control is not completed yet.
-+
TStatements evaluates a sequence of PHP statements and displays the content rendered by the statements. To specify the PHP statements to be evaluated, set the Statements property. For example, the following component tag displays the current time on the Web page,
-+
Note, TStatements evaluates the PHP statements during the rendering control lifecycle. Unlike TExpression, TStatements only displays the content 'echoed' within the statements.
-+
The context of the statements in a TStatements control is the control itself. That is, $this represents the control object if it is present in the statements. For example, the following statement tag will display the title of the page containing the TStatements control.
-+
Be aware, since TStatements allows execution of arbitrary PHP code, in general you should not use it to evaluate PHP code submitted by your application users.
diff --git a/demos/quickstart/protected/pages/Controls/Table.page b/demos/quickstart/protected/pages/Controls/Table.page index e0f5586e..ab9e6c1f 100644 --- a/demos/quickstart/protected/pages/Controls/Table.page +++ b/demos/quickstart/protected/pages/Controls/Table.page @@ -3,7 +3,7 @@+
TTable displays an HTML table on a page. It is used together with TTableRow and TTableCell to allow programmatically manipulating HTML tables. The rows of the table is stored in Rows property. You may set the table cellspacing and cellpadding via the CellSpacing and CellPadding properties, respectively. The table caption can be specified via Caption whose alignment is specified by CaptionAlign. The GridLines property indicates how the table should display its borders, and the BackImageUrl allows the table to have a background image.
+
TTextBox displays a text box on a Web page. The content in the text box is determined by the Text property. You can create a SingleLine, a MultiLine, or a Password text box by setting the TextMode property. The Rows and Columns properties specify their dimensions. If AutoPostBack is true, changing the content in the text box and then moving the focus out of it will cause postback action.
+
TTextHighlighter does syntax highlighting for its body content, including both static text and the rendering results of its child controls. The text being highlighted follows the syntax of the specified Language, which can be 'php' (default), 'prado', 'css', 'html', etc. Here, 'prado' stands for the syntax of PRADO control templates.
-+
If line numbers are desired in front of each line, set ShowLineNumbers to true.
-+
To use TTextHighlighter, simply enclose the contents to be syntax highlighted within the body of a TTextHighlighter control. The following example highlights a piece of PHP code,
-+
Validation controls, called validators, perform validation on user-entered data values when they are post back to the server. The validation is triggered by a postback control, such as a TButton, a TLinkButton or a TTextBox (under AutoPostBack mode) whose CausesValidation property is true.
-+
Validation is always performed on server side. If EnableClientScript is true and the client browser supports JavaScript, validators may also perform client-side validation. Client-side validation will validate user input before it is sent to the server. The form data will not be submitted if any error is detected. This avoids the round-trip of information necessary for server-side validation.
-+
Validators share a common set of properties, which are defined in the base class TBaseValidator class and listed as follows,
-+
TRequiredFieldValidator ensures that the user enters some data in the specified input field. By default, TRequiredFieldValidator will check if the user input is empty or not. The validation fails if the input is empty. By setting InitialValue, the validator can check if the user input is different from InitialValue. If not, the validation fails.
+
TRegularExpressionValidator verifies the user input against a regular pattern. The validation fails if the input does not match the pattern. The regular expression can be specified by the RegularExpression property. Some commonly used regular expressions include:
-[\w]{6,}
(0\d{1,4}-|\(0\d{1,4}\) ?)?\d{1,4}-\d{4}
\d{3}(-(\d{4}|\d{2}))?
\d{5}(-\d{4})?
\d{3}-\d{2}-\d{4}
+
More regular expression patterns can be found on the Internet, e.g. http://regexlib.com/.
-+
Note, TRegularExpressionValidator only checks for nonempty user input. Use a TRequiredFieldValidator to ensure the user input is not empty.
+
TEmailAddressValidator verifies that the user input is a valid email address. The validator uses a regular expression to check if the input is in a valid email address format. If CheckMXRecord is true, the validator will also check whether the MX record indicated by the email address is valid, provided checkdnsrr() is available in the installed PHP.
-+
Note, if the input being validated is empty, TEmailAddressValidator will not do validation. Use a TRequiredFieldValidator to ensure the value is not empty.
+
TCompareValidator compares the user input with a constant value specified by ValueToCompare, or another user input specified by ControlToCompare. The Operator property specifies how to compare the values, which includes Equal, NotEqual, GreaterThan, GreaterThanEqual, LessThan and LessThanEqual. Before comparison, the values being compared will be converted to the type specified by DataType listed as follows,
-+
Note, if the input being validated is empty, TEmailAddressValidator will not do validation. Use a TRequiredFieldValidator to ensure the value is not empty.
-+
N.B. If validating against a TDatePicker the DataType must be equal to "Date" and the DateFormat property of the validator must be equal to the DateFormat of the TDatePicker.
+
TDataTypeValidator verifies if the input data is of specific type indicated by DataType. The data types that can be checked against are the same as those in TCompareValidator.
-+
N.B. If validating against a TDatePicker the DataType must be equal to "Date" and the DateFormat property of the validator must be equal to the DateFormat of the TDatePicker.
@@ -105,10 +105,10 @@ TDataTypeValidator verifies if the input data is of specific type indicated by <+
TRangeValidator verifies whether an input value is within a specified range. TRangeValidator uses three key properties to perform its validation. The MinValue and MaxValue properties specify the minimum and maximum values of the valid range. The DataType property specifies the data type of the value being validated. The value will be first converted into the specified type and then compare with the valid range. The data types that can be checked against are the same as those in TCompareValidator.
-+
N.B. If validating against a TDatePicker the DataType must be equal to "Date" and the DateFormat property of the validator must be equal to the DateFormat of the TDatePicker.
@@ -116,16 +116,16 @@ TRangeValidator verifies whether an input value is within a specified range. TRa+
TCustomValidator performs user-defined validation (either server-side or client-side or both) on an input control.
-+
To create a server-side validation function, provide a handler for the OnServerValidate event that performs the validation. The data string of the input control to validate can be accessed by the event parameter's Value property. The result of the validation should be stored in the IsValid property of the parameter.
-+
To create a client-side validation function, add the client-side validation javascript function to the page template and assign its name to the ClientValidationFunction property. The function should have the following signature:
-