diff options
author | wei <> | 2007-01-14 02:10:24 +0000 |
---|---|---|
committer | wei <> | 2007-01-14 02:10:24 +0000 |
commit | 45b0fe42a979d444d547a5248eb2e9e915aaf16a (patch) | |
tree | 2480dae3350e4a70949956c41984cceb8dce3efc | |
parent | 898049a4012eaecd99e7a418726215e656677809 (diff) |
Add "block-content" to allow user comments on block level elements in quickstart docs.
115 files changed, 2258 insertions, 1393 deletions
diff --git a/.gitattributes b/.gitattributes index 24b923d7..3f081cfb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -348,6 +348,7 @@ buildscripts/chmbuilder/classes/pages/Classes.php -text buildscripts/chmbuilder/classes/pages/MainLayout.php -text buildscripts/chmbuilder/classes/pages/MainLayout.tpl -text buildscripts/chmbuilder/classes/pages/style.css -text +buildscripts/chmbuilder/index.php -text buildscripts/classtree/DWExtension.php -text buildscripts/classtree/DWExtensionReadme.txt -text buildscripts/classtree/build.php -text @@ -812,6 +813,13 @@ demos/quickstart/index2.php -text demos/quickstart/protected/.htaccess -text demos/quickstart/protected/QuickStartGlobalization.php -text demos/quickstart/protected/application.xml -text +demos/quickstart/protected/controls/Comments/CommentBlock.php -text +demos/quickstart/protected/controls/Comments/CommentBlock.tpl -text +demos/quickstart/protected/controls/Comments/comments.css -text +demos/quickstart/protected/controls/Comments/comments.js -text +demos/quickstart/protected/controls/Comments/right_back.png -text +demos/quickstart/protected/controls/Comments/right_tag.png -text +demos/quickstart/protected/controls/Comments/tag.gif -text demos/quickstart/protected/controls/DocLink.php -text demos/quickstart/protected/controls/Layout.php -text demos/quickstart/protected/controls/Layout.tpl -text @@ -2354,6 +2362,7 @@ tests/simple_unit/ActiveRecord/ActiveRecordMySql5TestCase.php -text tests/simple_unit/ActiveRecord/ActiveRecordRegistryTestCase.php -text tests/simple_unit/ActiveRecord/BaseActiveRecordTestCase.php -text tests/simple_unit/ActiveRecord/CountRecordsTestCase.php -text +tests/simple_unit/ActiveRecord/CriteriaTestCase.php -text tests/simple_unit/ActiveRecord/DeleteByPkTestCase.php -text tests/simple_unit/ActiveRecord/FindByPksTestCase.php -text tests/simple_unit/ActiveRecord/FindBySqlTestCase.php -text @@ -2368,6 +2377,7 @@ tests/simple_unit/ActiveRecord/records/SimpleUser.php -text tests/simple_unit/ActiveRecord/records/SqliteUsers.php -text tests/simple_unit/ActiveRecord/records/UserRecord.php -text tests/simple_unit/Soap/ContactManager.php -text +tests/simple_unit/Soap/SoapTestCase.php -text tests/simple_unit/SqlMap/ActiveRecordSqlMapTest.php -text tests/simple_unit/SqlMap/BaseCase.php -text tests/simple_unit/SqlMap/CacheTest.php -text @@ -2481,7 +2491,9 @@ tests/simple_unit/SqlMap/scripts/sqlite/database.sql -text tests/simple_unit/SqlMap/sqlite.xml -text tests/simple_unit/SqlMap/sqlite/backup.db -text tests/simple_unit/SqlMap/sqlite/tests.db -text +tests/simple_unit/application.xml -text tests/simple_unit/unit.php -text +tests/simple_unit/ws.php -text tests/test_tools/selenium/core/lib/cssQuery/cssQuery-p.js -text tests/test_tools/selenium/core/lib/cssQuery/src/cssQuery-level2.js -text tests/test_tools/selenium/core/lib/cssQuery/src/cssQuery-level3.js -text diff --git a/buildscripts/chmbuilder/index.php b/buildscripts/chmbuilder/index.php new file mode 100644 index 00000000..4330e1a9 --- /dev/null +++ b/buildscripts/chmbuilder/index.php @@ -0,0 +1,7 @@ +<?php
+include('../../framework/prado.php');
+ $app = new TApplication("classes");
+ $app->run();
+
+
+?>
\ No newline at end of file diff --git a/buildscripts/texbuilder/Page2Tex.php b/buildscripts/texbuilder/Page2Tex.php index 5d9a2b81..2374647c 100644 --- a/buildscripts/texbuilder/Page2Tex.php +++ b/buildscripts/texbuilder/Page2Tex.php @@ -4,6 +4,9 @@ class Page2Tex {
private $_current_page;
private static $header_count = 0;
+ private static $p_count=0;
+ private static $hil_count=0;
+ private $page_count=0;
private $_base;
private $_dir;
@@ -270,29 +273,66 @@ class Page2Tex }
- function set_header_id($content)
+ function set_header_id($content, $j)
{
+ $this->page_count=$j;
$content = preg_replace_callback('/<h1>/', array($this,"h1"), $content);
$content = preg_replace_callback('/<h2>/', array($this,"h2"), $content);
$content = preg_replace_callback('/<h3>/', array($this,"h3"), $content);
+ $content = $this->set_block_content_id($content);
return $content;
}
function h1($matches)
{
- return "<h1 id=\"".(++self::$header_count)."\">";
+ $page = $this->page_count*1000;
+ return "<h1 id=\"".($page + (++self::$header_count))."\">";
}
function h2($matches)
{
- return "<h2 id=\"".(++self::$header_count)."\">";
+ $page = $this->page_count*1000;
+ return "<h2 id=\"".($page + (++self::$header_count))."\">";
}
function h3($matches)
{
- return "<h3 id=\"".(++self::$header_count)."\">";
+ $page = $this->page_count*1000;
+ return "<h3 id=\"".($page + (++self::$header_count))."\">";
+ }
+
+ function set_block_content_id($content)
+ {
+ $content = preg_replace_callback('/<p>/', array($this, 'add_p'), $content);
+ $content = preg_replace_callback('/<com:TTextHighlighter([^>]+)>/', array($this, 'hil'), $content);
+ return $content;
+ }
+
+ function hil($matches)
+ {
+ $id = ($this->page_count*10000) + (++self::$hil_count);
+ if(preg_match('/id="code-\d+"/i', $matches[1]))
+ {
+ $code = preg_replace('/id="code-(\d+)"/', 'id="code_$1"', $matches[0]);
+ //var_dump($code);
+ return $code;
+ }
+ else if(preg_match('/id="[^"]+"/i', $matches[1]))
+ {
+ return $matches[0];
+ }
+ else
+ {
+ $changes = str_replace('"source"', '"source block-content" id="code-'.$id.'"', $matches[0]);
+ return $changes;
+ }
}
+ function add_p($matches)
+ {
+ $page = $this->page_count*10000;
+ return "<p id=\"".($page + (++self::$p_count))."\" class=\"block-content\">";
+ }
}
?>
diff --git a/buildscripts/texbuilder/quickstart/build.php b/buildscripts/texbuilder/quickstart/build.php index b5ee7841..2cee7fee 100644 --- a/buildscripts/texbuilder/quickstart/build.php +++ b/buildscripts/texbuilder/quickstart/build.php @@ -36,9 +36,9 @@ foreach($pages as $chapter => $sections) $current_path = $page;
$parser->setCurrentPage($current_path);
- //add id to <h1>, <h2>, <3>
+ //add id to <h1>, <h2>, <h3> and <p>
$tmp_content = $parser->set_header_id(file_get_contents($page),$j++);
-// file_put_contents($page, $tmp_content);
+ file_put_contents($page, $tmp_content);
$content .= $parser->get_section_label($section);
$file_content = file_get_contents($page);
diff --git a/demos/quickstart/protected/controls/Comments/CommentBlock.php b/demos/quickstart/protected/controls/Comments/CommentBlock.php new file mode 100644 index 00000000..63b25c72 --- /dev/null +++ b/demos/quickstart/protected/controls/Comments/CommentBlock.php @@ -0,0 +1,107 @@ +<?php
+
+Prado::using('System.Data.*');
+Prado::using('System.Web.UI.ActiveControls.*');
+Prado::using('System.Data.ActiveRecord.TActiveRecordManager');
+
+$db = new TDbConnection('mysql:host=localhost;dbname=xxxx', 'yyyy', 'zzzz');
+$manager = TActiveRecordManager::getInstance();
+$manager->setDbConnection($db);
+
+class CommentRecord extends TActiveRecord
+{
+ public $id;
+ public $username;
+ public $date_added;
+ public $page;
+ public $block_id;
+ public $content;
+
+ public static $_tablename='qs_comments';
+
+ public static function finder()
+ {
+ return self::getRecordFinder('CommentRecord');
+ }
+}
+
+class CommentBlock extends TTemplateControl
+{
+ private $_page;
+
+ function onLoad($param)
+ {
+ if(!$this->Page->IsCallBack)
+ {
+ $count = array();
+ $data = $this->getCommentData();
+ foreach($data as $r)
+ {
+ if(!isset($count[$r->block_id]))
+ $count[$r->block_id]=0;
+ $count[$r->block_id]++;
+ }
+ $js = "var comment_count = ".TJavascript::encode($count).";\n";
+ $this->Page->ClientScript->registerBeginScript('count',$js);
+ $this->comments->dataSource = $data;
+ $this->comments->dataBind();
+ }
+ }
+
+ function getCommentData()
+ {
+ return CommentRecord::finder()->findAllByPage($this->getCurrentPagePath());
+ }
+
+ function add_comment($sender, $param)
+ {
+ if(!$this->Page->IsValid)
+ return;
+ $record = new CommentRecord;
+ $record->username = $this->username->Text;
+ $record->date_added = date('Y-m-d h:i:s');
+ $record->page = $this->getCurrentPagePath();
+ $record->block_id = $this->block_id->Value;
+ $record->content = $this->content->Text;
+ $record->save();
+
+ $this->content->Text = '';
+ $this->password->Text = '';
+ $cc = $this->Page->CallbackClient;
+ $cc->appendContent('comment-list', $this->format_message($record));
+ $cc->callClientFunction('hide_add_comment');
+ $cc->callClientFunction('increment_count_tag', $record->block_id);
+ if(!$this->Page->IsCallBack)
+ {
+ $this->comments->dataSource = $this->getCommentData();
+ $this->comments->dataBind();
+ }
+ }
+
+ protected function getCurrentPagePath()
+ {
+ if(is_null($this->_page))
+ {
+ $page = str_replace($this->Service->BasePath, '', $this->Page->Template->TemplateFile);
+ $this->_page = str_replace('\\', '/', $page);
+ }
+ return $this->_page;
+ }
+
+ function validate_credential($sender, $param)
+ {
+ $param->IsValid = $this->password->Text == 'Prado';
+ }
+
+ protected function format_message($record)
+ {
+ $username=htmlspecialchars($record->username);
+ $content=nl2br(htmlspecialchars($record->content));
+ return <<<EOD
+ <div class="comment c-{$record->block_id}">
+ <span><a href="#">{$username}</a> on {$record->date_added}.</span>
+ <div>{$content}</div>
+ </div>
+EOD;
+ }
+}
\ No newline at end of file diff --git a/demos/quickstart/protected/controls/Comments/CommentBlock.tpl b/demos/quickstart/protected/controls/Comments/CommentBlock.tpl new file mode 100644 index 00000000..831938f2 --- /dev/null +++ b/demos/quickstart/protected/controls/Comments/CommentBlock.tpl @@ -0,0 +1,63 @@ +<com:TStyleSheet StyleSheetUrl=<%~ comments.css %> />
+<!--
+ <%~ right_back.png %>
+ <%~ right_tag.png %>
+ <%~ tag.gif %>
+-->
+<h2 style="margin-bottom: 0.4em; margin-top: 2em; border-bottom: 0 none" id="comments-header">User Comments</h2>
+<div id="user-comments">
+ <ul id="comment-nav">
+ <li><a href="#comment-list" style="display:none" id="show-comment-link" >View Comments</a></li>
+ <li><a href="#add-comment" class="active" id="add-comment-link">Add New Comment</a></li>
+ </ul>
+ <a href="javascript:;" class="right-tab" style="display:none" id="close-comments">Close</a>
+ <a href="#" class="right-tab" id="to-top">Top</a>
+<div id="comment-list">
+ <com:TRepeater ID="comments">
+ <prop:ItemTemplate>
+ <%# $this->parent->parent->format_message($this->DataItem) %>
+ </prop:ItemTemplate>
+ </com:TRepeater>
+</div>
+ <div id="add-comment">
+
+ <div class="username">
+ <div>
+ <com:TLabel ForControl="username" Text="Username/Password:" />
+ <span class="hint">(must have 5 or more posts in forum)</span>
+ <com:TRequiredFieldValidator
+ Style="font-weight: bold"
+ ControlToValidate="username"
+ ErrorMessage="*" />
+ </div>
+ <com:TTextBox ID="username" /> /
+ <com:TTextBox ID="password" TextMode="Password" />
+ <com:TActiveCustomValidator
+ ID="credential_validator"
+ ControlToValidate="password"
+ OnServerValidate="validate_credential"
+ ErrorMessage="Incorrect username/password" />
+ </div>
+ <div class="content">
+ <div>
+ <com:TLabel ForControl="content" Text="Comment:" />
+ <com:TRequiredFieldValidator
+ Style="font-weight: bold"
+ ControlToValidate="content"
+ ErrorMessage="*" />
+ </div>
+ <com:TTextBox TextMode="MultiLine" ID="content" />
+ <com:THiddenField ID="block_id" Value="top-content"/>
+ </div>
+
+ <div class="submit">
+ <com:TActiveButton Text="Add Comment" OnClick="add_comment" />
+ </div>
+ </div>
+</div>
+
+<div id="modal-background"></div>
+<com:TClientScript PradoScripts="prado" ScriptUrl=<%~ comments.js %> >
+ var hidden_block_id = '<%= $this->block_id->ClientID %>';
+ var content_textare_id = '<%= $this->content->ClientID %>';
+</com:TClientScript>
diff --git a/demos/quickstart/protected/controls/Comments/comments.css b/demos/quickstart/protected/controls/Comments/comments.css new file mode 100644 index 00000000..fb03951f --- /dev/null +++ b/demos/quickstart/protected/controls/Comments/comments.css @@ -0,0 +1,226 @@ +body
+{
+ background-image: url(right_back.png);
+ background-position: right;
+ background-repeat: repeat-y;
+}
+
+.languages
+{
+ margin-right: 80px !important;
+}
+
+div#content
+{
+ padding-right: 75px;
+}
+
+.block-content
+{
+ border-bottom: 1px dashed white;
+ border-top: 1px dashed white;
+ border-right: 1px solid white;
+ background-color: White;
+ position: relative;
+ z-index: 0;
+ display: block;
+}
+
+div.block-content
+{
+ margin-top: 0 !important;
+}
+
+.block-hover
+{
+ border-bottom: 1px dashed #0cf;
+ border-top: 1px dashed #0cf;
+ border-right-color: #0cf;
+ border-right-style: solid;
+ background-color: #F9FCFF;
+ padding-right: 9px;
+ margin-right: -9px;
+}
+
+div.block-hover
+{
+ border-bottom: 1px dashed #0cf !important;
+ border-top: 1px dashed #0cf !important;
+ border-right-color: #0cf !important;
+ border-right-style: solid !important;
+ background-color: #F9FCFF !important;
+ padding-right: 9px !important;
+ margin-right: -9px !important;
+}
+
+.block-comment-tag
+{
+ width: 51px;
+ float: right;
+ margin-right: -60px;
+ text-align: center;
+ color: #6495ED;
+ font-weight: bold;
+ cursor: pointer;
+}
+
+.block-comment-tag-ie
+{
+ width: 60px;
+ float: right;
+ margin-right: -69px;
+ text-align: center;
+ color: #6495ED;
+ font-weight: bold;
+ cursor: pointer;
+}
+
+.block-comment-tag div
+{
+ padding-top: 4px;
+ background-image: url(tag.gif);
+ background-repeat: no-repeat;
+ height: 26px;
+}
+
+.block-comment-tag-ie div
+{
+ padding-top: 4px;
+ background-image: url(tag.gif);
+ background-repeat: no-repeat;
+ height: 26px;
+ background-position: 9px 0px;
+}
+
+#user-comments
+{
+ border: 1px solid #B3CC8B;
+ padding: 10px;
+ background-color: #E5EDD7;
+/* position: absolute;
+ margin-right: 80px; */
+ z-index: 100;
+}
+
+#comment-list, #add-comment
+{
+/* height: 320px;*/
+ background-color: White;
+ padding: 10px;
+ clear: both;
+ border-top: 10px solid white;
+ margin-top: -3px;
+}
+
+#comment-list
+{
+/* overflow: auto;*/
+}
+
+#comment-nav, #comment-nav li
+{
+ display: inline;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+#comment-nav
+{
+ display: block;
+ height: 26px;
+}
+
+#comment-nav li a
+{
+ float: left;
+ padding: 0.4em 1.5em;
+ color: #9BB190;
+ text-decoration: none;
+ font-weight: bold;
+ background-color: #ECF0EA;
+ margin-right: 5px;
+}
+
+#comment-nav li a.active
+{
+ color: #556B2F;
+ background-color: White;
+}
+
+#user-comments .right-tab
+{
+ text-decoration: none;
+ padding: 0.4em 1em;
+ float:right;
+ color: #556B2F;
+ background-color: White;
+ margin-top: -1.95em;
+}
+
+#comment-list .comment
+{
+ margin-bottom: 2em;
+}
+
+#comment-list .comment span
+{
+ font-size: 0.85em;
+ border-bottom: 1px dotted #ccc;
+ padding: 0.2em;
+ display: block;
+}
+
+#comment-list .comment div
+{
+
+ padding: 0.5em;
+}
+
+#add-comment label
+{
+ font-weight: bold;
+}
+#add-comment .hint
+{
+ font-size: 0.8em;
+ font-weight: normal;
+}
+
+#add-comment .username input
+{
+ width: 180px
+}
+
+#add-comment .content
+{
+ margin-top: 0.5em;
+}
+
+#add-comment .content textarea
+{
+ width: 95%;
+ height: 180px;
+}
+
+
+#add-comment .submit
+{
+ border-top: 1px solid #ccc;
+ margin-top: 1em;
+ padding: 1em;
+}
+
+#add-comment .submit input
+{
+ width: 130px;
+}
+
+
+#modal-background
+{
+ background-color: #556B2F;
+ position: absolute;
+ z-index: 0;
+ filter: Alpha(Opacity=50);
+}
\ No newline at end of file diff --git a/demos/quickstart/protected/controls/Comments/comments.js b/demos/quickstart/protected/controls/Comments/comments.js new file mode 100644 index 00000000..4e0cdf67 --- /dev/null +++ b/demos/quickstart/protected/controls/Comments/comments.js @@ -0,0 +1,179 @@ +var currentCommentID;
+
+function show_comment_list()
+{
+ $('comment-list').show();
+ $('add-comment').hide();
+ $('show-comment-link').addClassName("active");
+ $('add-comment-link').removeClassName("active");
+}
+
+function show_add_comment()
+{
+ $('comment-list').hide();
+ $('add-comment').show();
+ $('show-comment-link').removeClassName("active");
+ $('add-comment-link').addClassName("active");
+}
+
+function hide_add_comment()
+{
+ $('user-comments').hide();
+ $('modal-background').hide();
+ $(content_textare_id).value = '';
+ $(currentCommentID).style.zIndex = 0;
+}
+
+function show_comments(block)
+{
+ var id = block.id
+ currentCommentID = id;
+ $(hidden_block_id).value = id;
+ var commentBlock = $('user-comments');
+ var pos = Position.cumulativeOffset(block);
+ var top = pos[1] + block.offsetHeight;
+ commentBlock.style.top = top+"px";
+ commentBlock.style.width = (block.offsetWidth-22)+"px";
+
+ commentBlock.show();
+ var list = $('comment-list');
+ var count=0;
+ for(var i=0, k=list.childNodes.length; i < k; i++)
+ {
+ var node = list.childNodes[i];
+ if(node.nodeType == 1) //an element node
+ {
+ if(node.className.indexOf(id) >= 0)
+ {
+ node.style.display="block"
+ count++;
+ }
+ else
+ node.style.display="none";
+ }
+ }
+
+ list.show();
+ if(count > 0)
+ show_comment_list();
+ else
+ show_add_comment();
+
+ var background = $('modal-background');
+ background.style.top="0px";
+ background.style.left="0px";
+ background.style.opacity="0.5";
+ background.style.width = document.body.offsetWidth+"px";
+ background.style.height = document.body.offsetHeight+"px";
+ background.show();
+ block.style.zIndex = 100;
+ block.style.paddingRight="9px";
+ block.style.marginRight="-9px";
+
+}
+
+function show_block(block)
+{
+ while(block && block.className.indexOf("block-content") < 0)
+ block = block.parentNode;
+ if(block && block.className.indexOf("block-content") >= 0)
+ {
+ block.addClassName('block-hover');
+ var tag = $('tag-'+block.id);
+// if(tag.className.indexOf("tag-shown")<=0)
+ tag.firstChild.style.visibility="visible"
+ }
+}
+
+function hide_block(block)
+{
+ while(block && block.className.indexOf("block-hover") < 0)
+ block = block.parentNode;
+ if(block && block.className.indexOf("block-hover") >= 0)
+ {
+ block.removeClassName('block-hover');
+ var tag = $('tag-'+block.id);
+ if(tag.className.indexOf("tag-shown")<=0)
+ tag.firstChild.style.visibility="hidden"
+ }
+}
+
+function add_comment_tag(el)
+{
+ var dim = Element.getDimensions(el);
+ var comments = get_comment_count(el.id);
+ var style = "height:"+(dim.height > 35 ? dim.height : 35)+"px;";
+ var cssClass = dim.height ? "block-comment-tag" : "block-comment-tag-ie";
+ var title = "View "+comments+" comments"
+ var innerStyle="";
+ if(comments <= 0)
+ {
+ innerStyle = " visibility:hidden;";
+ comments = "add";
+ title = "Add new comment";
+ }
+ else
+ cssClass += " tag-shown";
+ var id = "tag-"+el.id;
+ var tag = "<div id='"+id+"' class='"+cssClass+"' style='"+style+"'><div style='"+innerStyle+"' title='"+title+"'>"+comments+"</div> </div>";
+ new Insertion.Before(el, tag);
+ var tag_div = $(id);
+ Event.observe(tag_div, "mouseover", function(e){ show_block(el); });
+ Event.observe(tag_div, "mouseout", function(e){ hide_block(el); });
+ Event.observe(tag_div, "click", function(e) { show_comments(el); Event.stop(e); });
+}
+
+function increment_count_tag(id)
+{
+ var tag = $('tag-'+id);
+ if(tag && tag.firstChild)
+ {
+ if(tag.className.indexOf("tag-shown") >= 0)
+ {
+ var count = Number(tag.firstChild.innerHTML);
+ tag.firstChild.innerHTML = (++count)+"";
+ tag.firstChild.style.visibility="visible";
+ }
+ else
+ {
+ tag.firstChild.innerHTML = "1";
+ tag.addClassName("tag-shown");
+ tag.firstChild.style.visibility="visible";
+ }
+ }
+}
+
+function get_comment_count(id)
+{
+ return comment_count[id] ? comment_count[id] : 0;
+}
+
+//initialize the comment js
+
+(function()
+{
+ var userComments = $('user-comments');
+ userComments.style.position="absolute";
+ userComments.style.marginRight="80px";
+ var commentList = $('comment-list');
+ commentList.style.height="320px";
+ $('add-comment').style.height="320px";
+ commentList.style.overflow="auto";
+ $('show-comment-link').style.display="";
+ $('to-top').hide();
+ $('close-comments').show();
+ userComments.hide();
+ $('comments-header').hide();
+
+ $$('#content .block-content').each(function(el)
+ {
+ Event.observe(el, 'mouseover', function(e){ show_block(Event.element(e)); });
+ Event.observe(el, 'mouseout', function(e){ hide_block(Event.element(e)); });
+ add_comment_tag(el);
+ });
+
+ Event.observe($('show-comment-link'), "click", function(e) { show_comment_list(); Event.stop(e); });
+ Event.observe($('add-comment-link'), "click", function(e) { show_add_comment(); Event.stop(e); });
+ Event.observe($('close-comments'), "click", function(e) { hide_add_comment(); Event.stop(e); });
+
+})();
diff --git a/demos/quickstart/protected/controls/Comments/right_back.png b/demos/quickstart/protected/controls/Comments/right_back.png Binary files differnew file mode 100644 index 00000000..d591e24e --- /dev/null +++ b/demos/quickstart/protected/controls/Comments/right_back.png diff --git a/demos/quickstart/protected/controls/Comments/right_tag.png b/demos/quickstart/protected/controls/Comments/right_tag.png Binary files differnew file mode 100644 index 00000000..20adda2f --- /dev/null +++ b/demos/quickstart/protected/controls/Comments/right_tag.png diff --git a/demos/quickstart/protected/controls/Comments/tag.gif b/demos/quickstart/protected/controls/Comments/tag.gif Binary files differnew file mode 100644 index 00000000..654b61de --- /dev/null +++ b/demos/quickstart/protected/controls/Comments/tag.gif diff --git a/demos/quickstart/protected/controls/Layout.tpl b/demos/quickstart/protected/controls/Layout.tpl index 87013156..5426a221 100644 --- a/demos/quickstart/protected/controls/Layout.tpl +++ b/demos/quickstart/protected/controls/Layout.tpl @@ -42,7 +42,9 @@ </prop:FooterTemplate>
</com:TRepeater>
<div id="content">
+<p class="block-content" id="top-content" style="border-color: transparent; height:1px; margin: 0; padding: 0; background-color: transparent"></p>
<com:TContentPlaceHolder ID="body" />
+<com:Application.controls.Comments.CommentBlock Visible="false" />
</div>
</td>
</tr>
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 @@ <com:TContent ID="body">
<!-- $Id$ -->
-<h1>TActiveButton</h1>
+<h1 id="122026">TActiveButton</h1>
<com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveButton" />
-<p><tt>TActiveButton</tt> is the active control counter part to
+<p id="610410" class="block-content"><tt>TActiveButton</tt> is the active control counter part to
<a href="?page=Controls.Button">TButton</a>.
When a <tt>TActiveButton</tt> is clicked, rather than a normal post back request a
callback request is initiated. The <tt>OnCallback</tt> event is raised
@@ -11,29 +11,29 @@ during a callback request and it is raise <strong>after</strong> the <tt>OnClick</tt> event.
</p>
-<p>When the <tt>ActiveControl.EnableUpdate</tt> property is true,
+<p id="610411" class="block-content">When the <tt>ActiveControl.EnableUpdate</tt> property is true,
changing the <tt>Text</tt> property during a callback request will update
the button's caption on the client-side.</p>
-<p>Since the <tt>OnCallback</tt> event is raised only during a callback request,
+<p id="610412" class="block-content">Since the <tt>OnCallback</tt> event is raised only during a callback request,
the <tt>OnCallback</tt> event handler can be used to handle logic specifically
related to callback requests. The <tt>OnClick</tt> event handler is raised
when ever the button is clicked, even if javascript is disabled.</p>
-<p>The following example the use of both the <tt>OnClick</tt> and <tt>OnCallback</tt>
+<p id="610413" class="block-content">The following example the use of both the <tt>OnClick</tt> and <tt>OnCallback</tt>
events of an <tt>TActiveButton</tt>.</p>
<com:RunBar PagePath="ActiveControls.Samples.TActiveButton.Home" />
-<h2>TActiveButton Class Diagram</h2>
-<p>The class diagram for <tt>TActiveButton</tt> is illustrated in the figure below.
+<h2 id="122027">TActiveButton Class Diagram</h2>
+<p id="610414" class="block-content">The class diagram for <tt>TActiveButton</tt> is illustrated in the figure below.
Most active control that can perform callback request have a similar structure.
</p>
<img src=<%~ TActiveButtonClass.png %> class="figure"
alt="TActiveButton class diagram" title="TActiveButton class diagram" />
-<p><tt>TActiveButton</tt> is an extension of <a href="?page=Controls.Button">TButton</a>
+<p id="610415" class="block-content"><tt>TActiveButton</tt> is an extension of <a href="?page=Controls.Button">TButton</a>
and implements two additional interfaces <tt>ICallbackEventHandler</tt> and
<tt>IActiveControl</tt>. The <tt>TActiveButton</tt> contains an instance of
<a href="?page=ActiveControls.BaseActiveControl">TBaseActiveCallbackControl</a>
@@ -41,24 +41,24 @@ available through the <tt>ActiveControl</tt> property of <tt>TActiveButton</tt>. The following example set the callback parameter of the <tt>TActiveButton</tt> when
a callback request is dispatched.
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code1">
<com:TActiveButton
Text="Click Me"
OnCallback="button_callback"
ActiveControl.CallbackParameter="value" />
</com:TTextHighlighter>
-<p>In the <tt>OnCallback</tt> event handler method, the <tt>CallbackParameter</tt>
+<p id="610416" class="block-content">In the <tt>OnCallback</tt> event handler method, the <tt>CallbackParameter</tt>
is available in the <tt>$param</tt> object.</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code2">
public function button_callback($sender, $param)
{
echo $param->CallbackParameter; //outputs "value"
}
</com:TTextHighlighter>
-<h2>Adding Client Side Behaviour</h2>
+<h2 id="122028">Adding Client Side Behaviour</h2>
-<p>With in the <tt>ActiveControl</tt> property is an instance of
+<p id="610417" class="block-content">With in the <tt>ActiveControl</tt> property is an instance of
<a href="?page=ActiveControls.CallbackClientSide">TCallbackClientSide</a> available
as a property <tt>ClientSide</tt> of <tt>TActiveButton</tt>.
The <tt>ClientSide</tt> property contains sub-properties, such as <tt>RequestTimeOut</tt>,
@@ -68,7 +68,7 @@ The following example demonstrates the toggling of a "loading" indicator when the client-side is making a callback request.
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code3">
<com:TClientSide PradoScripts="effects" />
<span id="callback_status">Loading...</span>
@@ -82,7 +82,7 @@ when the client-side is making a callback request. </com:TActiveButton>
</com:TTextHighlighter>
-<p>The example loads the "effects" javascript library using the
+<p id="610418" class="block-content">The example loads the "effects" javascript library using the
<a href="?page=Controls.ClientScript">TClientScript</a> component.
The <tt>ClientSide.OnLoading</tt> 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 @@ <com:TContent ID="body">
<!-- $Id$ -->
-<h1>TActiveCheckBox</h1>
+<h1 id="124029">TActiveCheckBox</h1>
<com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveCheckBox" />
-<p>
+<p id="620419" class="block-content">
<tt>TActiveCheckBox</tt> is the active control counter part to
<a href="?page=Controls.CheckBox">TCheckbox</a>. The <tt>AutoPostBack</tt>
property of <tt>TActiveCheckBox</tt> is set to true by default.
@@ -11,7 +11,7 @@ <tt>OnCallback</tt> event is raise after the <tt>OnCheckedChanged</tt> event.
</p>
- <p>
+ <p id="620420" class="block-content">
The <tt>Text</tt> and <tt>Checked</tt> properties of <tt>TActiveCheckBox</tt>
can be changed during a callback request. The <tt>TextAlign</tt> property
of <tt>TActiveCheckBox</tt> <strong>can not</strong> 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 @@ <com:TContent ID="body">
<!-- $Id: ActiveCheckBox.page 1405 2006-09-10 01:03:56Z wei $ -->
-<h1>TActiveCustomValidator</h1>
+<h1 id="126030">TActiveCustomValidator</h1>
<com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveCustomValidator" />
-<p>Performs custom validation using only server-side <tt>OnServerValidate</tt>
+<p id="630421" class="block-content">Performs custom validation using only server-side <tt>OnServerValidate</tt>
validation event. The client-side uses callbacks to raise
<tt>onServerValidate</tt> event. The <tt>ClientValidationFunction</tt> property
is disabled and will throw an exception if trying to set this property.
</p>
-<p> Beware that the <tt>onServerValidate</tt> may be
+<p id="630422" class="block-content"> Beware that the <tt>onServerValidate</tt> 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 @@ <com:TContent ID="body" >
<!-- $Id$ -->
-<h1>Active Controls (AJAX enabled Controls)</h1>
-<p>See the <a href="?page=ActiveControls.Introduction">Introduction</a>
+<h1 id="128031">Active Controls (AJAX enabled Controls)</h1>
+<p id="640423" class="block-content">See the <a href="?page=ActiveControls.Introduction">Introduction</a>
for a quick overview of the concept behind active controls (AJAX enabled controls).
Most active controls have a property of
<a href="?page=ActiveControls.BaseActiveControl">ActiveControl</a> and
@@ -13,14 +13,14 @@ during a callback request. Active controls is reliant on a collection of <a href="?page=ActiveControl.ClientSideJavascript">javascript classes</a>.
</p>
-<p>For a quick demo of active controls, try the <a href="?page=ActiveControls.ActiveButton">
+<p id="640424" class="block-content">For a quick demo of active controls, try the <a href="?page=ActiveControls.ActiveButton">
TActiveButton</a> control. See also the later part of the <a href="?page=Tutorial.CurrencyConverter">Current Converter</a> tutorial for a more indepth example.
</p>
-<p>* the tutorial for this control is not completed yet.</p>
+<p id="640425" class="block-content">* the tutorial for this control is not completed yet.</p>
-<h2>Standard Active Controls</h2>
-<ul>
+<h2 id="128032">Standard Active Controls</h2>
+<ul id="u1" class="block-content">
<li>
<a href="?page=ActiveControls.ActiveButton">TActiveButton</a>
represents a click button on a Web page. It can be used to trigger a callback request.
@@ -92,8 +92,8 @@ TActiveButton</a> control. See also the later part of the <a href="?page=Tutoria </ul>
-<h2>Active List Controls</h2>
-<ul>
+<h2 id="128033">Active List Controls</h2>
+<ul id="u2" class="block-content">
<li>
* <a href="?page=ActiveControls.ActiveCheckBoxList">TActiveCheckBoxList</a>
displays a list of checkboxes on a Web page and each checkbox
@@ -121,10 +121,10 @@ TActiveButton</a> control. See also the later part of the <a href="?page=Tutoria </li>
</ul>
-<h2>Extended Active Controls</h2>
+<h2 id="128034">Extended Active Controls</h2>
-<ul>
+<ul id="u3" class="block-content">
<li>
* <a href="?page=ActiveControls.AutoComplete">TAutoComplete</a>
extends TActiveTextBox to offer text completion suggestions.
@@ -158,8 +158,8 @@ TActiveButton</a> control. See also the later part of the <a href="?page=Tutoria </ul>
-<h2>Active Control Abilities</h2>
-<p>The following table shows the Active Controls that can trigger a
+<h2 id="128035">Active Control Abilities</h2>
+<p id="640426" class="block-content">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.</p>
<!-- tabular: align=|l|l|l|, width=(0.35 0.25 0.25) -->
@@ -307,10 +307,10 @@ if Javascript was disabled on the client's browser.</p> </tr>
</table>
-<h2>Active Control Infrastructure Classes</h2>
-<p>The following classes provide the basic infrastructure classes required to
+<h2 id="128036">Active Control Infrastructure Classes</h2>
+<p id="640427" class="block-content">The following classes provide the basic infrastructure classes required to
realize the active controls.</p>
-<ul>
+<ul id="u4" class="block-content">
<li>
* <a href="?page=ActiveControls.ActiveControlAdapter">TActiveControlAdapter</a>
tracks the viewstate values of the control and update differences of the client-side HTML
diff --git a/demos/quickstart/protected/pages/ActiveControls/Introduction.page b/demos/quickstart/protected/pages/ActiveControls/Introduction.page index 08edac33..df76bd3d 100644 --- a/demos/quickstart/protected/pages/ActiveControls/Introduction.page +++ b/demos/quickstart/protected/pages/ActiveControls/Introduction.page @@ -1,6 +1,6 @@ <com:TContent ID="body">
<!-- $Id$ -->
-<h1>Overview of Active Controls</h1>
+<h1 id="130037">Overview of Active Controls</h1>
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 @@ <com:TContent ID="body" >
<h1 id="5701">Assets</h1>
-<p>
+<p id="740577" class="block-content">
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 <tt>down.gif</tt> and <tt>up.gif</tt>, to show different toggle states. If we require the image files be stored under <tt>images</tt> 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.
</p>
-<p>
+<p id="740578" class="block-content">
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.
</p>
<h2 id="5702">Asset Publishing</h2>
-<p>
+<p id="740579" class="block-content">
PRADO provides several methods for publishing assets or directories containing assets:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li>In a template file, you can use <a href="?page=Configurations.Templates2#at">asset tags</a> to publish assets and obtain their URLs. Note, the assets must be relative to the directory containing the template file.</li>
<li>In PHP code, you can call <tt>$object->publishAsset($assetPath)</tt> to publish an asset and obtain its URL. Here, <tt>$object</tt> refers to an instance of <tt>TApplicationComponent</tt> or derived class, and <tt>$assetPath</tt> is a file or directory relative to the directory containing the class file.</li>
<li>If you want to publish an arbitrary asset, you need to call <tt>TAssetManager::publishFilePath($path)</tt>.</li>
</ul>
-<p>
+<p id="740580" class="block-content">
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.
</p>
<h2 id="5703">Customization</h2>
-<p>
+<p id="740581" class="block-content">
Asset publishing is managed by the <tt>System.Web.TAssetManager</tt> module. By default, all published asset files are stored under the <tt>[AppEntryPath]/assets</tt> directory, where <tt>AppEntryPath</tt> refers to the directory containing the application entry script. Make sure the <tt>assets</tt> directory is writable by the Web server process. You may change this directory to another by configuring the <tt>BasePath</tt> and <tt>BaseUrl</tt> properties of the <tt>TAssetManager</tt> module in application configuration,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code1">
<modules>
<module id="asset"
class="System.Web.TAssetManager"
@@ -35,18 +35,18 @@ Asset publishing is managed by the <tt>System.Web.TAssetManager</tt> module. By </com:TTextHighlighter>
<h2 id="5704">Performance</h2>
-<p>
+<p id="740582" class="block-content">
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, <tt>System.Web.TAssetManager</tt> only publishes an asset when it has a newer file modification time than the published file. When an application runs under the <tt>Performance</tt> mode, such timestamp checking is also omitted.
</p>
-<p>
+<p id="740583" class="block-content">
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.
</p>
<h2 id="5705">A Toggle Button Example</h2>
-<p>
+<p id="740584" class="block-content">
We now use the toggle button example to explain the usage of assets. The control uses two image files <tt>up.gif</tt> and <tt>down.gif</tt>, which are stored under the directory containing the control class file. When the button is in <tt>Up</tt> state, we would like to show the <tt>up.gif</tt> image. This can be done as follows,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code2">
class ToggleButton extends TWebControl {
...
protected function addAttributesToRender($writer) {
@@ -60,10 +60,10 @@ class ToggleButton extends TWebControl { ...
}
</com:TTextHighlighter>
-<p>
+<p id="740585" class="block-content">
In the above, the call <tt>$this->getAsset('up.gif')</tt> will publish the <tt>up.gif</tt> image file and return a URL for the published image file. The URL is then rendered as the <tt>src</tt> attribute of the HTML image tag.
</p>
-<p>
+<p id="740586" class="block-content">
To redistribute <tt>ToggleButton</tt>, simply pack together the class file and the image files. Users of <tt>ToggleButton</tt> merely need to unpack the file, and they can use it right away, without worrying about where to copy the image files to.
</p>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Advanced/Auth.page b/demos/quickstart/protected/pages/Advanced/Auth.page index 3373644a..45f6ea0b 100644 --- a/demos/quickstart/protected/pages/Advanced/Auth.page +++ b/demos/quickstart/protected/pages/Advanced/Auth.page @@ -1,29 +1,29 @@ <com:TContent ID="body" >
<h1 id="5501">Authentication and Authorization</h1>
-<p>
+<p id="720549" class="block-content">
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.
</p>
-<p>
+<p id="720550" class="block-content">
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.
</p>
<h2 id="5502">How PRADO Auth Framework Works</h2>
-<p>
+<p id="720551" class="block-content">
PRADO provides an extensible authentication/authorization framework. As described in <a href="?page=Fundamentals.Applications">application lifecycles</a>, <tt>TApplication</tt> reserves several lifecycles for modules responsible for authentication and authorization. PRADO provides the <tt>TAuthManager</tt> module for such purposes. Developers can plug in their own auth modules easily. <tt>TAuthManager</tt> is designed to be used together with <tt>TUserManager</tt> module, which implements a read-only user database.
</p>
-<p>
+<p id="720552" class="block-content">
When a page request occurs, <tt>TAuthManager</tt> 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, <tt>TAuthManager</tt> provides two commonly used methods: <tt>login()</tt> and <tt>logout()</tt>. A user is logged in (verified) if his username and password entries match a record in the user database managed by <tt>TUserManager</tt>. 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.
</p>
-<p>
+<p id="720553" class="block-content">
During <tt>Authorization</tt> application lifecycle, which occurs after <tt>Authentication</tt> lifecycle, <tt>TAuthManager</tt> 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, <tt>TAuthManager</tt> will redirect user browser to the login page which is specified by <tt>LoginPage</tt> property.
</p>
<h2 id="5503">Using PRADO Auth Framework</h2>
-<p>
+<p id="720554" class="block-content">
To enable PRADO auth framework, add the <tt>TAuthManager</tt> module and <tt>TUserManager</tt> module to <a href="?page=Configurations.AppConfig">application configuration</a>,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code1">
<service id="page" class="TPageService">
<modules>
<module id="auth" class="System.Security.TAuthManager"
@@ -36,13 +36,13 @@ To enable PRADO auth framework, add the <tt>TAuthManager</tt> module and <tt>TUs </modules>
</service>
</com:TTextHighlighter>
-<p>
+<p id="720555" class="block-content">
In the above, the <tt>UserManager</tt> property of <tt>TAuthManager</tt> is set to the <tt>users</tt> module which is <tt>TUserManager</tt>. Developers may replace it with a different user management module that is derived from <tt>TUserManager</tt>.
</p>
-<p>
+<p id="720556" class="block-content">
Authorization rules for pages are specified in <a href="?page=Configurations.PageConfig">page configurations</a> as follows,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code2">
<authorization>
<allow pages="PageID1,PageID2"
users="User1,User2"
@@ -52,41 +52,41 @@ Authorization rules for pages are specified in <a href="?page=Configurations.Pag verb="post" />
</authorization>
</com:TTextHighlighter>
-<p>
+<p id="720557" class="block-content">
An authorization rule can be either an <tt>allow</tt> rule or a <tt>deny</tt> rule. Each rule consists of four optional properties:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>pages</tt> - list of comma-separated page names that this rule applies to. If empty or not set, this rule will apply to all pages under the current directory and all its subdirectories recursively.</li>
<li><tt>users</tt> - list of comma-separated user names that this rule applies to. A character * refers to all users including anonymous/guest user. And a character ? refers to anonymous/guest user.</li>
<li><tt>roles</tt> - list of comma-separated user roles that this rule applies to.</li>
<li><tt>verb</tt> - page access method that this rule applies to. It can be either <tt>get</tt> or <tt>post</tt>. If empty or not set, the rule applies to both methods.</li>
</ul>
-<p>
+<p id="720558" class="block-content">
When a page request is being processed, a list of authorization rules may be available. However, only the <i>first effective</i> rule <i>matching</i> the current user will render the authorization result.
</p>
-<ul>
+<ul id="u2" class="block-content">
<li>Rules are ordered bottom-up, i.e., the rules contained in the configuration of current page folder go first. Rules in configurations of parent page folders go after.</li>
<li>A rule is effective if the current page is in the listed pages of the rule AND the current user action (<tt>get</tt> or <tt>post</tt>) is in the listed actions.</li>
<li>A rule matching occurs if the current user name is in the listed user names of an <i>effective</i> rule OR if the user's role is in the listed roles of that rule.</li>
<li>If no rule matches, the user is authorized.</li>
</ul>
-<p>
+<p id="720559" class="block-content">
In the above example, anonymous users will be denied from posting to <tt>PageID1</tt> and <tt>PageID2</tt>, while <tt>User1</tt> and <tt>User2</tt> and all users of role <tt>Role1</tt> can access the two pages (in both <tt>get</tt> and <tt>post</tt> methods).
</p>
<h2 id="5504">Using <tt>TUserManager</tt></h2>
-<p>
+<p id="720560" class="block-content">
As aforementioned, <tt>TUserManager</tt> implements a read-only user database. The user information are specified in either application configuration or an external XML file.
</p>
-<p>
+<p id="720561" class="block-content">
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,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code3">
<user name="demo" password="demo" roles="demo,admin" />
<role name="admin" users="demo,demo2" />
</com:TTextHighlighter>
-<p>
+<p id="720562" class="block-content">
where the <tt>roles</tt> attribute in <tt>user</tt> element is optional. User roles can be specified in either the <tt>user</tt> element or in a separate <tt>role</tt> element.
</p>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Advanced/Collections.page b/demos/quickstart/protected/pages/Advanced/Collections.page index 84883be4..a5b219db 100644 --- a/demos/quickstart/protected/pages/Advanced/Collections.page +++ b/demos/quickstart/protected/pages/Advanced/Collections.page @@ -1,21 +1,21 @@ <com:TContent ID="body" >
<h1 id="5501">Collections</h1>
-<p>
+<p id="710529" class="block-content">
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.
</p>
-<p>
+<p id="710530" class="block-content">
To enable object-oriented manipulation of collections, PRADO provides a set of powerful collection classes. Among them, the <tt>TList</tt> and <tt>TMap</tt> 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.
</p>
<h2 id="5502">Using <tt>TList</tt></h2>
-<p>
+<p id="710531" class="block-content">
A <tt>TList</tt> object represents a cardinal-indexed array, i.e., an array (object) with the index 0, 1, 2, ...
</p>
-<p>
+<p id="710532" class="block-content">
<tt>TList</tt> may be used like a PHP array. For example,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code1">
$list=new TList; // create a list object
...
$item=$list[$index]; // read the item at the specified index
@@ -26,14 +26,14 @@ if(isset($list[$index])) // test if the list has an item at $index foreach($list as $index=>$item) // traverse each item in the list
</com:TTextHighlighter>
-<p>
+<p id="710533" class="block-content">
To obtain the number of items in the list, use the <tt>Count</tt> property. Note, do not use <tt>count($list)</tt>, as it always returns 1.
</p>
-<p>
+<p id="710534" class="block-content">
In addition, <tt>TList</tt> implements a few commonly used convenient methods for manipulating the data in a list. These include
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>clear()</tt>: removes all items in the list.</li>
<li><tt>contains()</tt>: tests if the list contains the specified item.</li>
<li><tt>indexOf()</tt>: obtains the zero-based index of the specified item in the list.</li>
@@ -43,30 +43,30 @@ In addition, <tt>TList</tt> implements a few commonly used convenient methods fo </ul>
<h3 id="5504">Using <tt>TList</tt>-based component properties</h3>
-<p>
+<p id="710535" class="block-content">
As aforementioned, many PRADO component properties are based on <tt>TList</tt> or <tt>TList</tt>-derived collection classes. These properties all share the above usages.
</p>
-<p>
+<p id="710536" class="block-content">
For example, <tt>TControl</tt> (the base class for all PRADO controls) has a property called <tt>Controls</tt> which represents the collection of child controls. The type of <tt>Controls</tt> is <tt>TControlCollection</tt> which extends <tt>TList</tt>. Therefore, to append a new child control, we can use the following,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code2">
$control->Controls[]=$newControl;
</com:TTextHighlighter>
-<p>
+<p id="710537" class="block-content">
To traverse through the child controls, we can use,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code3">
foreach($control->Controls as $childControl) ...
</com:TTextHighlighter>
-<p>
+<p id="710538" class="block-content">
Another example is the <tt>Items</tt> property, available in list controls, <tt>TRepeater</tt>, <tt>TDataList</tt> and <tt>TDataGrid</tt>. In these controls, the ancestor class of <tt>Items</tt> is <tt>TList</tt>.
</p>
<h3 id="5505">Extending <tt>TList</tt></h3>
-<p>
+<p id="710539" class="block-content">
Often, we want to extend <tt>TList</tt> to perform additional operations for each addition or removal of an item. The only methods that the child class needs to override are <tt>insertAt()</tt> and <tt>removeAt()</tt>. For example, to ensure the list only contains items that are of <tt>TControl</tt> type, we can override <tt>insertAt()</tt> as follows,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code4">
public function insertAt($index,$item)
{
if($item instanceof TControl)
@@ -78,13 +78,13 @@ public function insertAt($index,$item) <h2 id="5503">Using <tt>TMap</tt></h2>
-<p>
+<p id="710540" class="block-content">
A <tt>TMap</tt> object represents a hash table (or we say string-indexed array).
</p>
-<p>
+<p id="710541" class="block-content">
Similar to <tt>TList</tt>, <tt>TMap</tt> may be used like an array,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code5">
$map=new TMap; // create a map object
...
$map[$key]=$value; // add a key-value pair
@@ -92,14 +92,14 @@ unset($map[$key]); // remove the value with the specified key if(isset($map[$key])) // if the map contains the key
foreach($map as $key=>$value) // traverse the items in the map
</com:TTextHighlighter>
-<p>
+<p id="710542" class="block-content">
The <tt>Count</tt> property gives the number of items in the map while the <tt>Keys</tt> property returns a list of keys used in the map.
</p>
-<p>
+<p id="710543" class="block-content">
The following methods are provided by <tt>TMap</tt> for convenience,
</p>
-<ul>
+<ul id="u2" class="block-content">
<li><tt>clear()</tt>: removes all items in the map.</li>
<li><tt>contains()</tt>: tests if the map contains the specified key.</li>
<li><tt>toArray()</tt>: returns an array representation of the items in the map.</li>
@@ -108,28 +108,28 @@ The following methods are provided by <tt>TMap</tt> for convenience, </ul>
<h3 id="5506">Using of <tt>TAttributeCollection</tt></h3>
-<p>
+<p id="710544" class="block-content">
<tt>TAttributeCollection</tt> is a special class extending from <tt>TMap</tt>. It is mainly used by the <tt>Attributes</tt> property of <tt>TControl</tt>.
</p>
Besides the normal functionalities provided by <tt>TMap</tt>, <tt>TAttributeCollection</tt> allows you to get and set collection items like getting and setting properties. For example,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code6">
$collection->Label='value'; // equivalent to: $collection['Label']='value';
echo $collection->Label; // equivalent to: echo $collection['Label'];
</com:TTextHighlighter>
-<p>
+<p id="710545" class="block-content">
Note, in the above <tt>$collection</tt> does NOT have a <tt>Label</tt> property.
</p>
-<p>
+<p id="710546" class="block-content">
Unlike <tt>TMap</tt>, keys in <tt>TAttributeCollection</tt> are case-insensitive. Therefore, <tt>$collection->Label</tt> is equivalent to <tt>$collection->LABEL</tt>.
</p>
-<p>
+<p id="710547" class="block-content">
Because of the above new features, when dealing with the <tt>Attributes</tt> property of controls, we may take advantage of the subproperty concept and configure control attribute values in a template as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code7">
<com:TButton Attributes.onclick="if(!confirm('Are you sure?')) return false;" .../>
</com:TTextHighlighter>
-<p>
+<p id="710548" class="block-content">
which adds an attribute named <tt>onclick</tt> to the <tt>TButton</tt> control.
</p>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Advanced/Error.page b/demos/quickstart/protected/pages/Advanced/Error.page index 9d2cf9ec..97d3a602 100644 --- a/demos/quickstart/protected/pages/Advanced/Error.page +++ b/demos/quickstart/protected/pages/Advanced/Error.page @@ -1,21 +1,21 @@ <com:TContent ID="body" >
<h1 id="6301">Error Handling and Reporting</h1>
-<p>
+<p id="800666" class="block-content">
PRADO provides a complete error handling and reporting framework based on the PHP 5 exception mechanism.
</p>
<h2 id="6302">Exception Classes</h2>
-<p>
+<p id="800667" class="block-content">
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.
</p>
-<p>
+<p id="800668" class="block-content">
All errors in PRADO applications are represented as exceptions. The base class for all PRADO exceptions is <tt>TException</tt>. 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.
</p>
-<p>
+<p id="800669" class="block-content">
Exceptions raised due to improper usage of the PRADO framework inherit from <tt>TSystemException</tt>, which can be one of the following exception classes:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>TConfigurationException</tt> - improper configuration, such as error in application configuration, control templates, etc.</li>
<li><tt>TInvalidDataValueException</tt> - data value is incorrect or unexpected.</li>
<li><tt>TInvalidDataTypeException</tt> - data type is incorrect or unexpected.</li>
@@ -28,46 +28,46 @@ Exceptions raised due to improper usage of the PRADO framework inherit from <tt> <li><tt>TNotSupportedException</tt> - errors caused by requesting for unsupported feature.</li>
<li><tt>THttpException</tt> - errors to be displayed to Web client users.</li>
</ul>
-<p>
+<p id="800670" class="block-content">
Errors due to improper usage of the Web application by client users inherit from <tt>TApplicationException</tt>.
</p>
<h2 id="6303">Raising Exceptions</h2>
-<p>
+<p id="800671" class="block-content">
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 <tt>THttpException</tt>, while exceptions shown to developers should use other exception classes.
</p>
<h2 id="6304">Error Capturing and Reporting</h2>
-<p>
+<p id="800672" class="block-content">
Exceptions raised during the runtime of PRADO applications are captured by <tt>System.Exceptions.TErrorHandler</tt> module. Different output templates are used to display the captured exceptions. <tt>THttpException</tt> 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.
</p>
<a href="<%~ exception2.gif %>" target="_blank"><img src="<%~ exception.gif %>" alt="exception page" style="border:0px"/></a>
<h2 id="6305">Customizing Error Display</h2>
-<p>
+<p id="800673" class="block-content">
Developers can customize the presentation of exception messages. By default, all error output templates are stored under <tt>framework/Exceptions/templates</tt>. The location can be changed by configuring <tt>TErrorHandler</tt> in application configuration,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_800226">
<module id="error"
class="TErrorHandler"
ErrorTemplatePath="Application.ErrorTemplates" />
</com:TTextHighlighter>
-<p>
+<p id="800674" class="block-content">
<tt>THttpException</tt> uses a set of templates that are differentiated according to different <tt>StatusCode</tt> property value of <tt>THttpException</tt>. <tt>StatusCode</tt> 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 <tt>StatusCode</tt> value is used to select which output template to use. The output template files use the following naming convention:
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_800227">
error<status code>-<language code>.html
</com:TTextHighlighter>
-<p>
+<p id="800675" class="block-content">
where <tt>status code</tt> refers to the <tt>StatusCode</tt> property value of <tt>THttpException</tt>, and <tt>language code</tt> must be a valid language such as <tt>en</tt>, <tt>zh</tt>, <tt>fr</tt>, etc. When a <tt>THttpException</tt> 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.
</p>
-<p>
+<p id="800676" class="block-content">
The naming convention for the template files used for all other exceptions is as follows,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_800228">
exception-<language code>.html
</com:TTextHighlighter>
-<p>
+<p id="800677" class="block-content">
Again, if the preferred language is not found, PRADO will try to use <tt>exception.html</tt>, instead.
</p>
<div class="note">
diff --git a/demos/quickstart/protected/pages/Advanced/I18N.page b/demos/quickstart/protected/pages/Advanced/I18N.page index 9c3d620f..091c0b0a 100644 --- a/demos/quickstart/protected/pages/Advanced/I18N.page +++ b/demos/quickstart/protected/pages/Advanced/I18N.page @@ -1,14 +1,14 @@ <com:TContent ID="body" >
<h1 id="6201">Internationalization (I18N) and Localization (L10N)</h1>
-<p>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.</p>
+<p id="790625" class="block-content">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.</p>
<h2 id="6203">Separate culture/locale sensitive data</h2>
-<p>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
+<p id="790626" class="block-content">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
</p>
-<ul>
+<ul id="u1" class="block-content">
<li> Strings, Messages, Text, in relatively small units (e.g. phrases, sentences, paragraphs, but not the full text of a book).</li>
<li> Labels on buttons.</li>
<li> Help files, large units of text, static text.</li>
@@ -23,20 +23,20 @@ <li> Page layout.</li>
</ul>
-<p>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).</p>
+<p id="790627" class="block-content">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).</p>
<h2 id="6204">Configuration</h2>
-<p>To enable the localization features in PRADO, you need to add a few configuration options in your <a href="?page=Configurations.AppConfig">application configuration</a>.
+<p id="790628" class="block-content">To enable the localization features in PRADO, you need to add a few configuration options in your <a href="?page=Configurations.AppConfig">application configuration</a>.
First you need to include the <tt>System.I18N.*</tt> namespace to your paths.
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_790203">
<paths>
<using namespace="System.I18N.*" />
</paths>
</com:TTextHighlighter>
-<p>Then, if you wish to translate some text in your application, you need to add one translation message data source.</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<p id="790629" class="block-content">Then, if you wish to translate some text in your application, you need to add one translation message data source.</p>
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_790204">
<module id="globalization" class="TGlobalization">
<translation type="XLIFF"
source="MyApp.messages"
@@ -45,19 +45,19 @@ First you need to include the <tt>System.I18N.*</tt> namespace to your paths. </module>
</com:TTextHighlighter>
-<p>Where <tt>source</tt> in <tt>translation</tt> is the dot path to a directory
+<p id="790630" class="block-content">Where <tt>source</tt> in <tt>translation</tt> is the dot path to a directory
where you are going to store your translate message catalogue. The <tt>autosave</tt>
attribute if enabled, saves untranslated messages back into the message catalogue.
With <tt>cache</tt> enabled, translated messages are saved in the application <tt>runtime/i18n</tt> directory.
The <tt>marker</tt> value is used to surround any untranslated text.
</p>
-<p>With the configuration complete, we can now start to localize your application. If you have <tt>autosave</tt> enabled, after running your application with some localization activity (i.e. translating some text), you will see a directory and a <tt>messages.xml</tt> created within your <tt>source</tt> directory.</p>
+<p id="790631" class="block-content">With the configuration complete, we can now start to localize your application. If you have <tt>autosave</tt> enabled, after running your application with some localization activity (i.e. translating some text), you will see a directory and a <tt>messages.xml</tt> created within your <tt>source</tt> directory.</p>
<h2 id="6205">What to do with <tt>messages.xml</tt>?</h2>
-<p>The translation message catalogue file, if using <tt>type="XLIFF"</tt>, 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.</p>
+<p id="790632" class="block-content">The translation message catalogue file, if using <tt>type="XLIFF"</tt>, 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.</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_790205">
<?xml version="1.0"?>
<xliff version="1.0">
<file original="I18N Example IndexPage"
@@ -80,23 +80,23 @@ Each translation message is wrapped within a <tt>trans-unit</tt> tag, where <tt> <h2 id="6206">Setting and Changing Culture</h2>
-<p>Once globalization is enabled, you can access the globalization settings, such as, <tt>Culture</tt>, <tt>Charset</tt>, etc, using </p>
-<com:TTextHighlighter CssClass="source">
+<p id="790633" class="block-content">Once globalization is enabled, you can access the globalization settings, such as, <tt>Culture</tt>, <tt>Charset</tt>, etc, using </p>
+<com:TTextHighlighter CssClass="source block-content" id="code_790206">
$globalization = $this->getApplication()->getGlobalization();
echo $globalization->Culture;
$globalization->Charset= "GB-2312"; //change the charset
</com:TTextHighlighter>
-<p>You also change the way the culture is determined by changing the <tt>class</tt> attribute in the module configuration. For example, to set the culture that depends on the browser settings, you can use the <tt>TGlobalizationAutoDetect</tt> class.
-<com:TTextHighlighter Language="xml" CssClass="source">
+<p id="790634" class="block-content">You also change the way the culture is determined by changing the <tt>class</tt> attribute in the module configuration. For example, to set the culture that depends on the browser settings, you can use the <tt>TGlobalizationAutoDetect</tt> class.
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_790207">
<module id="globalization" class="TGlobalizationAutoDetect">
...
</module>
</com:TTextHighlighter>
-<p>You may also provide your own globalization class to change how the application culture is set.
+<p id="790635" class="block-content">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 <a href="?page=Configurations.Templates1#tct">template control tags</a>. For example, changing the <tt>Culture</tt> to "zh".</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790208">
<%@ Application.Globalization.Culture="zh" %>
</com:TTextHighlighter>
@@ -104,16 +104,16 @@ Lastly, you can change the globalization settings on page by page basis using <a There are two areas in your application that may need message or string localization, in PHP code and in the templates. To localize strings within PHP, use the <tt>localize</tt> function detailed below. To localize text in the template, use the <a href="#ttranslate">TTranslate</a> component.
<h2 id="6208">Using <tt>localize</tt> function to translate text within PHP</h2>
-<p>The <tt>localize</tt> 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 <tt>$sender</tt> (assuming, say, the sender is a button). The original code before localization is as follows.
-<com:TTextHighlighter CssClass="source">
+<p id="790636" class="block-content">The <tt>localize</tt> 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 <tt>$sender</tt> (assuming, say, the sender is a button). The original code before localization is as follows.
+<com:TTextHighlighter CssClass="source block-content" id="code_790209">
function clickMe($sender,$param)
{
$sender->Text="Hello, world!";
}
</com:TTextHighlighter>
-<p>The hard coded message "Hello, world!" is to be localized using the <tt>localize</tt> function. </p>
-<com:TTextHighlighter CssClass="source">
+<p id="790637" class="block-content">The hard coded message "Hello, world!" is to be localized using the <tt>localize</tt> function. </p>
+<com:TTextHighlighter CssClass="source block-content" id="code_790210">
function clickMe($sender,$param)
{
$sender->Text=Prado::localize("Hello, world!");
@@ -122,60 +122,60 @@ function clickMe($sender,$param) <h2 id="6209">Compound Messages</h2>
-<p>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.</p>
-<com:TTextHighlighter CssClass="source">
+<p id="790638" class="block-content">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.</p>
+<com:TTextHighlighter CssClass="source block-content" id="code_790211">
$num_users = 12;
$message = "There are " . $num_users . " users online.";
</com:TTextHighlighter>
This problem can be solved using the <tt>localize</tt> function with string substitution. For example, the <tt>$message</tt> string above can be constructed as follows.
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_790212">
$num_users = 12;
$message = Prado::localize("There are {num_users} users online.", array('num_users'=>$num_users));
</com:TTextHighlighter>
-<p>Where the second parameter in <tt>localize</tt> takes an associative array with the key as the substitution to find in the text and replaced it with the associated value.
+<p id="790639" class="block-content">Where the second parameter in <tt>localize</tt> takes an associative array with the key as the substitution to find in the text and replaced it with the associated value.
The <tt>localize</tt> function does not solve the problem of localizing languages that have plural forms, the solution is to use <a href="#choice-format">TChoiceFormat</a>.</p>
-<p>The following sample demonstrates the basics of localization in PRADO.</p>
+<p id="790640" class="block-content">The following sample demonstrates the basics of localization in PRADO.</p>
<com:RunBar PagePath="Advanced.Samples.I18N.Home" />
<h1 id="6202">I18N Components</h1>
<a name="ttranslate"></a>
<h2 id="6210">TTranslate</h2>
-<p>Messages and strings can be localized in PHP or in templates.
+<p id="790641" class="block-content">Messages and strings can be localized in PHP or in templates.
To translate a message or string in the template, use <tt>TTranslate</tt>.</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790213">
<com:TTranslate>Hello World</com:TTranslate>
<com:TTranslate Text="Goodbye" />
</com:TTextHighlighter>
-<p><tt>TTranslate</tt> can also perform string substitution.
+<p id="790642" class="block-content"><tt>TTranslate</tt> can also perform string substitution.
The <tt>Parameters</tt> 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 "<tt>Parameters.time=<%= time() %></tt>".
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790214">
<com:TTranslate Parameters.time=<%= time() %> >
The time is {time}.
</com:TTranslate>
</com:TTextHighlighter>
-<p>A short for <tt>TTranslate</tt> is also provided using the following syntax.</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<p id="790643" class="block-content">A short for <tt>TTranslate</tt> is also provided using the following syntax.</p>
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790215">
<%[string]%>
</com:TTextHighlighter>
-<p>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.</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<p id="790644" class="block-content">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.</p>
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790216">
<com:TLabel Text="<%[ Hello World! ]%>" />
</com:TTextHighlighter>
<h2 id="6211">TDateFormat</h2>
-<p>Formatting localized date and time is straight forward.</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<p id="790645" class="block-content">Formatting localized date and time is straight forward.</p>
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790217">
<com:TDateFormat Value="12/01/2005" />
</com:TTextHighlighter>
-<p>The <tt>Pattern</tt> property accepts 4 predefined localized date patterns and 4 predefined localized time patterns.
-<ul>
+<p id="790646" class="block-content">The <tt>Pattern</tt> property accepts 4 predefined localized date patterns and 4 predefined localized time patterns.</p>
+<ul id="u2" class="block-content">
<li><tt>fulldate</tt></li>
<li><tt>longdate</tt></li>
<li><tt>mediumdate</tt></li>
@@ -185,19 +185,20 @@ The time is {time}. <li><tt>mediumtime</tt></li>
<li><tt>shorttime</tt></li>
</ul>
+<p id="p1" class="block-content">
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 <tt>Culture</tt> property.</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790218">
<com:TDateFormat Pattern="fulldate shorttime" />
</com:TTextHighlighter>
-<p>You can also specify a custom pattern using the following sub-patterns.
+<p id="790647" class="block-content">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:
-<com:TTextHighlighter Language="text" CssClass="source">
+<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_790219">
Symbol Meaning Presentation Example
------ ------- ------------ -------
G era designator (Text) AD
@@ -222,29 +223,29 @@ The date/time format is specified by means of a string time pattern. In this pat </com:TTextHighlighter>
</p>
-<p>The count of pattern letters determine the format.</p>
+<p id="790648" class="block-content">The count of pattern letters determine the format.</p>
-<p>(Text): 4 letters uses full form, less than 4, use short or abbreviated form
+<p id="790649" class="block-content">(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")</p>
-<p>(Number): the minimum number of digits. Shorter numbers are zero-padded
+<p id="790650" class="block-content">(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.</p>
-<p>(Text and Number): 3 or over, use text, otherwise use number. (e.g.,
+<p id="790651" class="block-content">(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".)</p>
-<p>Any characters in the pattern that are not in the ranges of ['a'..'z']
+<p id="790652" class="block-content">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.</p>
-<p>Examples using the US locale:
+<p id="790653" class="block-content">Examples using the US locale:
-<com:TTextHighlighter Language="text" CssClass="source">
+<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_790220">
Format Pattern Result
-------------- -------
"yyyy.MM.dd G 'at' HH:mm:ss" ->> 1996.07.10 AD at 15:08:56
@@ -256,54 +257,55 @@ Format Pattern Result </com:TTextHighlighter>
</p>
-<p>If the <tt>Value</tt> property is not specified, the current date and time is used.</p>
+<p id="790654" class="block-content">If the <tt>Value</tt> property is not specified, the current date and time is used.</p>
<h2 id="6212">TNumberFormat</h2>
-<p>PRADO's Internationalization framework provide localized currency formatting and number formatting. Please note that the <tt>TNumberFormat</tt> component provides formatting only, it does not perform current conversion or exchange.</p>
+<p id="790655" class="block-content">PRADO's Internationalization framework provide localized currency formatting and number formatting. Please note that the <tt>TNumberFormat</tt> component provides formatting only, it does not perform current conversion or exchange.</p>
-<p>Numbers can be formatted as currency, percentage, decimal or scientific
-numbers by specifying the <tt>Type</tt> attribute. The valid types are:
-<ul>
+<p id="790656" class="block-content">Numbers can be formatted as currency, percentage, decimal or scientific
+numbers by specifying the <tt>Type</tt> attribute. The valid types are:</p>
+<ul id="u3" class="block-content">
<li><tt>currency</tt></li>
<li><tt>percentage</tt></li>
<li><tt>decimal</tt></li>
<li><tt>scientific</tt></li>
</ul>
-</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790221">
<com:TNumberFormat Type="currency" Value="100" />
</com:TTextHighlighter>
-<p><tt>Culture</tt> and <tt>Currency</tt> properties may be specified to format locale specific numbers. </p>
+<p id="790657" class="block-content"><tt>Culture</tt> and <tt>Currency</tt> properties may be specified to format locale specific numbers. </p>
-<p>If someone from US want to see sales figures from a store in
+<p id="790658" class="block-content">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 <tt>Culture="de_DE"</tt> to get
the currency right, e.g. 100,00$. The decimal and grouping separator is
then also from the <tt>de_DE</tt> locale. This may lead to some confusion because
people from US uses the "," (comma) as thousand separator. Therefore a <tt>Currency</tt>
attribute is available, so that the output from the following example results in $100.00
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790222">
<com:TNumberFormat Type="currency"
Culture="en_US" Currency="EUR" Value="100" />
</com:TTextHighlighter>
</p>
-<p>The <tt>Pattern</tt> property determines the number of digits, thousand grouping
+<p id="790659" class="block-content">The <tt>Pattern</tt> 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 <tt>Culture</tt> property. The valid
-<tt>Pattern</tt> characters are:
-<ul>
+<tt>Pattern</tt> characters are:</p>
+<ul id="u6" class="block-content">
<li><tt># (hash)</tt> - represents the optional digits</li>
<li><tt>0 (zero)</tt> - represents the mandatory digits, zero left filled</li>
<li><tt>. (full stop)</tt> - the position of the decimal point (only 1 decimal point is allowed)</li>
<li><tt>, (comma)</tt> - thousand point separation (up to 2 commas are allowed)</li>
</ul>
+<p id="p2" class="block-content">
For example, consider the <tt>Value="1234567.12345"</tt> and
with <tt>Culture="en_US"</tt> (which uses "," for thousand point separator and "." for decimal separators).
-<com:TTextHighlighter Language="text" CssClass="source">
+</p>
+<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_790223">
Pattern Output
------- ------
##,###.00 ->> 1,234,567.12
@@ -315,11 +317,11 @@ Pattern Output </p>
<h2 id="6213">TTranslateParameter</h2>
-<p>Compound messages, i.e., string substitution, can be accomplished with <tt>TTranslateParameter</tt>.
+<p id="790660" class="block-content">Compound messages, i.e., string substitution, can be accomplished with <tt>TTranslateParameter</tt>.
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 <tt>TTranslate</tt>.
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790224">
<com:TTranslate>
{greeting} {name}!
<com:TTranslateParameter Key="name">World</com:TTranslateParameter>
@@ -331,19 +333,19 @@ with the values of "Hello" and "World", respectively.The substitution string mus <a name="choice-format"></a>
<h2 id="6214">TChoiceFormat</h2>
-<p>Using the <tt>localize</tt> function or <tt>TTranslate</tt> 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 <tt>number</tt> of apples.</p>
+<p id="790661" class="block-content">Using the <tt>localize</tt> function or <tt>TTranslate</tt> 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 <tt>number</tt> of apples.</p>
-<p>The <tt>TChoiceFormat</tt> component performs message/string choice translation. The following example demonstrated a simple 2 choice message translation.</p>
+<p id="790662" class="block-content">The <tt>TChoiceFormat</tt> component performs message/string choice translation. The following example demonstrated a simple 2 choice message translation.</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790225">
<com:TChoiceFormat Value="1"/>[1] One Apple. |[2] Two Apples</com:TChoiceFormat>
</com:TTextHighlighter>
-<p>In the above example, the <tt>Value</tt> "1" (one), thus the translated string
+<p id="790663" class="block-content">In the above example, the <tt>Value</tt> "1" (one), thus the translated string
is "One Apple". If the <tt>Value</tt> was "2", then it will show "Two Apples".</p>
-<p>The message/string choices are separated by the pipe "|" followed by a set notation of the form.</p>
-<ul>
+<p id="790664" class="block-content">The message/string choices are separated by the pipe "|" followed by a set notation of the form.</p>
+<ul id="u7" class="block-content">
<li><tt>[1,2]</tt> -- accepts values between 1 and 2, inclusive.</li>
<li><tt>(1,2)</tt> -- accepts values between 1 and 2, excluding 1 and 2.</li>
<li><tt>{1,2,3,4}</tt> -- only values defined in the set are accepted.</li>
@@ -351,7 +353,7 @@ is "One Apple". If the <tt>Value</tt> was "2", then it will show "Two Apples".</ and strictly less than 0</li>
</ul>
-<p>Any non-empty combinations of the delimiters of square and round brackets are acceptable.
+<p id="790665" class="block-content">Any non-empty combinations of the delimiters of square and round brackets are acceptable.
The string chosen for display depends on the <tt>Value</tt> property. The <tt>Value</tt> is evaluated for each set until the <tt>Value</tt> is found to belong to a particular set.</p>
diff --git a/demos/quickstart/protected/pages/Advanced/Logging.page b/demos/quickstart/protected/pages/Advanced/Logging.page index 9c7ec15e..d5a13da2 100644 --- a/demos/quickstart/protected/pages/Advanced/Logging.page +++ b/demos/quickstart/protected/pages/Advanced/Logging.page @@ -1,36 +1,36 @@ <com:TContent ID="body" >
<h1 id="6101">Logging</h1>
-<p>
+<p id="780615" class="block-content">
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,
</p>
<img src="<%~ logrouter.gif %>" alt="Log router" />
<h2 id="6102">Using Logging Functions</h2>
-<p>
+<p id="780616" class="block-content">
The following two methods are provided for logging messages in PRADO,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_780201">
Prado::log($message, $logLevel, $category);
Prado::trace($message, $category);
</com:TTextHighlighter>
-<p>
+<p id="780617" class="block-content">
The difference between <tt>Prado::log()</tt> and <tt>Prado::trace()</tt> is that the latter automatically selects the log level according to the application mode. If the application is in <tt>Debug</tt> mode, stack trace information is appended to the messages. <tt>Prado::trace()</tt> is widely used in the core code of the PRADO framework.
</p>
<h2 id="6103">Message Routing</h2>
-<p>
+<p id="780618" class="block-content">
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 <tt>System.Util.TLogRouter</tt> module. When plugged into an application, it can route the messages to different destination in parallel. Currently, PRADO provides three types of routes:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>TFileLogRoute</tt> - filtered messages are stored in a specified log file. By default, this file is named <tt>prado.log</tt> under the runtime directory of the application. File rotation is provided.</li>
<li><tt>TEmailLogRoute</tt> - filtered messages are sent to pre-specified email addresses.</li>
<li><tt>TBrowserLogRoute</tt> - filtered messages are appended to the end of the current page output.</li>
</ul>
-<p>
+<p id="780619" class="block-content">
To enable message routing, plug in and configure the <tt>TLogRouter</tt> module in application configuration,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_780202">
<module id="log" class="System.Util.TLogRouter">
<route class="TBrowserLogRoute"
Levels="Info"
@@ -40,21 +40,21 @@ To enable message routing, plug in and configure the <tt>TLogRouter</tt> module Categories="System.Web" />
</module>
</com:TTextHighlighter>
-<p>
+<p id="780620" class="block-content">
In the above, the <tt>Levels</tt> and <tt>Categories</tt> specify the log and category filters to selectively retrieve the messages to the corresponding destinations.
</p>
<h2 id="6104">Message Filtering</h2>
-<p>
+<p id="780621" class="block-content">
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.
</p>
-<p>
+<p id="780622" class="block-content">
Log levels defined in <tt>System.Util.TLogger</tt> include : <tt>DEBUG</tt>, <tt>INFO</tt>, <tt>NOTICE</tt>, <tt>WARNING</tt>, <tt>ERROR</tt>, <tt>ALERT</tt>, <tt>FATAL</tt>. Messages can be filtered according log level criteria. For example, if a filter specifies <tt>WARNING</tt> and <tt>ERROR</tt> levels, then only those messages that are of <tt>WARNING</tt> and <tt>ERROR</tt> will be returned.
</p>
-<p>
+<p id="780623" class="block-content">
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, <tt>System.Web</tt> category is the ancestor of <tt>System.Web.UI</tt> and <tt>System.Web.UI.WebControls</tt> categories. Messages can be selectively retrieved using such hierarchical category filters. For example, if the category filter is <tt>System.Web</tt>, then all messages in the <tt>System.Web</tt> are returned. In addition, messages in the child categories, such as <tt>System.Web.UI.WebControls</tt>, are also returned.
</p>
-<p>
+<p id="780624" class="block-content">
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 <tt>TPage</tt> will be of category <tt>System.Web.UI.TPage</tt>.
</p>
diff --git a/demos/quickstart/protected/pages/Advanced/MasterContent.page b/demos/quickstart/protected/pages/Advanced/MasterContent.page index b0836393..ee99b144 100644 --- a/demos/quickstart/protected/pages/Advanced/MasterContent.page +++ b/demos/quickstart/protected/pages/Advanced/MasterContent.page @@ -1,16 +1,16 @@ <com:TContent ID="body" >
<h1 id="5801">Master and Content</h1>
-<p>
+<p id="750587" class="block-content">
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.
</p>
-<p>
+<p id="750588" class="block-content">
Master and content only apply to template controls (controls extending <tt>TTemplateControl</tt> or its child classes). A template control can have at most one master control and one or several contents (each represented by a <tt>TContent</tt> control). Contents will be inserted into the master control at places reserved by <tt>TContentPlaceHolder</tt> controls. And the presentation of the template control is that of the master control with <tt>TContentPlaceHolder</tt> replaced by <tt>TContent</tt>.
</p>
-<p>
+<p id="750589" class="block-content">
For example, assume a template control has the following template:
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_750192">
<%@ MasterClass="MasterControl" %>
<com:TContent ID="A" >
content A
@@ -22,10 +22,10 @@ content B content B
</com:TContent >
</com:TTextHighlighter>
-<p>
+<p id="750590" class="block-content">
which uses <tt>MasterControl</tt> as its master control. The master control has the following template,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_750193">
other stuff
<com:TContentPlaceHolder ID="A" />
other stuff
@@ -34,23 +34,23 @@ other stuff <com:TContentPlaceHolder ID="C" />
other stuff
</com:TTextHighlighter>
-<p>
+<p id="750591" class="block-content">
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.
</p>
<img src=<%~ mastercontent.gif %> alt="Master and Content" />
<img src=<%~ pcrelation.gif %> alt="Parent-child relationship between master and content" />
<h2 id="6301">Master vs. External Template</h2>
-<p>
+<p id="750592" class="block-content">
Master is very similar to external templates which are introduced since version 3.0.5. A special <a href="?page=Configurations.Templates1">include tag</a> is used to include an external template file into a base template.
</p>
-<p>
+<p id="750593" class="block-content">
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.
</p>
-<p>
+<p id="750594" class="block-content">
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.
</p>
-<p>
+<p id="750595" class="block-content">
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.
</p>
diff --git a/demos/quickstart/protected/pages/Advanced/Performance.page b/demos/quickstart/protected/pages/Advanced/Performance.page index d33c110b..18465fca 100644 --- a/demos/quickstart/protected/pages/Advanced/Performance.page +++ b/demos/quickstart/protected/pages/Advanced/Performance.page @@ -1,27 +1,27 @@ <com:TContent ID="body" >
<h1 id="6401">Performance Tuning</h1>
-<p>
+<p id="810678" class="block-content">
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.
</p>
<h2 id="6402">Caching</h2>
-<p>
+<p id="810679" class="block-content">
PRADO provides a generic caching technique used by in several core parts of the framework. For example, when caching is enabled, <tt>TTemplateManager</tt> will save parsed templates in cache and reuse them in the following requests, which saves time for parsing templates. The <tt>TThemeManager</tt> adopts the similar strategy to deal with theme parsing.
</p>
-<p>
+<p id="810680" class="block-content">
Enabling caching is very easy. Simply add the cache module in the application configuration, and PRADO takes care of the rest.
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_810229">
<modules>
<module id="cache" class="System.Caching.TSqliteCache" />
</modules>
</com:TTextHighlighter>
-<p>
+<p id="810681" class="block-content">
Developers can also take advantage of the caching technique in their applications. The <tt>Cache</tt> property of <tt>TApplication</tt> returns the plugged-in cache module when it is available. To save and retrieve a data item in cache, use the following commands,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_810230">
if($application->Cache) {
// saves data item in cache
$application->Cache->set($keyName,$dataItem);
@@ -29,55 +29,55 @@ if($application->Cache) { $dataItem=$application->Cache->get($keyName);
}
</com:TTextHighlighter>
-<p>
+<p id="810682" class="block-content">
where <tt>$keyName</tt> should be a string that uniquely identifies the data item stored in cache.
</p>
<h2 id="6403">Using <tt>pradolite.php</tt></h2>
-<p>
+<p id="810683" class="block-content">
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 <tt>pradolite.php</tt> is also included. The file is a merge of all core PRADO class files with comments being stripped off and message logging removed.
</p>
-<p>
+<p id="810684" class="block-content">
To use <tt>pradolite.php</tt>, in your application entry script, replace the inclusion of <tt>prado.php</tt> with <tt>pradolite.php</tt>.
</p>
<h2 id="6404">Changing Application Mode</h2>
-<p>
+<p id="810685" class="block-content">
Application mode also affects application performance. A PRADO application can be in one of the following modes: <tt>Off</tt>, <tt>Debug</tt>, <tt>Normal</tt> and <tt>Performance</tt>. The <tt>Debug</tt> mode should mainly be used during application development, while <tt>Normal</tt> 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 <tt>Performance</tt> to further improve the performance.
</p>
-<p>
+<p id="810686" class="block-content">
The difference between <tt>Debug</tt>, <tt>Normal</tt> and <tt>Performance</tt> modes is that under <tt>Debug</tt> mode, application logs will contain debug information, and under <tt>Performance</tt> mode, timestamp checking is not performed for cached templates and published assets. Therefore, under <tt>Performance</tt> mode, application may not run properly if templates or assets are modified. Since <tt>Performance</tt> mode is mainly used when an application is stable, change of templates or assets are not likely.
</p>
-<p>
+<p id="810687" class="block-content">
To switch application mode, configure it in application configuration:
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_810231">
<application Mode="Performance" >
......
</application >
</com:TTextHighlighter>
<h2 id="6405">Reducing Page Size</h2>
-<p>
+<p id="810688" class="block-content">
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 <tt>TDataGrid</tt>, is used. To reduce the size of the network transmitted page size, two strategies can be used.
</p>
-<p>
+<p id="810689" class="block-content">
First, you may disable viewstate by setting <tt>EnableViewState</tt> 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.
</p>
-<p>
+<p id="810690" class="block-content">
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 <tt>StatePersisterClass</tt> property of the page determines which state persistence class to use. By default, it uses <tt>System.Web.UI.TPageStatePersister</tt> 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 <tt>IPageStatePersister</tt> interface. You may configure this property in several places, such as application configuration or page configuration using <pages> or <page> tags,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_810232">
<pages StatePersisterClass="MyPersister1" ... >
<page ID="SpecialPage" StatePersisterClass="MyPersister2" ... />
</pages>
</com:TTextHighlighter>
-<p>
+<p id="810691" class="block-content">
Note, in the above the <tt>SpecialPage</tt> will use <tt>MyPersister2</tt> as its persister class, while the rest pages will use <tt>MyPersister1</tt>. Therefore, you can have different state persister strategies for different pages.
</p>
<h2 id="6406">Other Techniques</h2>
-<p>
+<p id="810692" class="block-content">
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.
</p>
diff --git a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.de.page b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.de.page index 159c5d54..343df6d6 100644 --- a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.de.page +++ b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.de.page @@ -25,7 +25,7 @@ Weiter mit dem Thema kulturell angepasster Templates. Text kann unter Zuhilfenah <dd>Nachfolgender Prozess der Übersetzung und Anpassung eines Produktes an die kulturellen Konventionen eines gegebenen Marktes.</dd>
</dl>
<p> Die folgenden Merkmale werden von PRADO unterstützt: </p>
-<ul>
+<ul id="u1" class="block-content">
<li>Textübersetzung </li>
<li>Attributübersetzung (noch zu implementieren) </li>
<li>Parameteraustausch (falls erforderlich mit Übersetzung) </li>
diff --git a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.es.page b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.es.page index 31e7de07..b682a0e9 100644 --- a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.es.page +++ b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.es.page @@ -25,7 +25,7 @@ <dd> Proceso subsecuente de traducir y de adaptar un producto a las convenciones culturales de un mercado dado. </dd>
</dl>
<p> Las características siguientes son utilizadas por PRADO: </p>
-<ul>
+<ul id="u1" class="block-content">
<li>Traducción del texto </li>
<li>Traducción del atributo (todo) </li>
<li>Substitución de parámetro (con la traducción si es necesario) </li>
diff --git a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.fr.page b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.fr.page index 66d01c90..09def8f5 100644 --- a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.fr.page +++ b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.fr.page @@ -45,7 +45,7 @@ <p>
PRADO offrent les fonctionnalités suivantes :
</p>
- <ul>
+ <ul id="u1" class="block-content">
<li>
Traduction de contenu
<li>
diff --git a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.page b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.page index 466bbca8..40dbe591 100644 --- a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.page +++ b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.page @@ -26,7 +26,7 @@ Your current culture is <%= $this->Page->CurrentCulture %>. <dd>Subsequent process of translating and adapting a product to a given market's cultural conventions.</dd>
</dl>
<p>The following features are supported by PRADO: </p>
-<ul>
+<ul id="u1" class="block-content">
<li>Text translation</li>
<li>Attribute translation</li>
<li>Parameter substitution (with translation if needed) </li>
diff --git a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.pl.page b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.pl.page index 61882fee..7a30aac3 100644 --- a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.pl.page +++ b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.pl.page @@ -25,7 +25,7 @@ Twoim obecnym językiem jest: <%= $this->Page->CurrentCulture %>. <dd> To kolejny etap, jest to proces tłumaczenia i dostosowywania produktu do konkretnych wymagań językowo-kulturowych.</dd>
</dl>
<p>PRADO obsługuje następujące mechanizmy: </p>
-<ul>
+<ul id="u1" class="block-content">
<li>Tłumaczenie tekstu </li>
<li>Tłumaczenie atrybutów (todo) </li>
<li>Podstawianie parametrów (wraz z koniecznym tłumaczeniem) </li>
diff --git a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.zh.page b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.zh.page index 959f0b8e..c6858a3e 100644 --- a/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.zh.page +++ b/demos/quickstart/protected/pages/Advanced/Samples/I18N/Home.zh.page @@ -31,7 +31,7 @@ PRADO提供了gettext,XML,SQLite以及MySQL等手段用于存放消息的各 <dd>国际化的一个细节步骤,它针对某个特定的市场文化对产品进行翻译和调整。</dd>
</dl>
<p>PRADO支持以下功能:</p>
-<ul>
+<ul id="u1" class="block-content">
<li>文本翻译</li>
<li>属性翻译(尚未完成)</li>
<li>参数替换(如需要可进行翻译)</li>
diff --git a/demos/quickstart/protected/pages/Advanced/Samples/I18N/zh_TW/Home.page b/demos/quickstart/protected/pages/Advanced/Samples/I18N/zh_TW/Home.page index 329a7669..d9129c14 100644 --- a/demos/quickstart/protected/pages/Advanced/Samples/I18N/zh_TW/Home.page +++ b/demos/quickstart/protected/pages/Advanced/Samples/I18N/zh_TW/Home.page @@ -30,7 +30,7 @@ <dd>國際化的一個細節步驟,它針對某個特定的市場文化對產品進行翻譯和調整。</dd>
</dl>
<p>PRADO支持以下功能:</p>
- <ul>
+ <ul id="u1" class="block-content">
<li>文本翻譯</li>
<li>屬性翻譯(尚未完成)</li>
<li>參數替換(如需要可進行翻譯)</li>
diff --git a/demos/quickstart/protected/pages/Advanced/Scripts.page b/demos/quickstart/protected/pages/Advanced/Scripts.page index 8fa1e27e..08061182 100644 --- a/demos/quickstart/protected/pages/Advanced/Scripts.page +++ b/demos/quickstart/protected/pages/Advanced/Scripts.page @@ -4,11 +4,11 @@ This guide is based on the <a href="http://www.sergiopereira.com/articles/advjs. Quick guide to somewhat advanced JavaScript tour of some OO features</a> by Sergio Pereira.
<h2 id="6502">Hey, I didn't know you could do that</h2>
-<p>
+<p id="820693" class="block-content">
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.
</p>
-<p>
+<p id="820694" class="block-content">
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</a> by Serg complex and functional code to run on the client. That helped giving birth to the
AJAX phenomena.
</p>
-<p>
+<p id="820695" class="block-content">
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</a> by Serg hierarchies, patterns, and many other things we got used to seeing only in our server
side code.
</p>
-<p>
+<p id="820696" class="block-content">
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</a> by Serg that before.
</p>
-<p>
+<p id="820697" class="block-content">
The purpose of this article is precisely explaining the types of constructs that
many of us are not familiar with yet.
</p>
<h2 id="6503">JSON (JavaScript Object Notation)</h2>
-<p>
+<p id="820698" class="block-content">
JavaScript Object Notation (<a href="http://www.json.org/">JSON</a>,) 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.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820233">
var myPet = { color: 'black', leg_count: 4, communicate: function(repeatCount){
for(i=0;i<repeatCount;i++) alert('Woof!');} };
</com:TTextHighlighter>
-<p>
+<p id="820699" class="block-content">
Let's just add little bit of formatting so it looks more like how we usually find out there:
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820234">
var myPet =
{
color: 'black',
@@ -76,7 +76,7 @@ var myPet = }
};
</com:TTextHighlighter>
-<p>
+<p id="820700" class="block-content">
Here we created a reference to an object with two properties (<tt>color</tt>
and <tt>legCount</tt>) and a method (<tt>communicate</tt>.)
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:
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820235">
alert('my pet is ' + myPet.color);
alert('my pet has ' + myPet.legCount + ' legs');
//if you are a dog, bark three times:
myPet.communicate(3);
</com:TTextHighlighter>
-<p>
+<p id="820701" class="block-content">
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.
</p>
<h2 id="6504">What do you mean? A function is an object too?</h2>
-<p>
+<p id="820702" class="block-content">
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.
</p>
-<p>
+<p id="820703" class="block-content">
Take a look at this example. We will pass functions to another function that will use them.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820236">
var myDog =
{
bark: function()
@@ -137,56 +137,56 @@ annoyThePet(myDog.bark); //annoy the cat:
annoyThePet(myCat.meow);
</com:TTextHighlighter>
-<p>
+<p id="820704" class="block-content">
Note that we pass myDog.bark and myCat.meow without appending parenthesis
<tt>"()"</tt> 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,
<tt>undefined</tt> in both cases here.
</p>
-<p>
+<p id="820705" class="block-content">
If you want to make my lazy cat start barking, you can easily do this:
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820237">
myCat.meow = myDog.bark;
myCat.meow(); //alerts 'Woof!'
</com:TTextHighlighter>
<h2 id="6505">Arrays, items, and object members</h2>
-<p>
+<p id="820706" class="block-content">
The following two lines in JS do the same thing.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820238">
var a = new Array();
var b = [];
</com:TTextHighlighter>
-<p>
+<p id="820707" class="block-content">
As I'm sure you already know, you can access individual items in an array
by using the square brackets:
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820239">
var a = ['first', 'second', 'third'];
var v1 = a[0];
var v2 = a[1];
var v3 = a[2];
</com:TTextHighlighter>
-<p>
+<p id="820708" class="block-content">
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.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820240">
var obj = {}; //new, empty object
obj['member_1'] = 'this is the member value';
obj['flag_2'] = false;
obj['some_function'] = function(){ /* do something */};
</com:TTextHighlighter>
-<p>
+<p id="820709" class="block-content">
The above code has identical effect as the following:
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820241">
var obj =
{
member_1:'this is the member value',
@@ -195,24 +195,24 @@ var obj = };
</com:TTextHighlighter>
-<p>
+<p id="820710" class="block-content">
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.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820242">
obj.some_function();
obj['some_function']();
</com:TTextHighlighter>
<h2 id="6506">Enough about objects, may I have a class now?</h2>
-<p>
+<p id="820711" class="block-content">
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.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820243">
//defining a new class called Pet
var Pet = function(petName, age)
{
@@ -224,7 +224,7 @@ var Pet = function(petName, age) var famousDog = new Pet('Santa\'s Little Helper', 15);
alert('This pet is called ' + famousDog.name);
</com:TTextHighlighter>
-<p>
+<p id="820712" class="block-content">
Let's see how we add a method to our <tt>Pet</tt> class. We will be using the
<tt>prototype</tt> property that all classes have. The <tt>prototype</tt>
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.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820244">
Pet.prototype.communicate = function()
{
alert('I do not know what I should say, but my name is ' + this.name);
};
</com:TTextHighlighter>
-<p>
+<p id="820713" class="block-content">
That's when a library like <a href="http://www.sergiopereira.com/articles/prototype.js.html">prototype.js</a> comes in
handy. If we are using prototype.js, we can make our code look cleaner (at least in my opinion.)
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820245">
var Pet = Class.create();
Pet.prototype =
{
@@ -262,23 +262,23 @@ Pet.prototype = </com:TTextHighlighter>
<h2 id="6507">Functions as arguments, an interesting pattern</h2>
-<p>
+<p id="820714" class="block-content">
If you have never worked with languages that support closures
you may find the following idiom too funky.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820246">
var myArray = ['first', 'second', 'third'];
myArray.each( function(item, index)
{
alert('The item in the position #' + index + ' is:' + item);
});
</com:TTextHighlighter>
-<p>
+<p id="820715" class="block-content">
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.
</p>
-<p>
+<p id="820716" class="block-content">
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.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820247">
function myIterator(item, index)
{
alert('The item in the position #' + index + ' is:' + item);
@@ -295,7 +295,7 @@ function myIterator(item, index) var myArray = ['first', 'second', 'third'];
myArray.each( myIterator );
</com:TTextHighlighter>
-<p>
+<p id="820717" class="block-content">
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 ); </p>
<h2 id="6508">This is <tt>this</tt> but sometimes <tt>this</tt> is also that</h2>
-<p>
+<p id="820718" class="block-content">
One of the most common troubles we have with JS when we start writing our code
it the use of the <tt>this</tt> keyword. It could be a real
tripwire.
</p>
-<p>
+<p id="820719" class="block-content">
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.
</p>
-<p>
+<p id="820720" class="block-content">
Take this code snippet as an example.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820248">
function buttonClicked()
{
alert('button ' + this.id + ' was clicked');
@@ -329,28 +329,28 @@ var myButton2 = document.getElementById('someOtherButtonID'); myButton.onclick = buttonClicked;
myButton2.onclick = buttonClicked;
</com:TTextHighlighter>
-<p>
+<p id="820721" class="block-content">
Because the buttonClicked function is defined outside any object we may tend to
think the <tt>this</tt> keyword will contain a reference to
the <tt>window</tt> or <tt>document</tt>
object (assuming this code is in the middle of an HTML page viewed in a browser.)
</p>
-<p>
+<p id="820722" class="block-content">
But when we run this code we see that it works as intended and displays the <tt>id</tt> of
the clicked button. What happened here is that we made the onclick method of each button contain the
<tt>buttonClicked</tt> object reference, replacing whatever was there before. Now
whenever the button is clicked, the browser will execute something similar to the following line.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820249">
myButton.onclick();
</com:TTextHighlighter>
-<p>
+<p id="820723" class="block-content">
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.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820250">
var myHelper =
{
formFields: [ ],
@@ -376,7 +376,7 @@ myHelper.emptyAllFields(); var clearButton = document.getElementById('btnClear');
clearButton.onclick = myHelper.emptyAllFields;
</com:TTextHighlighter>
-<p>
+<p id="820724" class="block-content">
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 <tt>this</tt> 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.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_820251">
clearButton.onclick = function()
{
myHelper.emptyAllFields();
};
</com:TTextHighlighter>
-<p>
+<p id="820725" class="block-content">
That way we create a brand new function that calls our helper method within the helper object's context.
</p>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Advanced/Scripts1.page b/demos/quickstart/protected/pages/Advanced/Scripts1.page index 7079582a..35efb2c1 100644 --- a/demos/quickstart/protected/pages/Advanced/Scripts1.page +++ b/demos/quickstart/protected/pages/Advanced/Scripts1.page @@ -5,20 +5,20 @@ This guide is based on the <a href="http://www.sergiopereira.com/articles/protot Developer Notes for prototype.js</a> by Sergio Pereira.
<h2 id="6603">What is that?</h2>
-<p>
+<p id="830726" class="block-content">
In case you haven't already used it, <a href="http://prototype.conio.net">prototype.js</a> is a
JavaScript library written by <a href="http://www.conio.net">Sam Stephenson</a>.
This amazingly well thought and well written piece of <b>standards-compliant</b> code takes a lot of
the burden associated with creating rich, highly interactive web pages that characterize the Web 2.0 off your back.
</p>
-<p>
+<p id="830727" class="block-content">
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.
</p>
-<p>
+<p id="830728" class="block-content">
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, <a href="http://prototype.conio.net">protot <h2 id="6604">Using the <tt>$()</tt> function</h2>
-<p>
+<p id="830729" class="block-content">
The <tt>$()</tt> function is a handy shortcut to the all-too-frequent <tt>document.getElementById()</tt> function
of the DOM. Like the DOM function, this one returns the element that has the id passed as an argument.
</p>
-<p>
+<p id="830730" class="block-content">
Unlike the DOM function, though, this one goes further. You can pass more than one id and
<tt>$()</tt> will return an <tt>Array</tt> object with
all the requested elements. The example below should illustrate this.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_830252">
<com:TClientScript UsingClientScripts="prado" />
<div id="myDiv">
- <p>This is a paragraph</p>
+ <p id="830731" class="block-content">This is a paragraph</p>
</div>
<div id="myOtherDiv">
- <p>This is another paragraph</p>
+ <p id="830732" class="block-content">This is another paragraph</p>
</div>
<input type="button" value=Test1 onclick="test1();" />
@@ -68,18 +68,18 @@ function test2() /*]]>*/
</script>
</com:TTextHighlighter>
-<p>
+<p id="830733" class="block-content">
Another nice thing about this function is that you can pass either the <tt>id</tt> string or the element object itself,
which makes this function very useful when creating other functions that can also take either form of argument.
</p>
<h2 id="6605">Using the <tt>$F()</tt> function</h2>
-<p>
+<p id="830734" class="block-content">
The <tt>$F()</tt> 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 <tt>id</tt> or the element object itself.
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_830253">
<input type="text" id="userName" value="Joe Doe" />
<input type="button" value=Test3 onclick="test3();" />
diff --git a/demos/quickstart/protected/pages/Advanced/Scripts2.page b/demos/quickstart/protected/pages/Advanced/Scripts2.page index 2c9ce220..97d05897 100644 --- a/demos/quickstart/protected/pages/Advanced/Scripts2.page +++ b/demos/quickstart/protected/pages/Advanced/Scripts2.page @@ -3,16 +3,16 @@ <h2 id="6702">Basic event handling</h2>
-<p>The syntax for working with events looks like the code below.</p>
+<p id="840735" class="block-content">The syntax for working with events looks like the code below.</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840254">
Event.observe(element, name, observer, [useCapture]);
</com:TTextHighlighter>
-<p>Assuming for a moment that we want to observe when a link was clicked,
+<p id="840736" class="block-content">Assuming for a moment that we want to observe when a link was clicked,
we could do the following:</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840255">
// <a id="clicker" href="http://foo.com">Click me</a>
Event.observe('clicker', 'click', function(event)
{
@@ -20,9 +20,9 @@ Event.observe('clicker', 'click', function(event) });
</com:TTextHighlighter>
-<p>If we wanted to get the element that fired the event, we'd do this:</p>
+<p id="840737" class="block-content">If we wanted to get the element that fired the event, we'd do this:</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840256">
Event.observe('clicker', 'click', function(event)
{
alert(Event.element(event));
@@ -31,9 +31,9 @@ Event.observe('clicker', 'click', function(event) <h2 id="6703">Observing keystrokes</h2>
-<p>If we wanted to observe keystrokes for the entire document, we could do the following:</p>
+<p id="840738" class="block-content">If we wanted to observe keystrokes for the entire document, we could do the following:</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840257">
Event.observe(document, 'keypress', function(event)
{
if(Event.keyCode(event) == Event.KEY_TAB)
@@ -41,31 +41,31 @@ Event.observe(document, 'keypress', function(event) });
</com:TTextHighlighter>
-<p>And lets say we wanted to keep track of what has been typed :</p>
+<p id="840739" class="block-content">And lets say we wanted to keep track of what has been typed :</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840258">
Event.observe('search', 'keypress', function(event)
{
Element.update('search-results', $F(Event.element(event)));
});
</com:TTextHighlighter>
-<p>Prototype defines properties inside the event object for some
+<p id="840740" class="block-content">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.</p>
-<p>A final note on keypress events; If you'd like to detect a
+<p id="840741" class="block-content">A final note on keypress events; If you'd like to detect a
left click you can use <tt>Event.isLeftClick(event)</tt>.</p>
<h2 id="6704">Getting the coordinates of the mouse pointer</h2>
-<p>Drag and drop, dynamic element resizing, games, and
+<p id="840742" class="block-content">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.</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840259">
Event.observe(document, 'mousemove', function(event)
{
$('mouse').value = "X: " + Event.pointerX(event) +
@@ -73,23 +73,23 @@ Event.observe(document, 'mousemove', function(event) });
</com:TTextHighlighter>
-<p>If we wanted to observe the mouse location when it was
+<p id="840743" class="block-content">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.</p>
<h2 id="6705">Stopping Propagation</h2>
-<p><tt>Event.stop(event)</tt> will stop the propagation of an event .</p>
+<p id="840744" class="block-content"><tt>Event.stop(event)</tt> will stop the propagation of an event .</p>
<h2 id="6706">Events, Binding, and Objects</h2>
-<p>Everything has been fairly straight forward so far, but things
+<p id="840745" class="block-content">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.</p>
-<p>Lets look at some code so you can get a better understanding of what I'm talking about.</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<p id="840746" class="block-content">Lets look at some code so you can get a better understanding of what I'm talking about.</p>
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840260">
EventDispenser = Class.create();
EventDispenser.prototype =
{
@@ -141,15 +141,15 @@ EventDispenser.prototype = }
}
</com:TTextHighlighter>
-<p>Whoa! What's going on here? Well, we've defined our a
+<p id="840747" class="block-content">Whoa! What's going on here? Well, we've defined our a
custom class <tt>EventDispenser</tt>. 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.</p>
-<p>Looking at the <tt>initialize</tt> method, we can really see how
+<p id="840748" class="block-content">Looking at the <tt>initialize</tt> method, we can really see how
things are different now. Take a look at the code below:</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840261">
// Observe clicks on our list items
$$(this.list + " li").each(function(item)
{
@@ -157,82 +157,82 @@ $$(this.list + " li").each(function(item) }.bind(this));
</com:TTextHighlighter>
-<p>We've got iterators, binding and all sorts of stuff going on.
+<p id="840749" class="block-content">We've got iterators, binding and all sorts of stuff going on.
Lets break down what this chunk of code is doing.</p>
-<p>First we are hunting for a collection of elements based on
+<p id="840750" class="block-content">First we are hunting for a collection of elements based on
it's CSS selector. This uses the Prototype selector function <tt>$$()</tt>.
After we've found the list items we are dealing with we send
those into an each iteration where we will add our observers.</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840262">
Event.observe(item, 'click', this.showTagName.bindEvent(this));
</com:TTextHighlighter>
-<p>Now looking at the code above, you'll notice the <tt>bindEvent</tt> function.
+<p id="840751" class="block-content">Now looking at the code above, you'll notice the <tt>bindEvent</tt> function.
This takes the method before it <tt>showTagName</tt> and treats it as the
method that will be triggered when, in this case,
someone clicks one of our list items.</p>
-<p>You'll also notice we pass this as an argument to the <tt>bindEvent</tt> function.
+<p id="840752" class="block-content">You'll also notice we pass this as an argument to the <tt>bindEvent</tt> function.
This simply allows us to reference the object in context <tt>EventDispenser</tt>
inside our function <tt>showTagName(event)</tt>. If the <tt>showTagName</tt> function
requires additional parameters, you can attach them to the later parameters of <tt>bindEvent</tt>. For example</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840263">
this.showTagName.bindEvent(this, param1, param2);
//where the showTagName function is defined as
showTime : function (event, param1, param2) { ... }
</com:TTextHighlighter>
-<p>Moving on, you'll see <tt>bind(this)</tt> attached to our iterator function.
+<p id="840753" class="block-content">Moving on, you'll see <tt>bind(this)</tt> attached to our iterator function.
This really has nothing to do with events, it is only here to allow me to
use <tt>this</tt> inside the iterator. If we did not use <tt>bind(this)</tt>, I could not
reference the method <tt>showTagName</tt> inside the iterator.</p>
-<p>Ok, so we'll move on to looking at our methods that actually get
+<p id="840754" class="block-content">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 <tt>showTagName</tt>, lets look at it.</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840264">
showTagName: function(event)
{
alert(Event.element(event).tagName);
}
</com:TTextHighlighter>
-<p>As you can see, this function accepts one argument--the event.
+<p id="840755" class="block-content">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 <tt>Event.element</tt>. Now we can manipulate it at will.</p>
-<p>This covers the most confusing parts of our code. The text above is also
+<p id="840756" class="block-content">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.</p>
<h2 id="6707">Removing Event Listeners</h2>
-<p>This one threw me for a loop the first time I tried to use it.
+<p id="840757" class="block-content">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 <tt>Event.observe</tt>
call with the exception of using <tt>stopObserving</tt>, but nothing seemed
to change. In other words, the code below does <b>NOT</b> work.</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840265">
$$(this.list + " li").each(function(item)
{
Event.stopObserving(item, 'click', this.showTagName);
}.bind(this));
</com:TTextHighlighter>
-<p>What's the deal here? The reason this does not work is because there
+<p id="840758" class="block-content">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 <tt>this.showTagName</tt>
in the <tt>Event.observe</tt> 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.</p>
-<p>So how do we get the job done? All we need to do is give the
+<p id="840759" class="block-content">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 <tt>this.showTagName</tt>. Ok, lets change our code a bit.</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840266">
this.showTagObserver = this.showTagName.bindEvent(this);
// Observe clicks on our list items
@@ -242,8 +242,8 @@ $$(this.list + " li").each(function(item) }.bind(this));
</com:TTextHighlighter>
-<p>Now we can remove the event listeners from our list like this:</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<p id="840760" class="block-content">Now we can remove the event listeners from our list like this:</p>
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840267">
$$(this.list + " li").each(function(item)
{
Event.stopObserving(item, 'click', this.showTagObserver);
diff --git a/demos/quickstart/protected/pages/Advanced/Scripts3.page b/demos/quickstart/protected/pages/Advanced/Scripts3.page index 8ba6d5c8..1839f782 100644 --- a/demos/quickstart/protected/pages/Advanced/Scripts3.page +++ b/demos/quickstart/protected/pages/Advanced/Scripts3.page @@ -1,19 +1,19 @@ <com:TContent ID="body" >
<h1 id="6801">Javascript in PRADO, Questions and Answers</h1>
<h2 id="6802">How do I include the predefined Javascript libraries?</h2>
-<ul><li>Adding libraries in the template
-<com:TTextHighlighter Language="prado" CssClass="source">
+<ul id="u1" class="block-content"><li>Adding libraries in the template
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_850268">
<com:TClientScript UsingPradoScripts="effects" />
</com:TTextHighlighter>
</li>
<li>Adding libraries in PHP code
- <com:TTextHighlighter Language="php" CssClass="source">
+ <com:TTextHighlighter Language="php" CssClass="source block-content" id="code_850269">
$this->getPage()->getClientScript()->registerPradoScript("effects");
</com:TTextHighlighter>
</li>
</ul>
The available packaged libraries included in Prado are
-<ul>
+<ul id="u2" class="block-content">
<li><tt>prado</tt> : basic PRADO javascript framework based on Prototype</li>
<li><tt>effects</tt> : visual effects from script.aculo.us</li>
<li><tt>ajax</tt> : ajax and callback related based on Prototype</li>
@@ -24,12 +24,12 @@ The available packaged libraries included in Prado are <li><tt>colorpicker</tt> : colorpicker</li>
</ul>
-<p>The dependencies for each library are automatically resolved. Components
+<p id="850761" class="block-content">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 <tt>datepicker</tt>
and its dependencies will be automatically included on the page.</p>
-<p>See <a href="?page=Controls.ClientScript">TClientScript</a> for options of adding
+<p id="850762" class="block-content">See <a href="?page=Controls.ClientScript">TClientScript</a> for options of adding
your custom Javascript code to the page.</p>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Advanced/Security.page b/demos/quickstart/protected/pages/Advanced/Security.page index 3dbfe0ab..89a335dd 100644 --- a/demos/quickstart/protected/pages/Advanced/Security.page +++ b/demos/quickstart/protected/pages/Advanced/Security.page @@ -3,75 +3,75 @@ <h1 id="5601">Security</h1>
<h2 id="5602">Viewstate Protection</h2>
-<p>
+<p id="730563" class="block-content">
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.
</p>
-<p>
+<p id="730564" class="block-content">
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.
</p>
-<p>
+<p id="730565" class="block-content">
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.
</p>
-<p>
+<p id="730566" class="block-content">
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 <tt>TSecurityManager</tt> in application configuration,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_730186">
<modules>
<module id="security"
class="TSecurityManager"
ValidationKey="my private key" />
</modules>
</com:TTextHighlighter>
-<p>
+<p id="730567" class="block-content">
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 <tt>EnableStateEncryption</tt> of pages to true. This can be done in <a href="?page=Configurations.PageConfig">page configurations</a> 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.
</p>
<h2 id="5603">Cross Site Scripting Prevention</h2>
-<p>
+<p id="730568" class="block-content">
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.
</p>
-<p>
+<p id="730569" class="block-content">
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.
</p>
-<p>
+<p id="730570" class="block-content">
PRADO incorporates the work of <a href="http://pixel-apes.com/safehtml/">SafeHTML</a> and provides developers with a useful component called <tt>TSafeHtml</tt>. By enclosing content within a <tt>TSafeHtml</tt> component tag, the enclosed content are ensured to be safe to end users. In addition, the commonly used <tt>TTextBox</tt> has a <tt>SafeText</tt> property which contains user input that are ensured to be safe if displayed directly to end users.
</p>
<h2 id="5604">Cookie Attack Prevention</h2>
-<p>
+<p id="730571" class="block-content">
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.
</p>
-<p>
+<p id="730572" class="block-content">
There are several countermeasures to prevent cookies from being attacked.
</p>
-<ul>
+<ul id="u1" class="block-content">
<li>An application can use SSL to create a secure communication channel and only pass the authentication cookie over an HTTPS connection. Attackers are thus unable to decipher the contents in the transferred cookies.</li>
<li>Expire sessions appropriately, including all cookies and session tokens, to reduce the likelihood of being attacked.</li>
<li>Prevent <a href="?page=Security.XSS">cross-site scripting (XSS)</a> which causes arbitrary code to run in a user's browser and expose his cookies.</li>
<li>Validate cookie data and detect if they are altered.</li>
</ul>
-<p>
+<p id="730573" class="block-content">
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.
</p>
-<p>
+<p id="730574" class="block-content">
Cookie validation is disabled by default. To enable it, configure the <tt>THttpRequest</tt> module as follows,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_730187">
<modules>
<module id="request" class="THttpRequest" EnableCookieValidation="true" />
</modules>
</com:TTextHighlighter>
-<p>
+<p id="730575" class="block-content">
To make use of cookie validation scheme provided by PRADO, you also need to retrieve cookies through the <tt>Cookies</tt> collection of <tt>THttpRequest</tt> by using the following PHP statements,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_730188">
foreach($this->Request->Cookies as $cookie)
// $cookie is of type THttpCookie
</com:TTextHighlighter>
-<p>
+<p id="730576" class="block-content">
To send cookie data encoded with validation information, create new <tt>THttpCookie</tt> objects and add them to the <tt>Cookies</tt> collection of <tt>THttpResponse</tt>,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_730189">
$cookie=new THttpCookie($name,$value);
$this->Response->Cookies[]=$cookie;
</com:TTextHighlighter>
diff --git a/demos/quickstart/protected/pages/Advanced/State.page b/demos/quickstart/protected/pages/Advanced/State.page index 6e7e7f99..02958e05 100644 --- a/demos/quickstart/protected/pages/Advanced/State.page +++ b/demos/quickstart/protected/pages/Advanced/State.page @@ -1,53 +1,53 @@ <com:TContent ID="body" >
<h1 id="6001">Persistent State</h1>
-<p>
+<p id="770606" class="block-content">
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.
</p>
<h2 id="6002">View State</h2>
-<p>
+<p id="770607" class="block-content">
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.
</p>
-<p>
+<p id="770608" class="block-content">
View state is only available to controls. View state of a control can be disabled by setting its <tt>EnableViewState</tt> property to false. To store a variable in view state, call the following,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_770197">
$this->setViewState('Caption',$caption);
</com:TTextHighlighter>
-<p>
+<p id="770609" class="block-content">
where <tt>$this</tt> refers to the control object, <tt>Caption</tt> is a unique key identifying the <tt>$caption</tt> variable stored in viewstate. To retrieve the variable back from view state, call the following,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_770198">
$caption = $this->getViewState('Caption');
</com:TTextHighlighter>
<h2 id="6003">Control State</h2>
-<p>
+<p id="770610" class="block-content">
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.
</p>
-<p>
+<p id="770611" class="block-content">
To store and retrieve a variable in control state, use the following commands,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_770199">
$this->setControlState('Caption',$caption);
$caption = $this->getControlState('Caption');
</com:TTextHighlighter>
<h2 id="6004">Application State</h2>
-<p>
+<p id="770612" class="block-content">
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.
</p>
-<p>
+<p id="770613" class="block-content">
To store and retrieve a variable in application state, use the following commands,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_770200">
$application->setGlobalState('Caption',$caption);
$caption = $application->getGlobalState('Caption');
</com:TTextHighlighter>
<h2 id="6005">Session State</h2>
-<p>
+<p id="770614" class="block-content">
PRADO encapsulates the traditional session management in <tt>THttpSession</tt> module. The module can be accessed from within any component by using <tt>$this->Session</tt>, where <tt>$this</tt> refers to the component object.
</p>
diff --git a/demos/quickstart/protected/pages/Advanced/Themes.page b/demos/quickstart/protected/pages/Advanced/Themes.page index 07435928..876078b7 100644 --- a/demos/quickstart/protected/pages/Advanced/Themes.page +++ b/demos/quickstart/protected/pages/Advanced/Themes.page @@ -3,40 +3,40 @@ <h1 id="5901">Themes and Skins</h1>
<h2 id="5902">Introduction</h2>
-<p>
+<p id="760596" class="block-content">
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 <tt>PageSize</tt> property of the <tt>TDataGrid</tt> control.
</p>
<h2 id="5903">Understanding Themes</h2>
-<p>
+<p id="760597" class="block-content">
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 <tt>SkinID</tt>. When applying a theme to a page, a skin is applied to a control if the control type and the <tt>SkinID</tt> value both match to those of the skin. Note, if a skin has an empty <tt>SkinID</tt> value, it will apply to all controls of the particular type whose <tt>SkinID</tt> 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.
</p>
<h2 id="5904">Using Themes</h2>
-<p>
+<p id="760598" class="block-content">
To use a theme, you need to set the <tt>Theme</tt> property of the page with the theme name, which is the theme directory name. You may set it in either <a href="?page=Configurations.PageConfig">page configurations</a> or in the constructor or <tt>onPreInit()</tt> method of the page. You cannot set the property after <tt>onPreInit()</tt> because by that time, child controls of the page are already created (skins must be applied to controls right after they are created.)
</p>
-<p>
+<p id="760599" class="block-content">
To use a particular skin in the theme for a control, set <tt>SkinID</tt> property of the control in template like following,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_760194">
<com:TButton SkinID="Blue" ... />
</com:TTextHighlighter>
-<p>
+<p id="760600" class="block-content">
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 <tt>StyleSheetTheme</tt> property of the page instead of <tt>Theme</tt> (you can have both <tt>StyleSheetTheme</tt> and <tt>Theme</tt>).
</p>
-<p>
+<p id="760601" class="block-content">
To use the Javascript files and CSS files contained in a theme, a <tt>THead</tt> control must be placed on the page template. This is because the theme will register those files with the page and <tt>THead</tt> is the right place to load those files.
</p>
-<p>
+<p id="760602" class="block-content">
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 <tt>mystyle.print.css</tt>, it will be applied only to <tt>print</tt> media type. As another example, <tt>mystyle.screen.css</tt> applies to <tt>screen</tt> media only, and <tt>mystyle.css</tt> applies to all media types.
</p>
<h2 id="5905">Theme Storage</h2>
-<p>
+<p id="760603" class="block-content">
All themes by default must be placed under the <tt>[AppEntryPath]/themes</tt> directory, where <tt>AppEntryPath</tt> refers to the directory containing the application entry script. If you want to use a different directory, configure the <tt>BasePath</tt> and <tt>BaseUrl</tt> properties of the <tt>System.Web.UI.TThemeManager</tt> module in application configuration,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_760195">
<service id="page" class="TPageService">
<modules>
<module id="theme"
@@ -48,13 +48,13 @@ All themes by default must be placed under the <tt>[AppEntryPath]/themes</tt> di </com:TTextHighlighter>
<h2 id="5906">Creating Themes</h2>
-<p>
+<p id="760604" class="block-content">
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 <tt>.skin</tt>. 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 <tt>TButton</tt>, write the following in a skin file,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_760196">
<com:TButton SkinID="Blue" BackColor="blue" />
</com:TTextHighlighter>
-<p>
+<p id="760605" class="block-content">
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, <tt>Button.skin</tt> would contain skins only for the <tt>TButton</tt> control type.
</p>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Configurations/AppConfig.page b/demos/quickstart/protected/pages/Configurations/AppConfig.page index e15f1eea..97db019f 100644 --- a/demos/quickstart/protected/pages/Configurations/AppConfig.page +++ b/demos/quickstart/protected/pages/Configurations/AppConfig.page @@ -1,12 +1,12 @@ <com:TContent ID="body" >
<h1 id="1801">Application Configurations</h1>
-<p>
+<p id="210213" class="block-content">
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.
</p>
-<p>
+<p id="210214" class="block-content">
Configuration for an application is stored in an XML file named <tt>application.xml</tt>, which should be located under the application base path. Its format is shown in the following,
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_210095">
<application PropertyName="PropertyValue" ...>
<paths>
<alias id="AliasID" path="AliasPath" />
@@ -24,22 +24,22 @@ Configuration for an application is stored in an XML file named <tt>application. </application>
</com:TTextHighlighter>
</p>
-<ul>
+<ul id="u1" class="block-content">
<li>The outermost element <tt><application></tt> corresponds to the <tt>TApplication</tt> instance. The <tt>PropertyName="PropertyValue"</tt> pairs specify the initial values for the properties of <tt>TApplication</tt>.</li>
<li>The <tt><paths></tt> element contains the definition of path aliases and the PHP inclusion paths for the application. Each path alias is specified via an <tt><alias></tt> whose <tt>path</tt> attribute takes an absolute path or a path relative to the directory containing the application configuration file. The <tt><using></tt> element specifies a particular path (in terms of namespace) to be appended to the PHP include paths when the application runs. PRADO defines two default aliases: <tt>System</tt> and <tt>Application</tt>. The former refers to the PRADO framework root directory, and the latter refers to the directory containing the application configuration file.</li>
<li>The <tt><modules></tt> element contains the configurations for a list of modules. Each module is specified by a <tt><module></tt> element. Each module is uniquely identified by the <tt>id</tt> attribute and is of type <tt>class</tt>. The <tt>PropertyName="PropertyValue"</tt> pairs specify the initial values for the properties of the module.</li>
<li>The <tt><services></tt> element is similar to the <tt><modules></tt> element. It mainly specifies the services provided by the application.</li>
<li>The <tt><parameters></tt> element contains a list of application-level parameters that are accessible from anywhere in the application. You may specify component-typed parameters like specifying modules, or you may specify string-typed parameters which take a simpler format as follows,
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_210096">
<parameter id="ParameterID" value="ParameterValue" />
</com:TTextHighlighter>
Note, if the <tt>value</tt> attribute is not specified, the whole parameter XML node (of type <tt>TXmlElement</tt>) will be returned as the parameter value. In addition, the <tt>System.Util.TParameterModule</tt> module provides a way to load parameters from an external XML file. See more details in its API documentation.
</li>
</ul>
-<p>
+<p id="210215" class="block-content">
Complete specification of application configurations can be found in the <a href="<%~../../../../../docs/specs/application.dtd%>">DTD</a> and <a href="<%~../../../../../docs/specs/application.xsd%>">XSD</a> files.
</p>
-<p>
+<p id="210216" class="block-content">
By default without explicit configuration, a PRADO application when running will load a few core modules, such as <tt>THttpRequest</tt>, <tt>THttpResponse</tt>, etc. It will also provide the <tt>TPageService</tt> 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.
</p>
diff --git a/demos/quickstart/protected/pages/Configurations/Overview.page b/demos/quickstart/protected/pages/Configurations/Overview.page index ec606941..07167fc6 100644 --- a/demos/quickstart/protected/pages/Configurations/Overview.page +++ b/demos/quickstart/protected/pages/Configurations/Overview.page @@ -1,9 +1,9 @@ <com:TContent ID="body" >
<h1 id="1401">Configuration Overview</h1>
-<p>
+<p id="170164" class="block-content">
PRADO uses configurations to glue together components into pages and applications. There are <a href="?page=Configurations.AppConfig">application configurations</a>, <a href="?page=Configurations.PageConfig">page configurations</a>, and <a href="?page=Configurations.Templates1">templates</a>.
</p>
-<p>
+<p id="170165" class="block-content">
Application and page configurations are optional if default values are used. Templates are mainly used by pages and template controls. They are optional, too.
</p>
diff --git a/demos/quickstart/protected/pages/Configurations/PageConfig.page b/demos/quickstart/protected/pages/Configurations/PageConfig.page index b0ef5ccb..f770dba2 100644 --- a/demos/quickstart/protected/pages/Configurations/PageConfig.page +++ b/demos/quickstart/protected/pages/Configurations/PageConfig.page @@ -1,16 +1,16 @@ <com:TContent ID="body" >
<h1 id="1901">Page Configurations</h1>
-<p>
+<p id="220217" class="block-content">
Page configurations are mainly used by <tt>TPageService</tt> 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 <tt>config.xml</tt>.
</p>
-<p>
+<p id="220218" class="block-content">
When a user requests a page stored under <tt><BasePath>/dir1/dir2</tt>, the <tt>TPageService</tt> will try to parse and load <tt>config.xml</tt> files under <tt><BasePath></tt>, <tt><BasePath>/dir1</tt> and <tt><BasePath>/dir1/dir2</tt>. Paths, modules, and parameters specified in these configuration files will be appended or merged into the existing application configuration. Here <tt><BasePath></tt> is as defined in <a href="?page=Fundamentals.Services">page service</a>.
</p>
-<p>
+<p id="220219" class="block-content">
The format of a page configuration file is as follows,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_220097">
<configuration>
<paths>
<alias id="AliasID" path="AliasPath" />
@@ -31,10 +31,10 @@ The format of a page configuration file is as follows, </parameters>
</configuration>
</com:TTextHighlighter>
-<p>
+<p id="220220" class="block-content">
The <tt><paths></tt>, <tt><modules></tt> and <tt><parameters></tt> are similar to those in an application configuration. The <tt><authorization></tt> 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 <tt><pages></tt> element specifies the initial values for the properties of pages. Each <tt><page></tt> element specifies the initial property values for a particular page identified by the <tt>id</tt> attribute. Initial property values given in the <tt><pages></tt> element apply to all pages in the current directory and all its subdirectories.
</p>
-<p>
+<p id="220221" class="block-content">
Complete specification of page configurations can be found in the <a href="<%~../../../../../docs/specs/config.dtd%>">DTD</a> and <a href="<%~../../../../../docs/specs/config.xsd%>">XSD</a> files.
</p>
diff --git a/demos/quickstart/protected/pages/Configurations/Templates1.page b/demos/quickstart/protected/pages/Configurations/Templates1.page index cda02d2b..566a36b3 100644 --- a/demos/quickstart/protected/pages/Configurations/Templates1.page +++ b/demos/quickstart/protected/pages/Configurations/Templates1.page @@ -1,41 +1,41 @@ <com:TContent ID="body" >
<h1 id="1501">Templates: Part I</h1>
-<p>
+<p id="180166" class="block-content">
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 <tt>TTemplateControl</tt> 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 <tt>.page</tt>; for other regular template controls, the suffix is <tt>.tpl</tt>.
</p>
-<p>The template format is like HTML, with a few PRADO-specifc tags, including <a href="#ct">component tags</a>, <a href="#tct">template control tags</a>, <a href="#cot">comment tags</a>, <a href="?page=Configurations.Templates2#dct">dynamic content tags</a>, and <a href="?page=Configurations.Templates3#dpt">dynamic property tags</a>. .
+<p id="180167" class="block-content">The template format is like HTML, with a few PRADO-specifc tags, including <a href="#ct">component tags</a>, <a href="#tct">template control tags</a>, <a href="#cot">comment tags</a>, <a href="?page=Configurations.Templates2#dct">dynamic content tags</a>, and <a href="?page=Configurations.Templates3#dpt">dynamic property tags</a>. .
</p>
<a name="ct"></a>
<h2 id="1502">Component Tags</h2>
-<p>
+<p id="180168" class="block-content">
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.
</p>
-<p>
+<p id="180169" class="block-content">
The format of a component tag is as follows,
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_180072">
<com:ComponentType PropertyName="PropertyValue" ... EventName="EventHandler" ...>
body content
</com:ComponentType>
</com:TTextHighlighter>
<tt>ComponentType</tt> can be either the class name or the dotted type name (e.g. <tt>System.Web.UI.TControl</tt>) of the component. <tt>PropertyName</tt> and <tt>EventName</tt> are both case-insensitive. <tt>PropertyName</tt> can be a property or subproperty name (e.g. <tt>Font.Name</tt>). Note, <tt>PropertyValue</tt> will be HTML-decoded when assigned to the corresponding property. Content enclosed between the opening and closing component tag are normally treated the body of the component.
</p>
-<p>
+<p id="180170" class="block-content">
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.
</p>
-<p>
+<p id="180171" class="block-content">
The following template shows a component tag specifying the <tt>Text</tt> property and <tt>OnClick</tt> event of a button control,
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_180073">
<com:TButton Text="Register" OnClick="registerUser" />
</com:TTextHighlighter>
Note, property names and event names are all case-insensitive, while component type names are case-sensitive. Event names always begin with <tt>On</tt>.
</p>
-<p>
+<p id="180172" class="block-content">
Also note, initial values for properties whose name ends with <tt>Template</tt> are specially processed. In particular, the initial values are parsed as <tt>TTemplate</tt> objects. The <tt>ItemTemplate</tt> property of the <tt>TRepeater</tt> control is such an example.
</p>
-<p>
+<p id="180173" class="block-content">
To deal conveniently with properties taking take big trunk of initial data, the following property initialization tag is introduced,
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_180074">
<prop:PropertyName>
PropertyValue
</prop:PropertyName>
@@ -44,9 +44,9 @@ It is equivalent to <tt>...PropertyName="PropertyValue"...</tt> in every aspect. </p>
<h3 id="1505">Component IDs</h3>
-<p>
+<p id="180174" class="block-content">
When specified in templates, component <tt>ID</tt> 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 <tt>Home</tt> page's template, the following component tag
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_180075">
<com:TTextBox ID="TextBox" Text="First Name" />
</com:TTextHighlighter>
makes it possible to get the textbox object in code using <tt>$page->TextBox</tt>.
@@ -55,24 +55,24 @@ makes it possible to get the textbox object in code using <tt>$page->TextBox</tt <a name="tct"></a>
<h2 id="1503">Template Control Tags</h2>
A template control tag is used to configure the initial property values of the control owning the template. Its format is as follows,
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_180076">
<%@ PropertyName="PropertyValue" ... %>
</com:TTextHighlighter>
Like in component tags, <tt>PropertyName</tt> is case-insensitive and can be a property or subproperty name.
</p>
-<p>
+<p id="180175" class="block-content">
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 <tt>Init</tt> stage of the control.
</p>
-<p>
+<p id="180176" class="block-content">
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.
</p>
<a name="cot"></a>
<h2 id="1504">Comment Tags</h2>
-<p>
+<p id="180177" class="block-content">
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,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_180077">
<!--
Comments INVISIBLE to end-users
--->
@@ -81,17 +81,17 @@ Comments INVISIBLE to end-users The new comment tag <tt><!-- ... ---></tt> has been introduced since PRADO version 3.1. Previously, it was <tt><!-- ... --!></tt> which was deprecated because some editors have problems in syntax-highlighting such tags. </div>
<h2 id="1601">Include Tags</h2>
-<p>
+<p id="180178" class="block-content">
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 <tt>.tpl</tt>.
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_180078">
<%include path.to.templateFile %>
</com:TTextHighlighter>
-<p>
+<p id="180179" class="block-content">
External templates will be inserted at the places where the include tags occur in the base template.
</p>
-<p>
+<p id="180180" class="block-content">
Note, nested template inclusion is not supported, i.e., you cannot have include tags in an external template.
</p>
diff --git a/demos/quickstart/protected/pages/Configurations/Templates2.page b/demos/quickstart/protected/pages/Configurations/Templates2.page index 201c526f..e7cb46f5 100644 --- a/demos/quickstart/protected/pages/Configurations/Templates2.page +++ b/demos/quickstart/protected/pages/Configurations/Templates2.page @@ -3,42 +3,42 @@ <a name="dct"></a>
<h2 id="1602">Dynamic Content Tags</h2>
-<p>
+<p id="190181" class="block-content">
Dynamic content tags are introduced as shortcuts to some commonly used <a href="?page=Configurations.Templates1#ct">component tags</a>. These tags are mainly used to render contents resulted from evaluating some PHP expressions or statements. They include <a href="#et">expression tags</a>, <a href="#st">statement tags</a>, <a href="#dt">databind tags</a>, <a href="#pt">parameter tags</a>, <a href="#at">asset tags</a> and <a href="#lot">localization tags</a>.
</p>
<a name="et"></a>
<h3 id="1603">Expression Tags</h3>
-<p>
+<p id="190182" class="block-content">
An expression tag represents a PHP expression that is evaluated when the template control is in <tt>PreRender</tt> stage. The expression evaluation result is inserted at the place where the tag resides in the template. The context (namely <tt>$this</tt>) of the expression is the control owning the template.
</p>
-<p>
+<p id="190183" class="block-content">
The format of an expression tag is as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_190079">
<%= PhpExpression %>
</com:TTextHighlighter>
-<p>
+<p id="190184" class="block-content">
For example, the following expression tag will display the current page title at the place,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_190080">
<%= $this->Title %>
</com:TTextHighlighter>
<a name="st"></a>
<h3 id="1604">Statement Tags</h3>
-<p>
+<p id="190185" class="block-content">
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 <tt>echo</tt> or <tt>print</tt> in PHP) are displayed at the place where the statement tag resides in the template. The context (namely <tt>$this</tt>) of the statements is the control owning the template. The format of statement tags is as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_190081">
<%%
PHP Statements
%>
</com:TTextHighlighter>
-<p>
+<p id="190186" class="block-content">
The following example displays the current time in Dutch at the place,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_190082">
<%%
setlocale(LC_ALL, 'nl_NL');
echo strftime("%A %e %B %Y",time());
@@ -47,52 +47,52 @@ echo strftime("%A %e %B %Y",time()); <a name="dt"></a>
<h3 id="1605">Databind Tags</h3>
-<p>
+<p id="190187" class="block-content">
Databind tags are similar to expression tags, except that the expressions are evaluated only when a <tt>dataBind()</tt> call is invoked on the controls representing the databind tags. The context (namely <tt>$this</tt>) of a databind expression is the control owning the template. The format of databind tags is as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_190083">
<%# PhpExpression %>
</com:TTextHighlighter>
<a name="pt"></a>
<h3 id="1606">Parameter Tags</h3>
-<p>
+<p id="190188" class="block-content">
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,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_190084">
<%$ ParameterName %>
</com:TTextHighlighter>
-<p>
+<p id="190189" class="block-content">
Note, application parameters are usually defined in application configurations or page directory configurations. The parameters are evaluated when the template is instantiated.
</p>
<a name="at"></a>
<h3 id="1607">Asset Tags</h3>
-<p>
+<p id="190190" class="block-content">
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.
</p>
-<p>
+<p id="190191" class="block-content">
The format of asset tags is as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_190085">
<%~ LocalFileName %>
</com:TTextHighlighter>
-<p>
+<p id="190192" class="block-content">
where <tt>LocalFileName</tt> 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.
</p>
-<p>
+<p id="190193" class="block-content">
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.
</p>
<a name="lot"></a>
<h3 id="1608">Localization Tags</h3>
-<p>
+<p id="190194" class="block-content">
Localization tags represent localized texts. They are in the following format,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_190086">
<%[string]%>
</com:TTextHighlighter>
-<p>
+<p id="190195" class="block-content">
where <tt>string</tt> will be translated to different languages according to the end-user's language preference. Localization tags are in fact shortcuts to the function call <tt>Prado::localize(string)</tt>.
</p>
diff --git a/demos/quickstart/protected/pages/Configurations/Templates3.page b/demos/quickstart/protected/pages/Configurations/Templates3.page index bc3b1f87..38391e9c 100644 --- a/demos/quickstart/protected/pages/Configurations/Templates3.page +++ b/demos/quickstart/protected/pages/Configurations/Templates3.page @@ -3,51 +3,51 @@ <a name="dpt"></a>
<h2 id="1702">Dynamic Property Tags</h2>
-<p>
+<p id="200196" class="block-content">
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,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_200087">
<com:ComponentType PropertyName=DynamicPropertyTag ...>
body content
</com:ComponentType>
</com:TTextHighlighter>
-<p>
+<p id="200197" class="block-content">
where you may enclose <tt>DynamicPropertyTag</tt> within single or double quotes for better readability.
</p>
-<p>
+<p id="200198" class="block-content">
Like dynamic content tags, we have <a href="#et">expression tags</a>, <a href="#dt">databind tags</a>, <a href="#pt">parameter tags</a>, <a href="#at">asset tags</a> and <a href="#lot">localization tags</a>. (Note, there is no statement tag here.)
</p>
<a name="et"></a>
<h3 id="1703">Expression Tags</h3>
-<p>
+<p id="200199" class="block-content">
An expression tag represents a PHP expression that is evaluated when the control is in <tt>PreRender</tt> stage. The expression evaluation result is assigned to the corresponding component property. The format of expression tags is as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_200088">
<%= PhpExpression %>
</com:TTextHighlighter>
-<p>
+<p id="200200" class="block-content">
In the expression, <tt>$this</tt> refers to the control owning the template. The following example specifies a <tt>TLabel</tt> control whose <tt>Text</tt> property is initialized as the current page title when the <tt>TLabel</tt> control is being constructed,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_200089">
<com:TLabel Text=<%= $this->Page->Title %> />
</com:TTextHighlighter>
<a name="dt"></a>
<h3 id="1704">Databind Tags</h3>
-<p>
+<p id="200201" class="block-content">
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 <tt>dataBind()</tt> call is invoked on the controls represented by the component tags. In the expression, <tt>$this</tt> refers to the control owning the template. Databind tags do not apply to all components. They can only be used for controls.
</p>
-<p>
+<p id="200202" class="block-content">
The format of databind tags is as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_200090">
<%# PhpExpression %>
</com:TTextHighlighter>
-<p>
+<p id="200203" class="block-content">
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,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_200091">
<com:TLabel>
<prop:Text>
Today is <%= date('F d, Y',time()) >.
@@ -55,49 +55,49 @@ Since v3.0.2, expression tags and databind tags can be embedded within static st </prop:Text>
</com:TLabel>
</com:TTextHighlighter>
-<p>
+<p id="200204" class="block-content">
Previously, you would have to use a single expression with string concatenations to achieve the same effect.
</p>
<a name="pt"></a>
<h3 id="1705">Parameter Tags</h3>
-<p>
+<p id="200205" class="block-content">
Parameter tags are used to assign application parameter values to the corresponding component properties. The format of parameter tags is as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_200092">
<%$ ParameterName %>
</com:TTextHighlighter>
-<p>
+<p id="200206" class="block-content">
Note, application parameters are usually defined in application configurations or page directory configurations. The parameters are evaluated when the template is instantiated.
</p>
<a name="at"></a>
<h3 id="1706">Asset Tags</h3>
-<p>
+<p id="200207" class="block-content">
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.
</p>
-<p>
+<p id="200208" class="block-content">
The format of asset tags is as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_200093">
<%~ LocalFileName %>
</com:TTextHighlighter>
-<p>
+<p id="200209" class="block-content">
where <tt>LocalFileName</tt> 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.
</p>
-<p>
+<p id="200210" class="block-content">
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.
</p>
<a name="lot"></a>
<h3 id="1707">Localization Tags</h3>
-<p>
+<p id="200211" class="block-content">
Localization tags represent localized texts. They are in the following format,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_200094">
<%[string]%>
</com:TTextHighlighter>
-<p>
+<p id="200212" class="block-content">
where <tt>string</tt> 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 <tt>Prado::localize(string)</tt>.
</p>
diff --git a/demos/quickstart/protected/pages/Configurations/UrlMapping.page b/demos/quickstart/protected/pages/Configurations/UrlMapping.page index 20954c24..a8ea3ace 100644 --- a/demos/quickstart/protected/pages/Configurations/UrlMapping.page +++ b/demos/quickstart/protected/pages/Configurations/UrlMapping.page @@ -4,12 +4,12 @@ <com:DocLink ClassPath="System.Web.TUrlMapping" />
-<p>Using the <tt>TUrlMapping</tt> module different URLs can be
+<p id="230222" class="block-content">Using the <tt>TUrlMapping</tt> module different URLs can be
mapped into any existing Prado pages or services. This allows
the application to use nice looking and friendly URLs.
</p>
-<p>
+<p id="230223" class="block-content">
The <tt>TUrlMapping</tt> 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 <tt>TUrlMapping</tt> module before any Specifying the mappings in the per directory <tt>config.xml</tt> is not supported.
</div>
-<p>
+<p id="230224" class="block-content">
To use <tt>TUrlMapping</tt>, one must set the <tt>UrlManager</tt> property of the <tt>THttpRequest</tt> module as the <tt>TUrlMapping</tt> module ID. See following for an example,
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_230098">
<modules>
<module id="request" class="THttpRequest" UrlManager="friendly-url" />
<module id="friendly-url" class="System.Web.TUrlMapping">
@@ -39,25 +39,25 @@ To use <tt>TUrlMapping</tt>, one must set the <tt>UrlManager</tt> property of th </com:TTextHighlighter>
</p>
-<p>
+<p id="230225" class="block-content">
The above example is part of the application configuration of the <tt>blog</tt> demo in the PRADO release. It enables recognition of the following URL formats:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>/index.php/post/123</tt> is recognized as <tt>/index.php?page=Posts.ViewPost&id=123</tt></li>
<li><tt>/index.php/archive/200605</tt> is recognized as <tt>/index.php?page=Posts.ListPost&time=200605</tt></li>
<li><tt>/index.php/category/2</tt> is recognized as <tt>/index.php?page=Posts.ListPost&cat=2</tt></li>
</ul>
-<p>
+<p id="230226" class="block-content">
The <tt>ServiceParameter</tt> and <tt>ServiceID</tt> (the default ID is 'page') set the service parameter and service ID, respectively, of the <a href="?page=Fundamentals.Modules">Request module</a>. The service parameter for the <tt>TPageService</tt> 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 <a href="?page=Fundamentals.Services">Services</a> for further details.
</p>
-<h2>Specifying URL Patterns</h2>
-<p>
+<h2 id="46023">Specifying URL Patterns</h2>
+<p id="230227" class="block-content">
<tt>TUrlMapping</tt> enables recognition of customized URL formats based on a list prespecified of URL patterns. Each pattern is specified in a <tt><url></tt> tag.
</p>
-<p>
+<p id="230228" class="block-content">
The <tt>Pattern</tt> and <tt>Parameters</tt> attribute
values are regular expression patterns that
determine the mapping criteria. The <tt>Pattern</tt> property takes
@@ -65,20 +65,20 @@ a regular expression with parameter names enclosed between a left brace '<tt>{</ and a right brace '<tt>}</tt>'. The pattens for each parameter can be set
using <tt>Parameters</tt>attribute collection.
For example,
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_230099">
<url ServiceParameter="ArticleView" pattern="articles/{year}/{month}/{day}"
parameters.year="\d{4}" parameters.month="\d{2}" parameters.day="\d+" />
</com:TTextHighlighter>
</p>
The example is equivalent to the following regular expression (it uses the "named group" feature in regular expressions available in PHP):
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_230100">
<url ServiceParmaeter="ArticleView">
<![CDATA[
/articles\/(?P<year>\d{4})\/(?P<month>\d{2})\/(?P<day>\d+)/u
]]>
</url>
</com:TTextHighlighter>
-<p>
+<p id="230229" class="block-content">
In the above example, the pattern contains 3 parameters named "<tt>year</tt>",
"<tt>month</tt>" and "<tt>day</tt>". The pattern for these parameters are,
respectively, "<tt>\d{4}</tt>" (4 digits), "<tt>\d{2}</tt>" (2 digits)
@@ -92,7 +92,7 @@ to form a complete regular expression string. property you need to escape the slash in regular expressions.
</div>
-<p>Following from the above pattern example,
+<p id="230230" class="block-content">Following from the above pattern example,
an URL "<tt>http://example.com/index.php/articles/2006/07/21</tt>" will be matched
and valid. However, "<tt>http://example.com/index.php/articles/2006/07/hello</tt>" is not
valid since the "<tt>day</tt>" parameter pattern is not satisfied.
@@ -101,19 +101,19 @@ and valid. However, "<tt>http://example.com/index.php/articles/2006/07/hello</t "<tt>/index.php/articles/2006/07/21</tt>" portion of the URL is considered.
</p>
-<p>
+<p id="230231" class="block-content">
The mapped request URL is equivalent to <tt>index.php?page=ArticleView&year=2006&month=07&day=21</tt>.
The request parameter values are available through the standard <tt>Request</tt>
object. For example, <tt>$this->Request['year']</tt>.
</p>
-<p>The URL mapping are evaluated in order they are place and only the first mapping that matches
+<p id="230232" class="block-content">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.
</p>
-<h2>Constructing Customized URLs</h2>
-<p>
+<h2 id="46024">Constructing Customized URLs</h2>
+<p id="230233" class="block-content">
Since version 3.0.6, <tt>TUrlMapping</tt> starts to support constructing customized URL formats. This is achieved by allowing users to extend <tt>TUrlMapping</tt> class and override the <tt>constructUrl</tt> method. In the applications, users can still use <tt>THttpRequest.constructUrl()</tt> or <tt>TPageService.constructUrl()</tt> to generate PRADO-recognizable URLS. The actual URL construction work is ultimately delegated to the <tt>TUrlMapping.constructUrl()</tt>, provided it is implemented.
</p>
diff --git a/demos/quickstart/protected/pages/Controls/Button.page b/demos/quickstart/protected/pages/Controls/Button.page index 37b90062..c145a4df 100644 --- a/demos/quickstart/protected/pages/Controls/Button.page +++ b/demos/quickstart/protected/pages/Controls/Button.page @@ -3,10 +3,10 @@ <h1 id="2001">TButton</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TButton" />
-<p>
+<p id="240234" class="block-content">
<tt>TButton</tt> creates a click button on a Web page. The button's caption is specified by <tt>Text</tt> property. A button is used to submit data to a page. <tt>TButton</tt> raises two server-side events, <tt>OnClick</tt> and <tt>OnCommand</tt>, when it is clicked on the client-side. The difference between <tt>OnClick</tt> and <tt>OnCommand</tt> events is that the latter event is bubbled up to the button's ancestor controls. An <tt>OnCommand</tt> event handler can use <tt>CommandName</tt> and <tt>CommandParameter</tt> associated with the event to perform specific actions.
</p>
-<p>
+<p id="240235" class="block-content">
Clicking on button can trigger form validation, if <tt>CausesValidation</tt> is true. And the validation may be restricted within a certain group of validator controls according to <tt>ValidationGroup</tt>.
</p>
<com:RunBar PagePath="Controls.Samples.TButton.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/CheckBox.page b/demos/quickstart/protected/pages/Controls/CheckBox.page index 7f2767c0..54417320 100644 --- a/demos/quickstart/protected/pages/Controls/CheckBox.page +++ b/demos/quickstart/protected/pages/Controls/CheckBox.page @@ -3,10 +3,10 @@ <h1 id="2101">TCheckBox</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TCheckBox" />
-<p>
+<p id="250236" class="block-content">
<tt>TCheckBox</tt> displays a check box on a Web page. A caption can be specified via <tt>Text</tt> and displayed beside the check box. It can appear either on the right or left of the check box, which is determined by <tt>TextAlign</tt>. You may further specify attributes applied to the text by using <tt>LabelAttributes</tt>.
</p>
-<p>
+<p id="250237" class="block-content">
To determine whether the check box is checked, test the <tt>Checked</tt> property. A <tt>CheckedChanged</tt> event is raised if the state of <tt>Checked</tt> is changed between posts to the server. If <tt>AutoPostBack</tt> is true, changing the check box state will cause postback action. And if <tt>CausesValidation</tt> is also true, upon postback validation will be performed for validators within the specified <tt>ValidationGroup</tt>.
</p>
<com:RunBar PagePath="Controls.Samples.TCheckBox.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/ClientScript.page b/demos/quickstart/protected/pages/Controls/ClientScript.page index d5687fb1..5b2147ec 100644 --- a/demos/quickstart/protected/pages/Controls/ClientScript.page +++ b/demos/quickstart/protected/pages/Controls/ClientScript.page @@ -3,7 +3,7 @@ <h1 id="2201">TClientScript</h1> <com:DocLink ClassPath="System.Web.UI.WebControls.TClientScript" /> <h2 id="2202">Including Bundled Javascript Libraries in Prado</h2> -<p> +<p id="260238" class="block-content"> <tt>TClientScript</tt> 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. </p> -<com:TTextHighlighter Language="prado" CssClass="source"> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_260101"> <com:TClientScript PradoScripts="ajax, effects" /> </com:TTextHighlighter> -<p> - The available bundled libraries included in Prado are - <ul> +<p id="260239" class="block-content"> + The available bundled libraries included in Prado are</p> + <ul id="u1" class="block-content"> <li><tt>prado</tt> : basic prado javascript framework based on Prototype</li> <li><tt>effects</tt> : visual effects from script.aculo.us</li> <li><tt>ajax</tt> : ajax and callback related based on Prototype</li> @@ -28,25 +28,24 @@ to include on the page. For following example will include the "ajax" and "effec <li><tt>rico</tt> : Rico library</li> <li><tt>colorpicker</tt> : colorpicker</li> </ul> -</p> -<p>The dependencies for each library are automatically resolved. That is, +<p id="260240" class="block-content">The dependencies for each library are automatically resolved. That is, specifying, say the "ajax", will also include the "prado" library.</p> <h2 id="2203">Including Custom Javascript Files</h2> -<p>Custom Javascript files can be register using the <tt>ScriptUrl</tt> property. +<p id="260241" class="block-content">Custom Javascript files can be register using the <tt>ScriptUrl</tt> 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 <a href="?page=Configurations.Templates3">dynamic asset tag</a>, the file "test.js" will be published automatically, that is, the file will be copied to the assets directory if necessary. </p> -<com:TTextHighlighter Language="prado" CssClass="source"> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_260102"> <com:TClientScript ScriptUrl=<%~ test.js %> /> </com:TTextHighlighter> -<p>You can include Javascript files from other servers by specifying the full URL string in +<p id="260242" class="block-content">You can include Javascript files from other servers by specifying the full URL string in the <tt>ScriptUrl</tt> property.</p> <h2 id="2204">Including Custom Javascript Code Blocks</h2> -<p> Any content within the <tt>TClientScript</tt> control tag will be considered as +<p id="260243" class="block-content"> Any content within the <tt>TClientScript</tt> control tag will be considered as Javascript code and will be rendered where it is declared.</p> </com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Controls/ColorPicker.page b/demos/quickstart/protected/pages/Controls/ColorPicker.page index 8909ad98..e0de6712 100644 --- a/demos/quickstart/protected/pages/Controls/ColorPicker.page +++ b/demos/quickstart/protected/pages/Controls/ColorPicker.page @@ -3,7 +3,7 @@ <h1 id="2201">TColorPicker</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TColorPicker" />
-<p>
+<p id="270244" class="block-content">
TBD
</p>
diff --git a/demos/quickstart/protected/pages/Controls/Data.page b/demos/quickstart/protected/pages/Controls/Data.page index 6a93ec6f..aea25ab7 100644 --- a/demos/quickstart/protected/pages/Controls/Data.page +++ b/demos/quickstart/protected/pages/Controls/Data.page @@ -2,7 +2,7 @@ <h1 id="5001">Data Controls</h1>
-<ul>
+<ul id="u1" class="block-content">
<li>
<a href="?page=Controls.DataList">TDataList</a> is used to display or modify a list of data items.
</li>
diff --git a/demos/quickstart/protected/pages/Controls/DataGrid.page b/demos/quickstart/protected/pages/Controls/DataGrid.page index 4697d0e5..83b5c3cf 100644 --- a/demos/quickstart/protected/pages/Controls/DataGrid.page +++ b/demos/quickstart/protected/pages/Controls/DataGrid.page @@ -2,24 +2,24 @@ <h1 id="5201">TDataGrid</h1>
-<p>
+<p id="590373" class="block-content">
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 <tt>DataSource</tt> or <tt>DataSourceID</tt> are bound to the rows and feed contents to cells.
</p>
-<p>
+<p id="590374" class="block-content">
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.
</p>
-<p>
+<p id="590375" class="block-content">
Rows of TDataGrid can be accessed via its <tt>Items</tt> 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 <tt>EditItemIndex</tt> or <tt>SelectedItemIndex</tt>. Note, if an item is in edit mode, then selecting this item will have no effect.
</p>
<h2 id="5202">Columns</h2>
-<p>
+<p id="590376" class="block-content">
Columns of a data grid determine how the associated cells are displayed. For example, cells associated with a <tt>TBoundColumn</tt> 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.
</p>
-<p>
+<p id="590377" class="block-content">
PRADO provides five types of columns:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>TBoundColumn</tt> associates cells with a specific field of data and displays the cells according to their modes.</li>
<li><tt>TLiteralColumn</tt> associates cells with a specific field of data and displays the cells with static texts.</li>
<li><tt>TCheckBoxColumn</tt> associates cells with a specific field of data and displays in each cell a checkbox whose check state is determined by the data field value.</li>
@@ -31,18 +31,18 @@ PRADO provides five types of columns: </ul>
<h2 id="5203">Item Styles</h2>
-<p>
+<p id="590378" class="block-content">
TDataGrid defines different styles applied to its items. For example, <tt>AlternatingItemStyle</tt> 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.
</p>
-<p>
+<p id="590379" class="block-content">
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, <tt>ItemStyle</tt>, <tt>AlternatingItemStyle</tt>, <tt>SelectedItemStyle</tt>, and <tt>EditItemStyle</tt>. Therefore, if background color is set as red in <tt>ItemStyle</tt>, <tt>EditItemStyle</tt> will also have red background color, unless it is explicitly set to a different value.
</p>
<h2 id="5204">Events</h2>
-<p>
+<p id="590380" class="block-content">
TDataGrid provides several events to facilitate manipulation of its items,
</p>
-<ul>
+<ul id="u2" class="block-content">
<li><tt>OnItemCreated</tt> - raised each time an item is newly created. When the event is raised, data and child controls are both available for the new item.</li>
<li><tt>OnItemDataBound</tt> - raised each time an item just completes databinding. When the event is raised, data and child controls are both available for the item, and the item has finished databindings of itself and all its child controls.</li>
<li><tt>OnItemCommand</tt> - raised when a child control of some item (such as a <tt>TButton</tt>) raises an <tt>OnCommand</tt> event.</li>
@@ -62,13 +62,13 @@ TDataGrid provides several events to facilitate manipulation of its items, <h2 id="5205">Using TDataGrid</h2>
<h3 id="5210">Automatically Generated Columns</h3>
-<p>
+<p id="590381" class="block-content">
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 <tt>TBoundColumn</tt>.
</p>
-<p>
+<p id="590382" class="block-content">
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,
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_590121">
public function onLoad($param) {
parent::onLoad($param);
if(!$this->IsPostBack) {
@@ -80,13 +80,13 @@ public function onLoad($param) { <com:RunBar PagePath="Controls.Samples.TDataGrid.Sample1" />
<h3 id="5211">Manually Specified Columns</h3>
-<p>
+<p id="590383" class="block-content">
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.
</p>
-<p>
+<p id="590384" class="block-content">
To manually specify columns, set <tt>AutoGenerateColumns</tt> to false, and specify the columns in a template like the following,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_590122">
<com:TDataGrid ...>
<com:TBoundColumn DataField="name" .../>
<com:TBoundColumn DataField="price" .../>
@@ -94,78 +94,78 @@ To manually specify columns, set <tt>AutoGenerateColumns</tt> to false, and spec ...
</com:TDataGrid>
</com:TTextHighlighter>
-<p>
+<p id="590385" class="block-content">
Note, if <tt>AutoGenerateColumns</tt> 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 <tt>Columns</tt> property contains only manually specified columns and no automatically generated ones.
</p>
-<p>
+<p id="590386" class="block-content">
The following example uses manually specified columns to show a list of book information,
</p>
-<ul>
+<ul id="u4" class="block-content">
<li>Book title - displayed as a hyperlink pointing to the corresponding amazon.com book page. <tt>THyperLinkColumn</tt> is used.</li>
<li>Publisher - displayed as a piece of text using <tt>TBoundColumn</tt>.</li>
<li>Price - displayed as a piece of text using <tt>TBoundColumn</tt> with output formatting string and customized styles.</li>
<li>In-stock or not - displayed as a checkbox using <tt>TCheckBoxColumn</tt>.</li>
<li>Rating - displayed as an image using <tt>TTemplateColumn</tt> which allows maximum freedom in specifying cell contents.</li>
</ul>
-<p>Pay attention to how item (row) styles and column styles cooperate together to affect the appearance of the cells in the datagrid.</p>
+<p id="590387" class="block-content">Pay attention to how item (row) styles and column styles cooperate together to affect the appearance of the cells in the datagrid.</p>
<com:RunBar PagePath="Controls.Samples.TDataGrid.Sample2" />
<h2 id="5206">Interacting with TDataGrid</h2>
-<p>
+<p id="590388" class="block-content">
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 <tt>TBoundColumn</tt> 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 <tt>TEditCommandColumn</tt> for switching item modes. In addition, <tt>TButtonColumn</tt> offers developers the flexibility of creating arbitrary buttons for various user interactions.
</p>
-<p>
+<p id="590389" class="block-content">
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: <tt>TEditCommandColumn</tt> and <tt>TButtonColumn</tt>. In addition,
<tt>TDropDownListColumn</tt> replaces the previous <tt>TTemplateColumn</tt> to allow users to select a rating from a dropdown list. Note, it is also possible to use <tt>TTemplateColumn</tt> to achieve the same task.
</p>
<com:RunBar PagePath="Controls.Samples.TDataGrid.Sample3" />
<h2 id="5207">Sorting</h2>
-<p>
+<p id="590390" class="block-content">
TDataGrid supports sorting its items according to specific columns. To enable sorting, set <tt>AllowSorting</tt> to true. This will turn column headers into clickable buttons if their <tt>SortExpression</tt> property is not empty. When users click on the header buttons, an <tt>OnSortCommand</tt> event will be raised. Developers can write handlers to respond to the sort command and sort the data according to <tt>SortExpression</tt> which is specified in the corresponding column.
</p>
-<p>
+<p id="590391" class="block-content">
The following example turns the datagrid in <a href="?page=Controls.Samples.TDataGrid.Sample2">Example 2</a> 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.
</p>
<com:RunBar PagePath="Controls.Samples.TDataGrid.Sample4" />
<h2 id="5208">Paging</h2>
-<p>
+<p id="590392" class="block-content">
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 <tt>PagerStyle</tt>. For example, <tt>PagerStyle.Visible</tt> determines whether the pager is visible or not; <tt>PagerStyle.Position</tt> indicates where the pager is displayed; and <tt>PagerStyle.Mode</tt> specifies what type of pager is displayed, a numeric one or a next-prev one.
</p>
-<p>
+<p id="590393" class="block-content">
To enable paging, set <tt>AllowPaging</tt> to true. The number of rows of data displayed in a page is specified by <tt>PageSize</tt>, while the index (zero-based) of the page currently showing to users is by <tt>CurrentPageIndex</tt>. When users click on a pager button, TDataGrid raises <tt>OnPageIndexChanged</tt> event. Typically, the event handler is written as follows,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_590123">
public function pageIndexChanged($sender,$param) {
$this->DataGrid->CurrentPageIndex=$param->NewPageIndex;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
}
</com:TTextHighlighter>
-<p>
+<p id="590394" class="block-content">
The following example enables the paging functionality of the datagrid shown in <a href="?page=Controls.Samples.TDataGrid.Sample1">Example 1</a>. In this example, you can set various pager styles interactively to see how they affect the pager display.
</p>
<com:RunBar PagePath="Controls.Samples.TDataGrid.Sample5" />
<h3 id="5212">Custom Paging</h3>
-<p>
+<p id="590395" class="block-content">
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.
</p>
-<p>
+<p id="590396" class="block-content">
To enable custom paging, set both <tt>AllowPaging</tt> and <tt>AllowCustomPaging</tt> to true. Notify TDataGrid the total number of data items (rows) available by setting <tt>VirtualItemCount</tt>. And respond to the <tt>OnPageIndexChanged</tt> event. In the event handler, use the <tt>NewPageIndex</tt> property of the event parameter to fetch the new page of data from data source. For MySQL database, this can be done by using <tt>LIMIT</tt> clause in an SQL select statement.
</p>
<com:RunBar PagePath="Controls.Samples.TDataGrid.Sample6" />
<h2 id="5209">Extending TDataGrid</h2>
-<p>
+<p id="590397" class="block-content">
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 <tt>TTemplateColumn</tt> 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.
</p>
-<p>
+<p id="590398" class="block-content">
All datagrid column components must inherit from <tt>TDataGridColumn</tt>. The main method that needs to be overridden is <tt>initializeCell()</tt> 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 <tt>Header</tt>, <tt>AltneratingItem</tt>, etc.), different content may be created according to the item type. For the image column example, one may want to create a <tt>TImage</tt> control within cells residing in items of <tt>Item</tt> and <tt>AlterantingItem</tt> types.
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_590124">
class ImageColumn extends TDataGridColumn {
...
public function initializeCell($cell,$columnIndex,$itemType) {
@@ -178,7 +178,7 @@ class ImageColumn extends TDataGridColumn { }
}
</com:TTextHighlighter>
-<p>
+<p id="590399" class="block-content">
In <tt>initializeCell()</tt>, remember to call the parent implementation, as it initializes cells in items of <tt>Header</tt> and <tt>Footer</tt> types.
</p>
diff --git a/demos/quickstart/protected/pages/Controls/DataList.page b/demos/quickstart/protected/pages/Controls/DataList.page index 75541564..1630ed96 100644 --- a/demos/quickstart/protected/pages/Controls/DataList.page +++ b/demos/quickstart/protected/pages/Controls/DataList.page @@ -1,16 +1,16 @@ <com:TContent ID="body" >
<h1 id="5101">TDataList</h1>
-<p>
+<p id="580362" class="block-content">
TDataList is used to display or modify a list of data items specified by its <tt>DataSource</tt> or <tt>DataSourceID</tt> property. Each data item is displayed by a data list item which is a child control of the data list. The <tt>Items</tt> property contains the list of all data list items.
</p>
-<p>
+<p id="580363" class="block-content">
TDataList displays its items in either a <tt>Table</tt> or <tt>Flow</tt> layout, which is specified by the <tt>RepeatLayout</tt> 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 <tt>Table</tt>, the table's cellpadding and cellspacing can be adjusted by <tt>CellPadding</tt> and <tt>CellSpacing</tt> properties, respectively. And <tt>Caption</tt> and <tt>CaptionAlign</tt> 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 <tt>RepeatColumns</tt> property, while the <tt>RepeatDirection</tt> governs the order of the items being rendered.
</p>
-<p>
+<p id="580364" class="block-content">
Each data list item is created according to one of the seven kinds of templates that developers may specified for a TDataList,
</p>
-<ul>
+<ul id="u5" class="block-content">
<li><tt>HeaderTemplate</tt> - the template used for displaying content at the beginning of a data list;</li>
<li><tt>FooterTemplate</tt> - the template used for displaying content at the end of a data list;</li>
<li><tt>ItemTemplate</tt> - the template used for displaying every data list item. If <tt>AlternatingItemTemplate</tt> is also defined, <tt>ItemTemplate</tt> will be used for displaying item 1, 3, 5, etc.</li>
@@ -19,19 +19,19 @@ Each data list item is created according to one of the seven kinds of templates <li><tt>EditItemTemplate</tt> - the template used for displaying items in edit mode.</li>
<li><tt>SelectedItemTemplate</tt> - the template used for displaying items in selected mode.</li>
</ul>
-<p>
+<p id="580365" class="block-content">
Each of the above templates is associated with a style property that is applied to the items using the template. For example, <tt>ItemTemplate</tt> is associated with a property named <tt>AlternatingItemStyle</tt>. Through this property, one can set CSS style fields or CSS classes for the data list items.
</p>
-<p>
+<p id="580366" class="block-content">
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, <tt>ItemStyle</tt>, <tt>AlternatingItemStyle</tt>, <tt>SelectedItemStyle</tt>, and <tt>EditItemStyle</tt>. Therefore, if background color is set as red in <tt>ItemStyle</tt>, <tt>EditItemStyle</tt> will also have red background color, unless it is explicitly set to a different value.
</p>
-<p>
+<p id="580367" class="block-content">
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 <tt>EditItemIndex</tt> or <tt>SelectedItemIndex</tt>. Note, if an item is in edit mode, then selecting this item will have no effect.
</p>
-<p>
+<p id="580368" class="block-content">
TDataList provides several events to facilitate manipulation of its items,
</p>
-<ul>
+<ul id="u7" class="block-content">
<li><tt>OnItemCreated</tt> - raised each time an item is newly created. When the event is raised, data and child controls are both available for the new item.</li>
<li><tt>OnItemDataBound</tt> - raised each time an item just completes databinding. When the event is raised, data and child controls are both available for the item, and the item has finished databindings of itself and all its child controls.</li>
<li><tt>OnItemCommand</tt> - raised when a child control of some item (such as a <tt>TButton</tt>) raises an <tt>OnCommand</tt> event.</li>
@@ -45,17 +45,17 @@ TDataList provides several events to facilitate manipulation of its items, </ul>
</li>
</ul>
-<p>
+<p id="580369" class="block-content">
The following example shows how to use TDataList to display tabular data, with different layout and styles.
</p>
<com:RunBar PagePath="Controls.Samples.TDataList.Sample1" />
-<p>
+<p id="580370" class="block-content">
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.
</p>
-<p>
+<p id="580371" class="block-content">
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, <tt>DataKeys</tt> property is used.
</p>
-<p>
+<p id="580372" class="block-content">
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.
</p>
<com:RunBar PagePath="Controls.Samples.TDataList.Sample2" />
diff --git a/demos/quickstart/protected/pages/Controls/DatePicker.page b/demos/quickstart/protected/pages/Controls/DatePicker.page index 36d2f435..039540ce 100644 --- a/demos/quickstart/protected/pages/Controls/DatePicker.page +++ b/demos/quickstart/protected/pages/Controls/DatePicker.page @@ -3,14 +3,14 @@ <h1 id="2301">TDatePicker</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TDatePicker" />
-<p><tt>TDatePicker</tt> displays a text box for date input purpose.
+<p id="280245" class="block-content"><tt>TDatePicker</tt> 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 <tt>DateFormat</tt> property. Valid formats are the combination of the
following tokens:
-<com:TTextHighlighter Language="text" CssClass="source">
+<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_280103">
Character Format Pattern (en-US)
---------------------------------------------------------------------
d day digit
@@ -24,52 +24,50 @@ Character Format Pattern (en-US) ---------------------------------------------------------------------
</com:TTextHighlighter>
-<p>
+<p id="280246" class="block-content">
The date of the date picker can be set using the <tt>Date</tt> or <tt>Timestamp</tt>
properties. The <tt>Date</tt> property value must be in the same format as the pattern
specified in the <tt>DateFormat</tt> property. The <tt>Timestamp</tt> property
only accepts integers such as the Unix timestamp.
</p>
-<p>
-TDatePicker has three <tt>Mode</tt> to show the date picker popup.
- <ul>
+<p id="280247" class="block-content">
+TDatePicker has three <tt>Mode</tt> to show the date picker popup.</p>
+ <ul id="u1" class="block-content">
<li><tt>Basic</tt> - Only shows a text input, focusing on the input shows the date picker.</li>
<li><tt>Button</tt> - Shows a button next to the text input, clicking on the button shows the date, button text can be by the <tt>ButtonText</tt> property.</li>
<li><tt>ImageButton</tt> - Shows an image next to the text input, clicking on the image shows the date picker, image source can be change through the <tt>ImageUrl</tt> property.</li>
</ul>
-</p>
-<p>The <tt>CssClass</tt> property can be used to override the CSS class name
+<p id="280248" class="block-content">The <tt>CssClass</tt> property can be used to override the CSS class name
for the date picker panel. The <tt>CalendarStyle</tt> property changes the overall calendar style.
-The following <tt>CalendarStyle</tt> values are available:
- <ul>
+The following <tt>CalendarStyle</tt> values are available:</p>
+ <ul id="u2" class="block-content">
<li><tt>default</tt> - The default calendar style.</li>
</ul>
-</p>
-<p>The <tt>InputMode</tt> property can be set to "TextBox" or "DropDownList" with
+<p id="280249" class="block-content">The <tt>InputMode</tt> property can be set to "TextBox" or "DropDownList" with
default as "TextBox". In <tt>DropDownList</tt> mode, in addition to the popup date picker, three
drop down list (day, month and year) are presented to select the date .
When <tt>InputMode</tt> equals "DropDownList", the order and appearance of the date, month, and year
will depend on the pattern specified in <tt>DateFormat</tt> property.
</p>
-<p>The popup date picker can be hidden by specifying <tt>ShowCalendar</tt> as false. Much of the
+<p id="280250" class="block-content">The popup date picker can be hidden by specifying <tt>ShowCalendar</tt> as false. Much of the
text of the popup date picker can be changed to a different language using the <tt>Culture</tt> property.
</p>
-<p>The calendar picker year limit can be set using the <tt>FromYear</tt> and <tt>UpToYear</tt> properties
+<p id="280251" class="block-content">The calendar picker year limit can be set using the <tt>FromYear</tt> and <tt>UpToYear</tt> properties
where <tt>FromYear</tt> is the starting year and <tt>UpToYear</tt> is the last year selectable.
The starting day of the week can be changed by the <tt>FirstDayOfWeek</tt> property, with 0 as Sunday, 1 as Monday, etc.
</p>
-<p><b>Note 1:</b> If the <tt>InputMode</tt> is "TextBox", the <tt>DateFormat</tt> should
+<p id="280252" class="block-content"><b>Note 1:</b> If the <tt>InputMode</tt> is "TextBox", the <tt>DateFormat</tt> should
only <b>NOT</b> contain <code>MMM</code> or <code>MMMM</code> patterns. The
server side date parser will not be able to determine the correct date if <code>MMM</code> or
<code>MMMM</code> are used. When <tt>InputMode</tt> equals "DropDownList", all patterns can be used.</p>
-<p><b>Note 2:</b> When the <tt>TDatePicker</tt> is used together
+<p id="280253" class="block-content"><b>Note 2:</b> When the <tt>TDatePicker</tt> is used together
with a validator, the <tt>DateFormat</tt> property of the validator must be equal to
the <tt>DateFormat</tt> of the <tt>TDatePicker</tt> <b>AND</b> must set <tt>DataType</tt>="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 @@ <h1 id="2401">TExpression</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TExpression" />
-<p>
+<p id="290254" class="block-content">
<tt>TExpression</tt> evaluates a PHP expression and displays the evaluation result. To specify the expression to be evaluated, set the <tt>Expression</tt> property. Note, <tt>TExpression</tt> evaluates the expression during the rendering control lifecycle.
</p>
-<p>
+<p id="290255" class="block-content">
The context of the expression in a <tt>TExpression</tt> control is the control itself. That is, <tt>$this</tt> 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 <tt>TExpression</tt> control.
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_290104">
<com:TExpression Expression="$this->Page->Title" />
</com:TTextHighlighter>
-<p>
+<p id="290256" class="block-content">
Be aware, since <tt>TExpression</tt> allows execution of arbitrary PHP code, in general you should not use it to evaluate expressions submitted by your application users.
</p>
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 @@ <h1 id="2501">TFileUpload</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TFileUpload" />
-<p>
+<p id="300257" class="block-content">
<tt>TFileUpload</tt> 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.
</p>
-<p>
+<p id="300258" class="block-content">
<tt>TFileUpload</tt> raises an <tt>OnFileUpload</tt> event when it is post back. The property <tt>HasFile</tt> indicates whether the file upload is successful or not. If successful, the uploaded file may be saved on the server by calling <tt>saveAs()</tt> method.
</p>
-<p>
+<p id="300259" class="block-content">
The following properties give the information about the uploaded file:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>FileName</tt> - the original client-side file name without directory information.</li>
<li><tt>FileType</tt> - the MIME type of the uploaded file.</li>
<li><tt>FileSize</tt> - the file size in bytes.</li>
<li><tt>LocalName</tt> - the absolute file path of the uploaded file on the server. Note, this file will be deleted after the current page request is completed. Call <tt>saveAs()</tt> to save the uploaded file.</li>
</ul>
-<p>
+<p id="300260" class="block-content">
If the file upload is unsuccessful, the property <tt>ErrorCode</tt> gives the error code describing the cause of failure. See <a href="http://www.php.net/manual/en/features.file-upload.errors.php">PHP documentation</a> for a complete explanation of the possible error codes.
</p>
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 @@ <h1 id="2601">THead</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.THead" />
-<p>
+<p id="310261" class="block-content">
TBD
</p>
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 @@ <h1 id="2701">THiddenField</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.THiddenField" />
-<p>
+<p id="320262" class="block-content">
<tt>THiddenField</tt> represents a hidden field on a Web page. The value of the hidden field can be accessed via its <tt>Value</tt> property.
</p>
-<p>
+<p id="320263" class="block-content">
<tt>THiddenField</tt> raises an <tt>OnValueChanged</tt> event if its value is changed during postback.
</p>
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 @@ <h1 id="2801">THtmlArea</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.THtmlArea" />
-<p>
+<p id="330264" class="block-content">
<tt>THtmlArea</tt> displays a WYSIWYG text input field on a Web page to collect input in HTML format. The text displayed in the <tt>THtmlArea</tt> control is specified or determined by using the <tt>Text</tt> property. To adjust the size of the input region, set <tt>Width</tt> and <tt>Height</tt> properties instead of <tt>Columns</tt> and <tt>Rows</tt> because the latter has no meaning under this situation. To disable the WYSIWYG feature, set <tt>EnableVisualEdit</tt> to false.
</p>
-<p>
+<p id="330265" class="block-content">
<tt>THtmlArea</tt> provides the WYSIWYG feature by wrapping the functionalities provided by the <a href="http://tinymce.moxiecode.com/">TinyMCE project</a>.
</p>
-<p>
+<p id="330266" class="block-content">
The default editor gives only the basic tool bar. To change or add additional tool bars, use the <tt>Options</tt> property to add additional editor options with each options on a new line. See <a href="http://tinymce.moxiecode.com/tinymce/docs/index.html">TinyMCE website</a> for a complete list of options. The following example displays a toolbar specific for HTML table manipulation,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_330105">
<com:THtmlArea>
<prop:Options>
plugins : "table"
@@ -23,7 +23,7 @@ The default editor gives only the basic tool bar. To change or add additional to </com:THtmlArea>
</com:TTextHighlighter>
-<p>
+<p id="330267" class="block-content">
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.
</p>
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 @@ <h1 id="2901">THyperLink</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.THyperLink" />
-<p>
+<p id="340268" class="block-content">
<tt>THyperLink</tt> displays a hyperlink on a page. The hyperlink URL is specified via the <tt>NavigateUrl</tt> property, and link text is via the <tt>Text</tt> property. The link target is specified via the <tt>Target</tt> property. It is also possible to display an image by setting the <tt>ImageUrl</tt> property. In this case, <tt>Text</tt> is displayed as the alternate text of the image. If both <tt>ImageUrl</tt> and <tt>Text</tt> are empty, the content enclosed within the control tag will be rendered.
</p>
<com:RunBar PagePath="Controls.Samples.THyperLink.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/Image.page b/demos/quickstart/protected/pages/Controls/Image.page index 1e8df3de..dc68a8bd 100644 --- a/demos/quickstart/protected/pages/Controls/Image.page +++ b/demos/quickstart/protected/pages/Controls/Image.page @@ -3,7 +3,7 @@ <h1 id="3201">TImage</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TImage" />
-<p>
+<p id="370273" class="block-content">
<tt>TImage</tt> displays an image on a page. The image is specified via the <tt>ImageUrl</tt> property which takes a relative or absolute URL to the image file. The alignment of the image displayed is set by the <tt>ImageAlign</tt> property. To set alternate text or long description of the image, use <tt>AlternateText</tt> or <tt>DescriptionUrl</tt>, respectively.
</p>
<com:RunBar PagePath="Controls.Samples.TImage.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/ImageButton.page b/demos/quickstart/protected/pages/Controls/ImageButton.page index a4f8d30f..22ec483f 100644 --- a/demos/quickstart/protected/pages/Controls/ImageButton.page +++ b/demos/quickstart/protected/pages/Controls/ImageButton.page @@ -3,7 +3,7 @@ <h1 id="3001">TImageButton</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TImageButton" />
-<p>
+<p id="350269" class="block-content">
<tt>TImageButton</tt> is also similar to <tt>TButton</tt>, except that <tt>TImageButton</tt> displays the button as an image. The image is specified via <tt>ImageUrl</tt>, and the alternate text is specified by <tt>Text</tt>. 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 <tt>OnClick</tt> event (not <tt>OnCommand</tt>).
</p>
<com:RunBar PagePath="Controls.Samples.TImageButton.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/ImageMap.page b/demos/quickstart/protected/pages/Controls/ImageMap.page index 002861a3..162500e3 100644 --- a/demos/quickstart/protected/pages/Controls/ImageMap.page +++ b/demos/quickstart/protected/pages/Controls/ImageMap.page @@ -3,16 +3,16 @@ <h1 id="3101">TImageMap</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TImageMap" />
-<p>
+<p id="360270" class="block-content">
<tt>TImageMap</tt> represents an image on a Web page with predefined hotspot regions that can respond differently to users' clicks on them. Depending on the <tt>HotSpotMode</tt> of the hotspot region, clicking on the hotspot may trigger a postback or navigate to a specified URL.
</p>
-<p>
+<p id="360271" class="block-content">
Each hotspot is described using a <tt>THotSpot</tt> object and is maintained in the <tt>HotSpots</tt> collection in <tt>TImageMap</tt>. A hotspot can be a circle, rectangle, polygon, etc.
</p>
-<p>
+<p id="360272" class="block-content">
Hotspots can be added to <tt>TImageMap</tt> via its <tt>HotSpots</tt> property or in a template like the following,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_360106">
<com:TImageMap ... >
<com:TCircleHotSpot ... />
<com:TRectangleHotSpot ... />
diff --git a/demos/quickstart/protected/pages/Controls/InlineFrame.page b/demos/quickstart/protected/pages/Controls/InlineFrame.page index efd5144d..08b47f21 100644 --- a/demos/quickstart/protected/pages/Controls/InlineFrame.page +++ b/demos/quickstart/protected/pages/Controls/InlineFrame.page @@ -3,20 +3,20 @@ <h1 id="3301">TInlineFrame</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TInlineFrame" />
-<p>
+<p id="380274" class="block-content">
<tt>TInlineFrame</tt> displays an inline frame (<iframe>) on a Web page. The location of the frame content is specified by the <tt>FrameUrl</tt> property.
</p>
-<p>
+<p id="380275" class="block-content">
The appearance of a <tt>TInlineFrame</tt> may be customized with the following properties, in addition to those inherited from <tt>TWebControl</tt>.
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>Align</tt> - the alignment of the frame.</li>
<li><tt>DescriptionUrl</tt> - the URI of a long description of the frame's contents.</li>
<li><tt>MarginWidth</tt> and <tt>MarginHeight</tt> - the number of pixels to use as the left/right margins and top/bottom margins, respectively.</li>
<li><tt>ScrollBars</tt> - whether scrollbars are provided for the inline frame. By default, it is <tt>Auto</tt>, meaning the scroll bars appear as needed. Setting it as <tt>None</tt> or <tt>Both</tt> to explicitly hide or show the scroll bars.</li>
</ul>
-<p>
+<p id="380276" class="block-content">
The following samples show <tt>TInlineFrame</tt> with different property settings. The Google homepage is used as the frame content.
</p>
<com:RunBar PagePath="Controls.Samples.TInlineFrame.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/JavascriptLogger.page b/demos/quickstart/protected/pages/Controls/JavascriptLogger.page index 2c0032f8..a41495d2 100644 --- a/demos/quickstart/protected/pages/Controls/JavascriptLogger.page +++ b/demos/quickstart/protected/pages/Controls/JavascriptLogger.page @@ -3,28 +3,28 @@ <h1 id="3401">TJavascriptLogger</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TJavascriptLogger" />
-<p>
+<p id="390277" class="block-content">
<tt>TJavascriptLogger</tt> provides logging for client-side javascript. It is mainly a wrapper of the Javascript developed at <a href="http://gleepglop.com/javascripts/logger/">http://gleepglop.com/javascripts/logger/</a>.
</p>
-<p>
+<p id="390278" class="block-content">
To use <tt>TJavascriptLogger</tt>, simply place the following component tag in a page template.
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_390107">
<com:TJavascriptLogger />
</com:TTextHighlighter>
-<p>
+<p id="390279" class="block-content">
Then, the client-side Javascript may contain the following statements. When they are executed, they will appear in the logger window.
</p>
-<com:TTextHighlighter Language="js" CssClass="source">
+<com:TTextHighlighter Language="js" CssClass="source block-content" id="code_390108">
Logger.info('something happend');
Logger.warn('A warning');
Logger.error('This is an error');
Logger.debug('debug information');
</com:TTextHighlighter>
-<p>
+<p id="390280" class="block-content">
To toggle the visibility of the logger and console on the browser window, press ALT-D (or CTRL-D on OS X).
</p>
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 @@ <h1 id="3501">TLabel</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TLabel" />
-<p>
+<p id="400281" class="block-content">
<tt>TLabel</tt> displays a piece of text on a Web page. The text to be displayed is set via its <tt>Text</tt> property. If <tt>Text</tt> is empty, content enclosed within the <tt>TLabel</tt> component tag will be displayed. <tt>TLabel</tt> may also be used as a form label associated with some control on the form. Since <tt>Text</tt> is not HTML-encoded when being rendered, make sure it does not contain dangerous characters that you want to avoid.
</p>
<com:RunBar PagePath="Controls.Samples.TLabel.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/LinkButton.page b/demos/quickstart/protected/pages/Controls/LinkButton.page index e0255141..9c586ed3 100644 --- a/demos/quickstart/protected/pages/Controls/LinkButton.page +++ b/demos/quickstart/protected/pages/Controls/LinkButton.page @@ -3,7 +3,7 @@ <h1 id="3601">TLinkButton</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TLinkButton" />
-<p>
+<p id="410282" class="block-content">
<tt>TLinkButton</tt> is similar to <tt>TButton</tt> in every aspect except that <tt>TLinkButton</tt> is displayed as a hyperlink. The link text is determined by its <tt>Text</tt> property. If the <tt>Text</tt> 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.
</p>
<com:RunBar PagePath="Controls.Samples.TLinkButton.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/List.page b/demos/quickstart/protected/pages/Controls/List.page index b5915693..c9fef3ab 100644 --- a/demos/quickstart/protected/pages/Controls/List.page +++ b/demos/quickstart/protected/pages/Controls/List.page @@ -1,12 +1,12 @@ <com:TContent ID="body" >
<h1 id="4801">List Controls</h1>
-<p>
+<p id="550329" class="block-content">
List controls covered in this section all inherit directly or indirectly from <tt>TListControl</tt>. Therefore, they share the same set of commonly used properties, including,
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>Items</tt> - list of items in the control. The items are of type <tt>TListItem</tt>. The item list can be populated via databinding or specified in templates like the following:
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_550115">
<com:TListBox>
<com:TListItem Text="text 1" Value="value 1" />
<com:TListItem Text="text 2" Value="value 2" Selected="true" />
@@ -22,12 +22,12 @@ List controls covered in this section all inherit directly or indirectly from <t <li><tt>CausesValidation</tt> - whether validation should be performed when postback is triggered by the list control.</li>
</ul>
-<p>
+<p id="550330" class="block-content">
Since <tt>TListControl</tt> inherits from <tt>TDataBoundControl</tt>, these list controls also share a common operation known as <tt>databinding</tt>. The <tt>Items</tt> can be populated from preexisting data specified by <tt>DataSource</tt> or <tt>DataSourceID</tt>. A function call to <tt>dataBind()</tt> will cause the data population. For list controls, data can be specified in the following two kinds of format:
</p>
-<ul>
+<ul id="u2" class="block-content">
<li>one-dimensional array or objects implementing <tt>ITraversable</tt> : array keys will be used as list item values, and array values will be used as list item texts. For example
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_550116">
$listbox->DataSource=array(
'key 1'=>'item 1',
'key 2'=>'item 2',
@@ -36,7 +36,7 @@ $listbox->dataBind(); </com:TTextHighlighter>
</li>
<li>tabular (two-dimensional) data : each row of data populates a single list item. The list item value is specified by the data member indexed with <tt>DataValueField</tt>, and the list item text by <tt>DataTextField</tt>. For example,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_550117">
$listbox->DataTextField='name';
$listbox->DataValueField='id';
$listbox->DataSource=array(
@@ -49,22 +49,22 @@ $listbox->dataBind(); </ul>
<h2 id="4802">TListBox</h2>
-<p>
+<p id="550331" class="block-content">
<tt>TListBox</tt> displays a list box that allows single or multiple selection. Set the property <tt>SelectionMode</tt> as <tt>Single</tt> to make a single selection list box, and <tt>Multiple</tt> a multiple selection list box. The number of rows displayed in the box is specified via the <tt>Rows</tt> property value.
</p>
<com:RunBar PagePath="Controls.Samples.TListBox.Home" />
<h2 id="4803">TDropDownList</h2>
-<p>
+<p id="550332" class="block-content">
<tt>TDropDownList</tt> displays a dropdown list box that allows users to select a single option from a few prespecified ones.
</p>
<com:RunBar PagePath="Controls.Samples.TDropDownList.Home" />
<h2 id="4804">TCheckBoxList</h2>
-<p>
+<p id="550333" class="block-content">
<tt>TCheckBoxList</tt> displays a list of checkboxes on a Web page. The alignment of the text besides each checkbox can be specified <tt>TextAlign</tt>. The layout of the checkboxes can be controlled by the following properties:
</p>
-<ul>
+<ul id="u3" class="block-content">
<li><tt>RepeatLayout</tt> - can be either <tt>Table</tt> or <tt>Flow</tt>. A <tt>Table</tt> uses HTML table cells to organize the checkboxes, while a <tt>Flow</tt> uses HTML span tags and breaks for the organization. With <tt>Table</tt> layout, you can set <tt>CellPadding</tt> and <tt>CellSpacing</tt>.</li>
<li><tt>RepeatColumns</tt> - how many columns the checkboxes should be displayed in.</li>
<li><tt>RepeatDirection</tt> - how to traverse the checkboxes, in a horizontal way or a vertical way (because the checkboxes are displayed in a matrix-like layout).</li>
@@ -73,19 +73,19 @@ $listbox->dataBind(); <com:RunBar PagePath="Controls.Samples.TCheckBoxList.Home" />
<h2 id="4805">TRadioButtonList</h2>
-<p>
+<p id="550334" class="block-content">
<tt>TRadioButtonList</tt> is similar to <tt>TCheckBoxList</tt> in every aspect except that each <tt>TRadioButtonList</tt> displays a group of radiobuttons. Only one of the radiobuttions can be selected (<tt>TCheckBoxList</tt> allows multiple selections.)
</p>
<com:RunBar PagePath="Controls.Samples.TRadioButtonList.Home" />
<h2 id="4806">TBulletedList</h2>
-<p>
+<p id="550335" class="block-content">
<tt>TBulletedList</tt> displays items in a bullet format on a Web page. The style of the bullets can be specified by <tt>BulletStyle</tt>. When the style is <tt>CustomImage</tt>, the bullets are displayed as images, which is specified by <tt>BulletImageUrl</tt>.
</p>
-<p>
+<p id="550336" class="block-content">
<tt>TBulletedList</tt> displays the item texts in three different modes,
</p>
-<ul>
+<ul id="u4" class="block-content">
<li><tt>Text</tt> - the item texts are displayed as static texts;</li>
<li><tt>HyperLink</tt> - each item is displayed as a hyperlink whose URL is given by the item value, and <tt>Target</tt> property can be used to specify the target browser window;</li>
<li><tt>LinkButton</tt> - each item is displayed as a link button which posts back to the page if a user clicks on that, and the event <tt>OnClick</tt> will be raised under such a circumstance.</li>
diff --git a/demos/quickstart/protected/pages/Controls/Literal.page b/demos/quickstart/protected/pages/Controls/Literal.page index d5d40a13..ade7bc07 100644 --- a/demos/quickstart/protected/pages/Controls/Literal.page +++ b/demos/quickstart/protected/pages/Controls/Literal.page @@ -3,20 +3,20 @@ <h1 id="3701">TLiteral</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TLiteral" />
-<p>
+<p id="420283" class="block-content">
<tt>TLiteral</tt> displays a static text on a Web page. <tt>TLiteral</tt> is similar to the <tt>TLabel</tt> control, except that the <tt>TLiteral</tt>
* control has no style properties, such as <tt>BackColor</tt>, <tt>Font</tt>, etc.
</p>
-<p>
+<p id="420284" class="block-content">
The text displayed by <tt>TLiteral</tt> can be programmatically controlled by setting the <tt>Text</tt> property. The text displayed may be HTML-encoded if the <tt>Encode</tt> is true (the default value is false).
</p>
-<p>
+<p id="420285" class="block-content">
<tt>TLiteral</tt> will render the contents enclosed within its component tag if <tt>Text</tt> is empty.
</p>
-<p>
+<p id="420286" class="block-content">
Be aware, if <tt>Encode</tt> is false, make sure <tt>Text</tt> does not contain unwanted characters that may bring security vulnerabilities.
</p>
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 @@ <h1 id="3801">TMultiView</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TMultiView" />
-<p>
+<p id="430287" class="block-content">
<tt>TMultiView</tt> serves as a container for a group of <tt>TView</tt> controls, which can be retrieved by the <tt>Views</tt> property. Each view contains child controls. <tt>TMultiView</tt> determines which view and its child controls are visible. At any time, at most one view is visible (called <i>active</i>). To make a view active, set <tt>ActiveView</tt> or <tt>ActiveViewIndex</tt>. Note, by default there is no active view.
</p>
-<p>
+<p id="430288" class="block-content">
To add a view to <tt>TMultiView</tt>, manipulate the <tt>Views</tt> collection or add it in template as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_430109">
<com:TMultiView>
<com:TView>
view 1 content
@@ -20,21 +20,21 @@ To add a view to <tt>TMultiView</tt>, manipulate the <tt>Views</tt> collection o </com:TMultiView>
</com:TTextHighlighter>
-<p>
+<p id="430289" class="block-content">
<tt>TMultiView</tt> responds to the following command events to manage the visibility of its views.
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>NextView</tt> : switch to the next view (with respect to the currently active view).
<li><tt>PreviousView</tt> : switch to the previous view (with respect to the currently active view).
<li><tt>SwitchViewID</tt> : switch to a view by its ID path. The ID path is fetched from the command parameter.
<li><tt>SwitchViewIndex</tt> : switch to a view by its zero-based index in the <tt>Views</tt> collection. The index is fetched from the command parameter.
</ul>
-<p>
+<p id="430290" class="block-content">
Upon postback, if the active view index is changed, <tt>TMultiView</tt> will raise an <tt>OnActiveViewChanged</tt> event.
</p>
-<p>
+<p id="430291" class="block-content">
The <a href="?page=Fundamentals.Samples.Hangman.Home">Hangman game</a> is a typical use of <tt>TMultiView</tt>. The following example demonstrates another usage of <tt>TMultiView</tt>.
</p>
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 @@ <com:TContent ID="body" >
<h1 id="5401">Writing New Controls</h1>
-<p>
+<p id="660428" class="block-content">
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.
</p>
-<p>
+<p id="660429" class="block-content">
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 <tt>TControl</tt> or its child classes.
</p>
<h2 id="5402">Composition of Existing Controls</h2>
-<p>
+<p id="660430" class="block-content">
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 <a href="?page=Fundamentals.Components">subproperties</a>.
</p>
-<p>
+<p id="660431" class="block-content">
One can compose a new control in two ways. One is to extend <tt>TCompositeControl</tt> and override the <tt>TControl::createChildControls()</tt> method. The other is to extend <tt>TTemplateControl</tt> (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.
</p>
-<p>
+<p id="660432" class="block-content">
As an example, we show how to create a labeled textbox called <tt>LabeledTextBox</tt> using the above two approaches. A labeled textbox displays a label besides a textbox. We want reuse the PRADO provided <tt>TLabel</tt> and <tt>TTextBox</tt> to accomplish this task.
</p>
<h3 id="5404">Composition by Writing Templates</h3>
-<p>
+<p id="660433" class="block-content">
We need two files: a control class file named <tt>LabeledTextBox.php</tt> and a control template file named <tt>LabeledTextBox.tpl</tt>. Both must reside under the same directory.
</p>
-<p>
+<p id="660434" class="block-content">
Like creating a PRADO page, we can easily write down the content in the control template file.
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_660129">
<com:TLabel ID="Label" ForControl="TextBox" />
<com:TTextBox ID="TextBox" />
</com:TTextHighlighter>
-<p>
+<p id="660435" class="block-content">
The above template specifies a <tt>TLabel</tt> control named <tt>Label</tt> and a <tt>TTextBox</tt> control named <tt>TextBox</tt>. We would to expose these two controls. This can be done by defining a property for each control in the <tt>LabeledTextBox</tt> class file. For example, we can define a <tt>Label</tt> property as follows,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_660130">
class LabeledTextBox extends TTemplateControl {
public function getLabel() {
$this->ensureChildControls();
@@ -41,19 +41,19 @@ class LabeledTextBox extends TTemplateControl { }
}
</com:TTextHighlighter>
-<p>
+<p id="660436" class="block-content">
In the above, the method call to <tt>ensureChildControls()</tt> ensures that both the label and the textbox controls are created (from template) when the <tt>Label</tt> property is accessed. The <tt>TextBox</tt> property can be implemented similarly.
</p>
<com:RunBar PagePath="Controls.Samples.LabeledTextBox1.Home" />
<h3 id="5405">Composition by Overriding <tt>createChildControls()</tt></h3>
-<p>
+<p id="660437" class="block-content">
For a composite control as simple as <tt>LabeledTextBox</tt>, it is better to create it by extending <tt>TCompositeControl</tt> and overriding the <tt>createChildControls()</tt> method, because it does not use templates and thus saves template parsing time.
</p>
-<p>
+<p id="660438" class="block-content">
Complete code for <tt>LabeledTextBox</tt> is shown as follows,
</p>
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_660131">
class LabeledTextBox extends TCompositeControl {
private $_label;
private $_textbox;
@@ -81,37 +81,37 @@ class LabeledTextBox extends TCompositeControl { <com:RunBar PagePath="Controls.Samples.LabeledTextBox2.Home" />
<h3 id="5406">Using <tt>LabeledTextBox</tt></h3>
-<p>
+<p id="660439" class="block-content">
To use <tt>LabeledTextBox</tt> control, first we need to include the corresponding class file. Then in a page template, we can write lines like the following,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_660132">
<com:LabeledTextBox ID="Input" Label.Text="Username" />
</com:TTextHighlighter>
-<p>
+<p id="660440" class="block-content">
In the above, <tt>Label.Text</tt> is a subproperty of <tt>LabeledTextBox</tt>, which refers to the <tt>Text</tt> property of the <tt>Label</tt> property. For other details of using <tt>LabeledTextBox</tt>, see the above online examples.
</p>
<h2 id="5403">Extending Existing Controls</h2>
-<p>
+<p id="660441" class="block-content">
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.
</p>
-<p>
+<p id="660442" class="block-content">
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 <tt>TLabel</tt> control, so that it displays a red label by default. This would merely involves setting the <tt>ForeColor</tt> property to <tt>"red"</tt> 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 <tt>TControl</tt> or <tt>TWebControl</tt>.
</p>
-<p>
+<p id="660443" class="block-content">
In this section, we mainly introduce the base control classes <tt>TControl</tt> and <tt>TWebControl</tt>, 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.
</p>
<h3 id="5407">Extending <tt>TControl</tt></h3>
-<p>
+<p id="660444" class="block-content">
<tt>TControl</tt> is the base class of all control classes. Two methods are of the most importance for derived control classes:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>addParsedObject()</tt> - this method is invoked for each component or text string enclosed within the component tag specifying the control in a template. By default, the enclosed components and text strings are added into the <tt>Controls</tt> collection of the control. Derived controls may override this method to do special processing about the enclosed content. For example, <tt>TListControl</tt> only accepts <tt>TListItem</tt> components to be enclosed within its component tag, and these components are added into the <tt>Items</tt> collection of <tt>TListControl</tt>.
<li><tt>render()</tt> - this method renders the control. By default, it renders items in the <tt>Controls</tt> collection. Derived controls may override this method to give customized presentation.</li>
</ul>
Other important properties and methods include:
-<ul>
+<ul id="u2" class="block-content">
<li><tt>ID</tt> - a string uniquely identifying the control among all controls of the same naming container. An automatic ID will be generated if the ID property is not set explicitly.</li>
<li><tt>UnqiueID</tt> - a fully qualified ID uniquely identifying the control among all controls on the current page hierarchy. It can be used to locate a control in the page hierarchy by calling <tt>TControl::findControl()</tt> method. User input controls often use it as the value of the name attribute of the HTML input element.</li>
<li><tt>ClientID</tt> - similar to <tt>UniqueID</tt>, except that it is mainly used for presentation and is commonly used as HTML element id attribute value. Do not rely on the explicit format of <tt>ClientID</tt>.</li>
@@ -126,27 +126,27 @@ Other important properties and methods include: </ul>
<h3 id="5408">Extending <tt>TWebControl</tt></h3>
-<p>
+<p id="660445" class="block-content">
<tt>TWebControl</tt> 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 <tt>TControl::render()</tt> into the following methods that are more suitable for rendering an HTML element:
</p>
-<ul>
+<ul id="u3" class="block-content">
<li><tt>addAttributesToRender()</tt> - adds attributes for the HTML element to be rendered. This method is often overridden by derived classes as they usually have different attributes to be rendered.</li>
<li><tt>renderBeginTag()</tt> - renders the opening HTML tag.</li>
<li><tt>renderContents()</tt> - renders the content enclosed within the HTML element. By default, it displays the items in the <tt>Controls</tt> collection of the control. Derived classes may override this method to render customized contents.</li>
<li><tt>renderEndTag()</tt> - renders the closing HTML tag.</li>
</ul>
-<p>
+<p id="660446" class="block-content">
When rendering the openning HTML tag, <tt>TWebControl</tt> calls <tt>getTagName()</tt> to obtain the tag name. Derived classes may override this method to render different tag names.
</p>
<h3 id="5409">Creating Controls with Special Functionalities</h3>
-<p>
+<p id="660447" class="block-content">
If a control wants to respond to client-side events and translate them into server side events (called postback events), such as <tt>TButton</tt>, it has to implement the <tt>IPostBackEventHandler</tt> interface.
</p>
-<p>
+<p id="660448" class="block-content">
If a control wants to be able to load post data, such as <tt>TTextBox</tt>, it has to implement the <tt>IPostBackDataHandler</tt> interface.
</p>
-<p>
+<p id="660449" class="block-content">
If a control wants to get data from some external data source, it can extend <tt>TDataBoundControl</tt>. <tt>TDataBoundControl</tt> implements the basic properties and methods that are needed for populating data via databinding. In fact, controls like <tt>TListControl</tt>, <tt>TRepeater</tt> are <tt>TDataGrid</tt> are all derived from it.
</p>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Controls/OutputCache.page b/demos/quickstart/protected/pages/Controls/OutputCache.page index 6c1e5554..65823a7f 100644 --- a/demos/quickstart/protected/pages/Controls/OutputCache.page +++ b/demos/quickstart/protected/pages/Controls/OutputCache.page @@ -1,21 +1,21 @@ <com:TContent ID="body" >
-<h1>TOutputCache</h1>
+<h1 id="88025">TOutputCache</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TOutputCache" />
-<p>
+<p id="440292" class="block-content">
<tt>TOutputCache</tt> 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.
</p>
-<p>
+<p id="440293" class="block-content">
To use <tt>TOutputCache</tt>, simply enclose the content to be cached within the <tt>TOutputCache</tt> component tag on a template (either page or non-page control template), e.g.,
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_440110">
<com:TOutputCache>
content to be cached
</com:TOutputCache>
</com:TTextHighlighter>
-<p>
+<p id="440294" class="block-content">
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 <tt>TOutputCache</tt> on a single template and they can be nested.
</p>
@@ -23,23 +23,23 @@ where content to be cached can be static text and/or template tags. If the latte <tt>TOutputCache</tt> stores cached content via PRADO cache modules (e.g. <tt>TSqliteCache</tt>) and thus requires at least one cache module loaded when the application runs.
</div>
-<p>
+<p id="440295" class="block-content">
The validity of the cached content is determined based on two factors: the <tt>Duration</tt> 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.
</p>
-<p>
+<p id="440296" class="block-content">
There are two ways to specify cache dependency. One may write event handlers to respond to the <tt>OnCheckDependency</tt> event and set the event parameter's <tt>IsValid</tt> property to indicate whether the cached data remains valid or not. One can also extend <tt>TOutputCache</tt> and override its <tt>getCacheDependency()</tt> method.
</p>
-<p>
+<p id="440297" class="block-content">
The content fetched from cache may be variated with respect to some parameters. <tt>TOutputCache</tt> supports variation with respect to request parameters, which is specified by <tt>VaryByParam</tt> 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 <tt>VaryBySession</tt> is set true. To variate the cached content by other factors, override <tt>calculateCacheKey()</tt> method.
</p>
-<p>
+<p id="440298" class="block-content">
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.
</p>
-<p>
+<p id="440299" class="block-content">
By default, <tt>TOutputCache</tt> is effective only for non-postback page requests and when a cache module is enabled. Do not attempt to address child controls of <tt>TOutputCache</tt> when the cached content is currently being used. Use <tt>ContentCached</tt> property to determine whether the content is cached or not.
</p>
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 @@ <h1 id="3901">TPager</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TPager" />
-<p>
+<p id="450300" class="block-content">
<tt>TPager</tt> creates a pager that provides UI for end-users to interactively specify which page of data to be rendered in a <tt>TDataBoundControl</tt>-derived control, such as <tt>TDataList</tt>, <tt>TRepeater</tt>, <tt>TCheckBoxList</tt>, etc. The target data-bound control is specified by the <tt>ControlToPaginate</tt> property, which must be the ID path of the target control reaching from the pager's naming container.
</p>
-<p>
+<p id="450301" class="block-content">
Note, the target data-bound control must have its <tt>AllowPaging</tt> 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.
</p>
-<p>
+<p id="450302" class="block-content">
<tt>TPager</tt> can display one of the following three types of user interface, specified via its <tt>Mode</tt> property:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>NextPrev</tt> - a next page and a previous page button are rendered on each page.</li>
<li><tt>Numeric</tt> - a list of page index buttons are rendered.</li>
<li><tt>DropDownList</tt> - a dropdown list of page indices is rendered.</li>
</ul>
-<p>
+<p id="450303" class="block-content">
These user interfaces may be further customized by configuring the following properties
</p>
-<ul>
+<ul id="u2" class="block-content">
<li><tt>NextPageText</tt> and <tt>PrevPageText</tt> - the label of the next/previous page button. These properties are used when the pager <tt>Mode</tt> is <tt>NextPrev</tt> or <tt>Numeric</tt>.</li>
<li><tt>FirstPageText</tt> and <tt>LastPageText</tt> - the label of the first/last page button. If empty, the corresponding button will not be displayed. These properties are used when the pager <tt>Mode</tt> is <tt>NextPrev</tt> or <tt>Numeric</tt>.</li>
<li><tt>PageButtonCount</tt> - the maximum number of page index buttons on a page. This property is used when the pager <tt>Mode</tt> is <tt>Numeric</tt>.</li>
<li><tt>ButtonType</tt> - type of page buttons, either <tt>PushButton</tt> meaning normal form submission buttons, or <tt>LinkButton</tt> meaning hyperlink buttons.</li>
</ul>
-<p>
+<p id="450304" class="block-content">
<tt>TPager</tt> raises an <tt>OnPageIndexChanged</tt> 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 <tt>NewPageIndex</tt>. Using this new page index, one can feed a new page of data to the associated data-bound control.
</p>
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 @@ <h1 id="3901">TPanel</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TPanel" />
-<p>
+<p id="460305" class="block-content">
<tt>TPanel</tt> acts as a presentational container for other control. It displays a <div> element on a page. The property <tt>Wrap</tt> specifies whether the panel's body content should wrap or not, while <tt>HorizontalAlign</tt> governs how the content is aligned horizontally and <tt>Direction</tt> indicates the content direction (left to right or right to left). You can set <tt>BackImageUrl</tt> to give a background image to the panel, and you can set <tt>GroupingText</tt> 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 <tt>DefaultButton</tt> property.
</p>
<com:RunBar PagePath="Controls.Samples.TPanel.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/PlaceHolder.page b/demos/quickstart/protected/pages/Controls/PlaceHolder.page index b55d1616..482b3b85 100644 --- a/demos/quickstart/protected/pages/Controls/PlaceHolder.page +++ b/demos/quickstart/protected/pages/Controls/PlaceHolder.page @@ -3,7 +3,7 @@ <h1 id="4001">TPlaceHolder</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TPlaceHolder" />
-<p>
+<p id="470306" class="block-content">
<tt>TPlaceHolder</tt> reserves a place on a template, where static texts or controls may be dynamically inserted.
</p>
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 @@ <h1 id="4101">TRadioButton</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TRadioButton" />
-<p>
+<p id="480307" class="block-content">
<tt>TRadioButton</tt> is similar to <tt>TCheckBox</tt> in every aspect, except that <tt>TRadioButton</tt> displays a radio button on a Web page. The radio button can belong to a specific group specified by <tt>GroupName</tt> such that only one radio button within that group can be selected at most.
</p>
<com:RunBar PagePath="Controls.Samples.TRadioButton.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/Repeater.page b/demos/quickstart/protected/pages/Controls/Repeater.page index 3534c603..76a22e11 100644 --- a/demos/quickstart/protected/pages/Controls/Repeater.page +++ b/demos/quickstart/protected/pages/Controls/Repeater.page @@ -1,23 +1,23 @@ <com:TContent ID="body" >
<h1 id="5301">TRepeater</h1>
-<p>
+<p id="600400" class="block-content">
TRepeater displays its content defined in templates repeatedly based on the given data specified by the <tt>DataSource</tt> or <tt>DataSourceID</tt> property. The repeated contents can be retrieved from the <tt>Items</tt> property. Each item is created by instantiating a template and each is a child control of the repeater.
</p>
-<p>
+<p id="600401" class="block-content">
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,
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>HeaderTemplate</tt> - the template used for displaying content at the beginning of a repeater;</li>
<li><tt>FooterTemplate</tt> - the template used for displaying content at the end of a repeater;</li>
<li><tt>ItemTemplate</tt> - the template used for displaying every repeater item. If <tt>AlternatingItemTemplate</tt> is also defined, <tt>ItemTemplate</tt> will be used for displaying item 1, 3, 5, etc.</li>
<li><tt>AlternatingItemTemplate</tt> - the template used for displaying every alternating repeater item (i.e., item 2, 4, 6, etc.)</li>
<li><tt>SeparatorTemplate</tt> - the template used for displaying content between items.</li>
</ul>
-<p>
+<p id="600402" class="block-content">
To populate data into the repeater items, set <tt>DataSource</tt> to a valid data object, such as array, <tt>TList</tt>, <tt>TMap</tt>, or a database table, and then call <tt>dataBind()</tt> for the repeater. That is,
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_600125">
class MyPage extends TPage {
public function onLoad($param) {
parent::onLoad($param);
@@ -28,32 +28,32 @@ class MyPage extends TPage { }
}
</com:TTextHighlighter>
-<p>
+<p id="600403" class="block-content">
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.
</p>
-<p>
+<p id="600404" class="block-content">
TRepeater provides several events to facilitate manipulation of its items,
</p>
-<ul>
+<ul id="u2" class="block-content">
<li><tt>OnItemCreated</tt> - raised each time an item is newly created. When the event is raised, data and child controls are both available for the new item.</li>
<li><tt>OnItemDataBound</tt> - raised each time an item just completes databinding. When the event is raised, data and child controls are both available for the item, and the item has finished databindings of itself and all its child controls.</li>
<li><tt>OnItemCommand</tt> - raised when a child control of some item (such as a <tt>TButton</tt>) raises an <tt>OnCommand</tt> event.</li>
</ul>
-<p>
+<p id="600405" class="block-content">
The following example shows how to use TRepeater to display tabular data.
</p>
<com:RunBar PagePath="Controls.Samples.TRepeater.Sample1" />
-<p>
+<p id="600406" class="block-content">
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 <tt>OnItemDataBound</tt> event of the outer repeater. An <tt>OnItemDataBound</tt> event is raised each time an outer repeater item completes databinding. In the following example, we exploit another event of repeater called <tt>OnItemCreated</tt>, 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 <tt>AlternatingItemTemplate</tt> for the repeaters.
</p>
<com:RunBar PagePath="Controls.Samples.TRepeater.Sample2" />
-<p>
+<p id="600407" class="block-content">
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.
</p>
-<p>
+<p id="600408" class="block-content">
The <a href="../composer/index.php">PRADO component composer</a> 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 <tt>OnItemCommand</tt> event of repeater.
</p>
-<p>
+<p id="600409" class="block-content">
See in the following yet another example showing how to use repeater to collect user inputs.
</p>
<com:RunBar PagePath="Controls.Samples.TRepeater.Sample3" />
diff --git a/demos/quickstart/protected/pages/Controls/SafeHtml.page b/demos/quickstart/protected/pages/Controls/SafeHtml.page index 995ceb50..1e02bb9e 100644 --- a/demos/quickstart/protected/pages/Controls/SafeHtml.page +++ b/demos/quickstart/protected/pages/Controls/SafeHtml.page @@ -3,10 +3,10 @@ <h1 id="4201">TSafeHtml</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TSafeHtml" />
-<p>
+<p id="490308" class="block-content">
<tt>TSafeHtml</tt> is a control that strips down all potentially dangerous HTML content. It is mainly a wrapper of the <a href="http://pixel-apes.com/safehtml/">SafeHTML</a> project. According to the SafeHTML project, it tries to safeguard the following situations when the string is to be displayed to end-users:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li>Opening tag without its closing tag</li>
<li>closing tag without its opening tag
<li>any of these tags: base, basefont, head, html, body, applet, object, iframe, frame, frameset, script, layer, ilayer, embed, bgsound, link, meta, style, title, blink, xml, etc.</li>
@@ -16,7 +16,7 @@ <li>any other active content.</li>
</ul>
-<p>
+<p id="490309" class="block-content">
To use <tt>TSafeHtml</tt>, simply enclose the content to be secured within the <tt>TSafeHtml</tt> 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.
</p>
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 @@ <h1>Standard Controls</h1>
<p>* the tutorial for this control is not completed yet.</p>
-<ul>
+<ul id="u1" class="block-content">
<li>
<a href="?page=Controls.Button">TButton</a> represents a click button on a Web page. It is mainly used to trigger page postback.
</li>
diff --git a/demos/quickstart/protected/pages/Controls/Statements.page b/demos/quickstart/protected/pages/Controls/Statements.page index 3f3bd1fc..f8bb4928 100644 --- a/demos/quickstart/protected/pages/Controls/Statements.page +++ b/demos/quickstart/protected/pages/Controls/Statements.page @@ -3,10 +3,10 @@ <h1 id="4301">TStatements</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TStatements" />
-<p>
+<p id="500310" class="block-content">
<tt>TStatements</tt> evaluates a sequence of PHP statements and displays the content rendered by the statements. To specify the PHP statements to be evaluated, set the <tt>Statements</tt> property. For example, the following component tag displays the current time on the Web page,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_500111">
<com:TStatements>
<prop:Statements>
setlocale(LC_ALL, 'nl_NL');
@@ -15,14 +15,14 @@ </com:TStatements>
</com:TTextHighlighter>
-<p>
+<p id="500311" class="block-content">
Note, <tt>TStatements</tt> evaluates the PHP statements during the rendering control lifecycle. Unlike <tt>TExpression</tt>, <tt>TStatements</tt> only displays the content 'echoed' within the statements.
</p>
-<p>
+<p id="500312" class="block-content">
The context of the statements in a <tt>TStatements</tt> control is the control itself. That is, <tt>$this</tt> 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 <tt>TStatements</tt> control.
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_500112">
<com:TStatements>
<prop:Statements>
$page=$this->Page;
@@ -31,7 +31,7 @@ The context of the statements in a <tt>TStatements</tt> control is the control i </com:TStatements>
</com:TTextHighlighter>
-<p>
+<p id="500313" class="block-content">
Be aware, since <tt>TStatements</tt> allows execution of arbitrary PHP code, in general you should not use it to evaluate PHP code submitted by your application users.
</p>
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 @@ <h1 id="4401">TTable</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TTable" />
-<p>
+<p id="510314" class="block-content">
<tt>TTable</tt> displays an HTML table on a page. It is used together with <tt>TTableRow</tt> and <tt>TTableCell</tt> to allow programmatically manipulating HTML tables. The rows of the table is stored in <tt>Rows</tt> property. You may set the table cellspacing and cellpadding via the <tt>CellSpacing</tt> and <tt>CellPadding</tt> properties, respectively. The table caption can be specified via <tt>Caption</tt> whose alignment is specified by <tt>CaptionAlign</tt>. The <tt>GridLines</tt> property indicates how the table should display its borders, and the <tt>BackImageUrl</tt> allows the table to have a background image.
</p>
<com:RunBar PagePath="Controls.Samples.TTable.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/TextBox.page b/demos/quickstart/protected/pages/Controls/TextBox.page index b4d1576f..c5fee17e 100644 --- a/demos/quickstart/protected/pages/Controls/TextBox.page +++ b/demos/quickstart/protected/pages/Controls/TextBox.page @@ -3,7 +3,7 @@ <h1 id="4501">TTextBox</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TTextBox" />
-<p>
+<p id="520315" class="block-content">
<tt>TTextBox</tt> displays a text box on a Web page. The content in the text box is determined by the <tt>Text</tt> property. You can create a <tt>SingleLine</tt>, a <tt>MultiLine</tt>, or a <tt>Password</tt> text box by setting the <tt>TextMode</tt> property. The <tt>Rows</tt> and <tt>Columns</tt> properties specify their dimensions. If <tt>AutoPostBack</tt> is true, changing the content in the text box and then moving the focus out of it will cause postback action.
</p>
<com:RunBar PagePath="Controls.Samples.TTextBox.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/TextHighlighter.page b/demos/quickstart/protected/pages/Controls/TextHighlighter.page index 285a6f3e..b9ac1834 100644 --- a/demos/quickstart/protected/pages/Controls/TextHighlighter.page +++ b/demos/quickstart/protected/pages/Controls/TextHighlighter.page @@ -3,16 +3,16 @@ <h1 id="4601">TTextHighlighter</h1>
<com:DocLink ClassPath="System.Web.UI.WebControls.TTextHighlighter" />
-<p>
+<p id="530316" class="block-content">
<tt>TTextHighlighter</tt> 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 <tt>Language</tt>, which can be 'php' (default), 'prado', 'css', 'html', etc. Here, 'prado' stands for the syntax of PRADO control templates.
</p>
-<p>
+<p id="530317" class="block-content">
If line numbers are desired in front of each line, set <tt>ShowLineNumbers</tt> to true.
</p>
-<p>
+<p id="530318" class="block-content">
To use <tt>TTextHighlighter</tt>, simply enclose the contents to be syntax highlighted within the body of a <tt>TTextHighlighter</tt> control. The following example highlights a piece of PHP code,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_530113">
<com:TTextHighlighter ShowLineNumbers="true">
<?php
$str = 'one|two|three|four';
diff --git a/demos/quickstart/protected/pages/Controls/Validation.page b/demos/quickstart/protected/pages/Controls/Validation.page index 0e4006bb..7770c130 100644 --- a/demos/quickstart/protected/pages/Controls/Validation.page +++ b/demos/quickstart/protected/pages/Controls/Validation.page @@ -2,18 +2,18 @@ <h1 id="4901">Validation Controls</h1>
-<p>
+<p id="560337" class="block-content">
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 <tt>TButton</tt>, a <tt>TLinkButton</tt> or a <tt>TTextBox</tt> (under <tt>AutoPostBack</tt> mode) whose <tt>CausesValidation</tt> property is true.
</p>
-<p>
+<p id="560338" class="block-content">
Validation is always performed on server side. If <tt>EnableClientScript</tt> 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.
</p>
-<p>
+<p id="560339" class="block-content">
Validators share a common set of properties, which are defined in the base class <tt>TBaseValidator</tt> class and listed as follows,
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>ControlToValidate</tt> specifies the input control to be validated. This property must be set to the ID path of an input control. An ID path is the dot-connected IDs of the controls reaching from the validator's naming container to the target control.</li>
<li><tt>ErrorMessage</tt> specifies the error message to be displayed in case the corresponding validator fails.</li>
<li><tt>Text</tt> is similar to <tt>ErrorMessage</tt>. If they are both present, <tt>Text</tt> takes precedence. This property is useful when used together with <tt>TValidationSummary</tt>.</li>
@@ -33,17 +33,17 @@ Validators share a common set of properties, which are defined in the base class <a name="TRequiredFieldValidator"></a>
<h2 id="4902">TRequiredFieldValidator</h2>
-<p>
+<p id="560340" class="block-content">
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 <tt>InitialValue</tt>, the validator can check if the user input is different from <tt>InitialValue</tt>. If not, the validation fails.
</p>
<com:RunBar PagePath="Controls.Samples.TRequiredFieldValidator.Home" />
<a name="TRegularExpressionValidator"></a>
<h2 id="4903">TRegularExpressionValidator</h2>
-<p>
+<p id="560341" class="block-content">
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 <tt>RegularExpression</tt> property. Some commonly used regular expressions include:
</p>
-<ul>
+<ul id="u2" class="block-content">
<li>At least 6 characters: <code>[\w]{6,}</code></li>
<li>Japanese Phone Number: <code>(0\d{1,4}-|\(0\d{1,4}\) ?)?\d{1,4}-\d{4}</code></li>
<li>Japanese Postal Code: <code>\d{3}(-(\d{4}|\d{2}))?</code></li>
@@ -54,49 +54,49 @@ TRegularExpressionValidator verifies the user input against a regular pattern. T <li>U.S. ZIP Code: <code>\d{5}(-\d{4})?</code></li>
<li>U.S. Social Security Number: <code>\d{3}-\d{2}-\d{4}</code></li>
</ul>
-<p>
+<p id="560342" class="block-content">
More regular expression patterns can be found on the Internet, e.g.
<a href="http://regexlib.com/">http://regexlib.com/</a>.
</p>
-<p>
+<p id="560343" class="block-content">
Note, TRegularExpressionValidator only checks for nonempty user input. Use a TRequiredFieldValidator to ensure the user input is not empty.
</p>
<com:RunBar PagePath="Controls.Samples.TRegularExpressionValidator.Home" />
<h2 id="TEmailAddressValidator">TEmailAddressValidator</h2>
-<p>
+<p id="560344" class="block-content">
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 <tt>CheckMXRecord</tt> is true, the validator will also check whether the MX record indicated by the email address is valid, provided <tt>checkdnsrr()</tt> is available in the installed PHP.
</p>
-<p>
+<p id="560345" class="block-content">
Note, if the input being validated is empty, TEmailAddressValidator will not do validation. Use a TRequiredFieldValidator to ensure the value is not empty.
</p>
<com:RunBar PagePath="Controls.Samples.TEmailAddressValidator.Home" />
<a name="TCompareValidator"></a>
<h2 id="4904">TCompareValidator</h2>
-<p>
+<p id="560346" class="block-content">
TCompareValidator compares the user input with a constant value specified by <tt>ValueToCompare</tt>, or another user input specified by <tt>ControlToCompare</tt>. The <tt>Operator</tt> property specifies how to compare the values, which includes <tt>Equal</tt>, <tt>NotEqual</tt>, <tt>GreaterThan</tt>, <tt>GreaterThanEqual</tt>, <tt>LessThan</tt> and <tt>LessThanEqual</tt>. Before comparison, the values being compared will be converted to the type specified by <tt>DataType</tt> listed as follows,
</p>
-<ul>
+<ul id="u3" class="block-content">
<li><tt>String</tt> - A string data type.</li>
<li><tt>Integer</tt> - A 32-bit signed integer data type.</li>
<li><tt>Float</tt> - A double-precision floating point number data type.</li>
<li><tt>Date</tt> - A date data type. The date format can be specified by setting <tt>DateFormat</tt> property, which must be recognizable by <tt>TSimpleDateFormatter</tt>. If the property is not set, the GNU date syntax is assumed.</li>
</ul>
-<p>
+<p id="560347" class="block-content">
Note, if the input being validated is empty, TEmailAddressValidator will not do validation. Use a TRequiredFieldValidator to ensure the value is not empty.
</p>
-<p>
+<p id="560348" class="block-content">
<b>N.B.</b> If validating against a <a href="?page=Controls.DatePicker">TDatePicker</a> the <tt>DataType</tt> must be equal to "Date" and the <tt>DateFormat</tt> property of the validator must be equal to the <tt>DateFormat</tt> of the <a href="?page=Controls.DatePicker">TDatePicker</a>.
</p>
<com:RunBar PagePath="Controls.Samples.TCompareValidator.Home" />
<a name="TDataTypeValidator"></a>
<h2 id="4905">TDataTypeValidator</h2>
-<p>
+<p id="560349" class="block-content">
TDataTypeValidator verifies if the input data is of specific type indicated by <tt>DataType</tt>. The data types that can be checked against are the same as those in TCompareValidator.
</p>
-<p>
+<p id="560350" class="block-content">
<b>N.B.</b> If validating against a <a href="?page=Controls.DatePicker">TDatePicker</a> the <tt>DataType</tt> must be equal to "Date" and the <tt>DateFormat</tt> property of the validator must be equal to the <tt>DateFormat</tt> of the <a href="?page=Controls.DatePicker">TDatePicker</a>.
</p>
@@ -105,10 +105,10 @@ TDataTypeValidator verifies if the input data is of specific type indicated by < <a name="TRangeValidator"></a>
<h2 id="4906">TRangeValidator</h2>
-<p>
+<p id="560351" class="block-content">
TRangeValidator verifies whether an input value is within a specified range. TRangeValidator uses three key properties to perform its validation. The <tt>MinValue</tt> and <tt>MaxValue</tt> properties specify the minimum and maximum values of the valid range. The <tt>DataType</tt> 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.
</p>
-<p>
+<p id="560352" class="block-content">
<b>N.B.</b> If validating against a <a href="?page=Controls.DatePicker">TDatePicker</a> the <tt>DataType</tt> must be equal to "Date" and the <tt>DateFormat</tt> property of the validator must be equal to the <tt>DateFormat</tt> of the <a href="?page=Controls.DatePicker">TDatePicker</a>.
</p>
@@ -116,16 +116,16 @@ TRangeValidator verifies whether an input value is within a specified range. TRa <a name="TCustomValidator"></a>
<h2 id="4907">TCustomValidator</h2>
-<p>
+<p id="560353" class="block-content">
TCustomValidator performs user-defined validation (either server-side or client-side or both) on an input control.
</p>
-<p>
+<p id="560354" class="block-content">
To create a server-side validation function, provide a handler for the <tt>OnServerValidate</tt> event that performs the validation. The data string of the input control to validate can be accessed by the event parameter's <tt>Value</tt> property. The result of the validation should be stored in the <tt>IsValid</tt> property of the parameter.
</p>
-<p>
+<p id="560355" class="block-content">
To create a client-side validation function, add the client-side validation javascript function to the page template and assign its name to the <tt>ClientValidationFunction</tt> property. The function should have the following signature:
</p>
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_560118">
<script type="text/javascript">
function ValidationFunctionName(sender, parameter)
{
@@ -140,30 +140,30 @@ function ValidationFunctionName(sender, parameter) <a name="TValidationSummary"></a>
<h2 id="4908">TValidationSummary</h2>
-<p>
+<p id="560356" class="block-content">
TValidationSummary displays a summary of validation errors inline on a Web page, in a message box, or both.
</p>
-<p>
+<p id="560357" class="block-content">
By default, a validation summary will collect <tt>ErrorMessage</tt> of all failed validators on the page. If <tt>ValidationGroup</tt> is not empty, only those validators who belong to the group will show their error messages in the summary.
</p>
-<p>
+<p id="560358" class="block-content">
The summary can be displayed as a list, a bulleted list, or a single paragraph based on the <tt>DisplayMode</tt> property. The messages shown can be prefixed with <tt>HeaderText</tt>. The summary can be displayed on the Web page or in a JavaScript message box, by setting the <tt>ShowSummary</tt> and <tt>ShowMessageBox</tt> properties, respectively. Note, the latter is only effective when <tt>EnableClientScript</tt> is true.
</p>
<com:RunBar PagePath="Controls.Samples.TValidationSummary.Home" />
<h2 id="5301">Client and Server Side Conditional Validation</h2>
-<p>
- All validators contains the following events.
- <ul>
+<p id="560359" class="block-content">
+ All validators contains the following events.
+ The corresponding events for the client side is available as sub-properties
+ of the <tt>ClientSide</tt> property of the validator.
+</p>
+ <ul id="u4" class="block-content">
<li>The <tt>OnValidate</tt> event is raise before the validator validation functions are called.</li>
<li>The <tt>OnValidationSuccess</tt> event is raised after the validator has successfully validate the control.</li>
<li>The <tt>OnValidationError</tt> event is raised after the validator fails validation.</li>
</ul>
- The corresponding events for the client side is available as sub-properties
- of the <tt>ClientSide</tt> property of the validator.
-</p>
-<p>The following example pop-up a message saying "hello" when the validator fails on the client-side.
-<com:TTextHighlighter Language="prado" CssClass="source">
+<p id="560360" class="block-content">The following example pop-up a message saying "hello" when the validator fails on the client-side.
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_560119">
<com:TRequiredFieldValidator ... >
<prop:ClientSide.OnValidationError>
alert("hello");
@@ -171,7 +171,7 @@ The summary can be displayed as a list, a bulleted list, or a single paragraph b </com:TRequiredFieldValidator>
</com:TTextHighlighter>
The resulting client-side event callback function is of the following form.
-<com:TTextHighlighter Language="javascript" CssClass="source">
+<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_560120">
function onErrorHandler(sender, parameter)
{
alert("hello");
@@ -181,7 +181,7 @@ Where <tt>sender</tt> is the current client-side validator and <tt>parameter</tt is the control that invoked the validator.
</p>
<h3 id="5302">Conditional Validation Example</h3>
-<p>
+<p id="560361" class="block-content">
The following example show the use of client-side and server side validator events. The example
demonstrates conditional validation.
<com:RunBar PagePath="Controls.Samples.TClientSideValidator.Home" />
diff --git a/demos/quickstart/protected/pages/Controls/Wizard.page b/demos/quickstart/protected/pages/Controls/Wizard.page index fe910aa7..8705eeb2 100644 --- a/demos/quickstart/protected/pages/Controls/Wizard.page +++ b/demos/quickstart/protected/pages/Controls/Wizard.page @@ -4,24 +4,24 @@ <com:DocLink ClassPath="System.Web.UI.WebControls.TWizard" />
<h2 id="4702">Overview</h2>
-<p>
+<p id="540319" class="block-content">
<tt>TWizard</tt> is analogous to the installation wizard commonly used to install software on Windows. It splits a large form and presents the user with a series of smaller forms, called wizard steps, to complete. The following figure shows how a wizard is composed of when presented to users, where <tt>step content</tt> is the main content of a wizard step for users to complete, <tt>header</tt> refers to header content common to all steps, <tt>navigation</tt> contains buttons that allow users to navigate step by step, and <tt>side bar</tt> contains a list of hyperlinks by which users can reach to any step with one click. The visibility of the side bar can be toggled by setting <tt>ShowSideBar</tt>.
</p>
<img src="<%~wizard.gif%>" alt="components of wizard" />
-<p>
+<p id="540320" class="block-content">
By default, <tt>TWizard</tt> embeds the above components in an HTML table so that the side bar is displayed on the left while the rest on the right. If <tt>UseDefaultLayout</tt> is set to false, no HTML table will be used, and developers should use pure CSS techniques to position the wizard components. Note, each component is displayed as a <div> and the wizard itself is also a <div> that encloses its components' <div>.
</p>
-<p>
+<p id="540321" class="block-content">
Wizard steps are represented by <tt>TWizardStep</tt> and are maintained in <tt>TWizard</tt> through its <tt>WizardSteps</tt> property. At any time, only one step is visible, which is determined by the <tt>ActiveStep</tt> property. The <tt>ActiveStepIndex</tt> property gives the index of the active step in the step collection. Clicking on navigation buttons can activate different wizard steps.
</p>
-<p>
+<p id="540322" class="block-content">
Wizard steps are typically added to a wizard through template as follows,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_540114">
<com:TWizard>
<com:TWizardStep Title="step 1" StepType="Start">
content in step 1, may contain other controls
@@ -37,10 +37,10 @@ Wizard steps are typically added to a wizard through template as follows, </com:TWizard>
</com:TTextHighlighter>
-<p>
+<p id="540323" class="block-content">
In the above, <tt>StepType</tt> refers to the type of a wizard step, which can affect how the navigation appearance and behavior of the step. A wizard step can be of one of the following types:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>Start</tt> - the first step in the wizard.</li>
<li><tt>Step</tt> - the internal steps in the wizard.</li>
<li><tt>Finish</tt> - the last step that allows user interaction.</li>
@@ -52,16 +52,16 @@ In the above, <tt>StepType</tt> refers to the type of a wizard step, which can a <h2 id="4703">Using TWizard</h2>
<h3 id="4704">A Single-Step Wizard Sample</h3>
-<p>
+<p id="540324" class="block-content">
In this sample, we use wizard to collect user's preference of color. In the first step, the user is presented with a dropdown list from which he can choose hist favorite color. In the second step, the complete step, his choice in the previous step is displayed. In real application, at this step the choice may be stored in database in the backend.
</p>
<com:RunBar PagePath="Controls.Samples.TWizard.Sample1" />
<h3 id="4705">Customizing Wizard Styles</h3>
-<p>
+<p id="540325" class="block-content">
<tt>TWizard</tt> defines a whole set of properties for customization of appearance of its various components as shown in the above figure. In particular, the following properties are provided for style customization:
</p>
-<ul>
+<ul id="u2" class="block-content">
<li>Header - <tt>HeaderStyle</tt>.</li>
<li>Step - <tt>StepStyle</tt>.</li>
<li>Navigation - <tt>NavigationStyle</tt>, <tt>StartNextButtonStyle</tt>, <tt>StepNextButtonStyle</tt>, <tt>StepPreviousButtonStyle</tt>, <tt>FinishPreviousButtonStyle</tt>, <tt>FinishCompleteButtonStyle</tt>, <tt>CancelButtonStyle</tt>.</li>
@@ -70,10 +70,10 @@ In this sample, we use wizard to collect user's preference of color. In the firs <com:RunBar PagePath="Controls.Samples.TWizard.Sample2" />
<h3 id="4706">Customizing Wizard Navigation</h3>
-<p>
+<p id="540326" class="block-content">
Given a set of wizard steps, <tt>TWizard</tt> supports three different ways of navigation among them:
</p>
-<ul>
+<ul id="u3" class="block-content">
<li>Bidirectional - Users can navigate forward and backward along a sequence of wizard steps. User input data is usually collected at the last step. This is also known as commit-at-the-end model. It is the default navigation way that <tt>TWizard</tt> supports.</li>
<li>Unidirectional - Users can navigate forward along a sequence of wizard steps. Backward move is not allowed. User input data is usually collected step by step. This is also known as command-as-you-go model. To disallow backward move to a specific step, set its <tt>AllowReturn</tt> property to false.</li>
<li>Nonlinear - User input in a step determines which step to go next. To do so, set <tt>ActiveStepIndex</tt> to the step that you want the user to go to. In this case, when a user clicks on the previous button in the navigation panel, the previous step that they visited (not the previous step in the sequential order) will become visible.</li>
@@ -81,10 +81,10 @@ Given a set of wizard steps, <tt>TWizard</tt> supports three different ways of n <com:RunBar PagePath="Controls.Samples.TWizard.Sample3" />
<h3 id="4707">Using Templates in Wizard</h3>
-<p>
+<p id="540327" class="block-content">
<tt>TWizard</tt> supports more concrete control of its outlook through templates. In particular, it provides the following template properties that allow complete customization of the wizard's header, navigation and side bar.
</p>
-<ul>
+<ul id="u4" class="block-content">
<li>Header - <tt>HeaderTemplate</tt>.</li>
<li>Navigation - <tt>StartNavigationTemplate</tt>, <tt>StepNavigationTemplate</tt>, <tt>FinishNavigationTemplate</tt>.</li>
<li>Side bar - <tt>SideBarTemplate</tt>.</li>
@@ -92,7 +92,7 @@ Given a set of wizard steps, <tt>TWizard</tt> supports three different ways of n <com:RunBar PagePath="Controls.Samples.TWizard.Sample4" />
<h3 id="4708">Using Templated Wizard Steps</h3>
-<p>
+<p id="540328" class="block-content">
Wizard steps can also be templated. By using <tt>TTemplatedWizardStep</tt>, one can customize step content and navigation through its <tt>ContentTemplate</tt> and <tt>NavigationTemplate</tt> properties, respectively. This is useful for control developers to build specialized wizards, such as user registration, shopping carts, etc.
</p>
<com:RunBar PagePath="Controls.Samples.TWizard.Sample5" />
diff --git a/demos/quickstart/protected/pages/Database/ActiveRecord.page b/demos/quickstart/protected/pages/Database/ActiveRecord.page index 4dd70608..bc1d2359 100644 --- a/demos/quickstart/protected/pages/Database/ActiveRecord.page +++ b/demos/quickstart/protected/pages/Database/ActiveRecord.page @@ -1,7 +1,7 @@ <com:TContent ID="body" > <!-- $Id $ --> -<h1>Active Record</h1> -<p>Active Records are objects that wrap a row in a database table or view, +<h1 id="138046">Active Record</h1> +<p id="690478" class="block-content">Active Records are objects that wrap a row in a database table or view, encapsulates the database access and adds domain logic on that data. The basics of an Active Record is a business object class, e.g., a <tt>Products</tt> class, that match very closely the record structure @@ -13,21 +13,21 @@ Each field in the class must correspond to one column in the table. </div> -<h2>When to Use It</h2> -<p>Active Record is a good choice for domain logic that isn't too complex, +<h2 id="138047">When to Use It</h2> +<p id="690479" class="block-content">Active Record is a good choice for domain logic that isn't too complex, such as creates, reads, updates, and deletes. Derivations and validations based on a single record work well in this structure. Active Record has the primary advantage of simplicity. It's easy to build Active Records, and they are easy to understand.</p> - <p>However, as your business logic grows in complexity, you'll soon want + <p id="690480" class="block-content">However, as your business logic grows in complexity, you'll soon want to use your object's direct relationships, collections, inheritance, and so forth. These don't map easily onto Active Record, and adding them piecemeal gets very messy. Another argument against Active Record is the fact that it couples the object design to the database design. This makes it more difficult to refactor as a project goes forward.</p> - <p>The alternative is to use a Data Mapper that separates the roles of the + <p id="690481" class="block-content">The alternative is to use a Data Mapper that separates the roles of the business object and how these objects are stored. Prado provides a complimentary choice between Active Record and <a href="?page=Database.SqlMap">SqlMap Data Mapper</a>. @@ -39,26 +39,28 @@ <img src=<%~ sqlmap_active_record.png %> alt="Active Records and SqlMap DataMapper" id="fig:diagram.png" class="figure"/> </p> - <p> + <p id="690482" class="block-content"> The Active Record class has methods that do the following: - <ul> + </p> + <ul id="u1" class="block-content"> <li>Construct an instance of the Active Record from a SQL result set row.</li> <li>Construct a new instance for later insertion into the table.</li> <li>Finder methods to wrap commonly used SQL queries and return Active Record objects.</li> <li>Update existing records and insert new records into the database.</li> </ul> - </p> +<p id="p1" class="block-content"> The Active Record implementation utilizes the <a href="?page=Database.DAO">Prado DAO</a> classes for data access. The current Active Record implementation supports <a href="http://www.mysql.com">MySQL</a>, <a href="http://www.postgres.com">Postgres SQL</a> and <a href="http://www.sqlite.org">SQLite</a> databases. Support for other databases can be provided when there are sufficient demand. -<h2>Defining an Active Record</h2> -<p>Let us +</p> +<h2 id="138048">Defining an Active Record</h2> +<p id="690483" class="block-content">Let us consider the following "users" table that contains two columns named "username" and "email", where "username" is also the primary key. -<com:TTextHighlighter Language="sql" CssClass="source"> +<com:TTextHighlighter Language="sql" CssClass="source block-content" id="code_690147"> CREATE TABLE users ( username VARCHAR( 20 ) NOT NULL , @@ -67,8 +69,8 @@ CREATE TABLE users ); </com:TTextHighlighter> </p> -<p>Next we define our Active Record class that corresponds to the "users" table. -<com:TTextHighlighter Language="php" CssClass="source"> +<p id="690484" class="block-content">Next we define our Active Record class that corresponds to the "users" table. +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690148"> class UserRecord extends TActiveRecord { public $username; //the column named "username" in the "users" table @@ -86,7 +88,7 @@ class UserRecord extends TActiveRecord } </com:TTextHighlighter> </p> -<p>Each property of the <tt>UserRecord</tt> class must correspond to a +<p id="690485" class="block-content">Each property of the <tt>UserRecord</tt> class must correspond to a column with the same name in the "users" table. The static class variable <tt>$_tablename</tt> (must be public) is optional when the class name is the same as the table name in the database, otherwise <tt>$_tablename</tt> must @@ -102,7 +104,7 @@ E.g. MySQL uses back-ticks, <tt>$_tablename = "`database1`.`table1`"</tt> Since <tt>TActiveRecord</tt> extends <tt>TComponent</tt>, setter and getter methods can be defined to allow control over how variables are set and returned. For example, adding a <tt>$level</tt> property to the UserRecord class: -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690149"> class UserRecord extends TActiveRecord { ... //existing definitions as above @@ -124,19 +126,19 @@ from views are read-only, calling the <tt>save()</tt> or <tt>delete()</tt> metho will raise an exception. </div> -<p> +<p id="690486" class="block-content"> The static method <tt>finder()</tt> returns an <tt>UserRecord</tt> instance that can be used to load records from the database. The loading of records using the finer methods is discuss a little later. The <tt>TActiveRecord::getRecordFinder()</tt> static method takes the name of the current Active Record class as parameter. </p> -<h2>Setting up a database connection</h2> -<p> +<h2 id="138049">Setting up a database connection</h2> +<p id="690487" class="block-content"> A default database connection for Active Record can be set as follows. See <a href="?page=Database.DAO">Establishing Database Connection</a> for futher details regarding creation of database connection in general. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690150"> //create a connection and give it to the ActiveRecord manager. $dsn = 'pgsql:host=localhost;dbname=test'; //Postgres SQL $conn = new TDbConnection($dsn, 'dbuser','dbpass'); @@ -144,11 +146,11 @@ TActiveRecordManager::getInstance()->setDbConnection($conn); </com:TTextHighlighter> </p> -<p> +<p id="690488" class="block-content"> The default database connection can also be configured using a <tt><module></tt> tag in the <a href="?page=Configurations.AppConfig">application.xml</a> or <a href="?page=Configurations.PageConfig">config.xml</a> as follows. -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_690151"> <modules> <module class="System.Data.ActiveRecord.TActiveRecordConfig" EnableCache="true"> <database ConnectionString="pgsql:host=localhost;dbname=test" @@ -165,10 +167,10 @@ TActiveRecordManager::getInstance()->setDbConnection($conn); </div> </p> -<p>A <tt>ConnectionID</tt> property can be specified with value corresponding +<p id="690489" class="block-content">A <tt>ConnectionID</tt> property can be specified with value corresponding to another <tt>TDataSourceConfig</tt> module configuration's ID value. This allows the same database connection to be used in other modules such as <a href="?page=Database.SqlMap">SqlMap</a>. -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_690152"> <modules> <module class="System.Data.TDataSourceConfig" ID="db1"> <database ConnectionString="pgsql:host=localhost;dbname=test" @@ -184,16 +186,16 @@ TActiveRecordManager::getInstance()->setDbConnection($conn); </com:TTextHighlighter> </p> -<h2>Loading data from the database</h2> -<p> +<h2 id="138050">Loading data from the database</h2> +<p id="690490" class="block-content"> The <tt>TActiveRecord</tt> class provides many convenient methods to find records from the database. The simplest is finding records by matching primary keys. See the <com:DocLink ClassPath="System.Data.ActiveRecord.TActiveRecord" /> for more details. </p> - <h3><tt>findByPk()</tt></h3> - <p>Finds one record using only the primary key or composite primary keys. -<com:TTextHighlighter Language="php" CssClass="source"> + <h3 id="138055"><tt>findByPk()</tt></h3> + <p id="690491" class="block-content">Finds one record using only the primary key or composite primary keys. +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690153"> $finder = UserRecord::finder(); $user = $finder->findByPk($primaryKey); @@ -203,16 +205,16 @@ $record = $finder->findByPk(array($key1, $key2,...)); </com:TTextHighlighter> </p> - <h3><tt>findAllByPks()</tt></h3> - <p>Finds multiple records using a list of primary keys or composite primary keys. + <h3 id="138056"><tt>findAllByPks()</tt></h3> + <p id="690492" class="block-content">Finds multiple records using a list of primary keys or composite primary keys. The following are equivalent for scalar primary keys (primary key consisting of only one column/field). -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690154"> $finder = UserRecord::finder(); $users = $finder->findAllByPk($key1, $key2, ...); $users = $finder->findAllByPk(array($key1, $key2, ...)); </com:TTextHighlighter> The following are equivalent for composite keys. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690155"> //when the table uses composite keys $record = $finder->findAllByPks(array($key1, $key2), array($key3, $key4), ...); @@ -223,10 +225,10 @@ $record = $finder->findAllByPks($keys); </p> -<h3><tt>find()</tt></h3> -<p>Finds <b>one single record</b> that matches the criteria. The criteria - can be a partial SQL string or a <tt>TActiveRecordCriteria</tt> object. -<com:TTextHighlighter Language="php" CssClass="source"> +<h3 id="138057"><tt>find()</tt></h3> +<p id="690493" class="block-content">Finds <b>one single record</b> that matches the criteria. The criteria + can be a partial SQL string or a <tt>TActiveRecordCriteria</tt> object.</p> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690156"> $finder = UserRecord::finder(); //:name and :pass are place holders for specific values of $name and $pass @@ -241,19 +243,18 @@ $finder->find('username = ? AND password = ?', $name, $pass); //$criteria is of TActiveRecordCriteria $finder->find($criteria); //the 2nd parameter for find() is ignored. </com:TTextHighlighter> -</p> -<p>The <tt>TActiveRecordCriteria</tt> class has the following properties: - <ul> +<p id="690494" class="block-content">The <tt>TActiveRecordCriteria</tt> class has the following properties: +</p> + <ul id="u2" class="block-content"> <li><tt>Parameters</tt> -- name value parameter pairs.</li> <li><tt>OrderBy</tt> -- column name and ordering pairs.</li> <li><tt>Condition</tt> -- parts of the WHERE SQL conditions.</li> <li><tt>Limit</tt> -- maximum number of records to return.</li> <li><tt>Offset</tt> -- record offset in the table.</li> </ul> -</p> -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690157"> $criteria = new TActiveRecordCriteria; $criteria->Condition = 'username = :name AND password = :pass'; $criteria->Parameters[':name'] = 'admin'; @@ -264,45 +265,45 @@ $criteria->Limit = 10; $criteria->Offset = 20; </com:TTextHighlighter> -<h3><tt>findAll()</tt></h3> -<p>Same as <tt>find()</tt> but returns an array of objects.</p> +<h3 id="138058"><tt>findAll()</tt></h3> +<p id="690495" class="block-content">Same as <tt>find()</tt> but returns an array of objects.</p> -<h3><tt>findBy*()</tt> and <tt>findAllBy*()</tt></h3> -<p>Dynamic find method using parts of method name as search criteria. +<h3 id="138059"><tt>findBy*()</tt> and <tt>findAllBy*()</tt></h3> +<p id="690496" class="block-content">Dynamic find method using parts of method name as search criteria. Method names starting with <tt>findBy</tt> return 1 record only. Method names starting with <tt>findAllBy</tt> return an array of records. The condition is taken as part of the method name after <tt>findBy</tt> or <tt>findAllBy</tt>. The following blocks of code are equivalent: -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690158"> $finder->findByName($name) $finder->find('Name = ?', $name); </com:TTextHighlighter> -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690159"> $finder->findByUsernameAndPassword($name,$pass); $finder->findBy_Username_And_Password($name,$pass); $finder->find('Username = ? AND Password = ?', $name, $pass); </com:TTextHighlighter> -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690160"> $finder->findAllByAge($age); $finder->findAll('Age = ?', $age); </com:TTextHighlighter> </p> -<h3><tt>findBySql()</tt></h3> -<p>Finds records using full SQL, returns corresponding array of record objects.</p> +<h3 id="138060"><tt>findBySql()</tt></h3> +<p id="690497" class="block-content">Finds records using full SQL, returns corresponding array of record objects.</p> -<h3><tt>count()</tt></h3> -<p>Find the number of matchings records.</p> +<h3 id="138061"><tt>count()</tt></h3> +<p id="690498" class="block-content">Find the number of matchings records.</p> -<h2>Inserting and updating records</h2> -<p> +<h2 id="138051">Inserting and updating records</h2> +<p id="690499" class="block-content"> Add a new record using TActiveRecord is very simple, just create a new Active Record object and call the <tt>save()</tt> method. E.g. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690161"> $user1 = new UserRecord(); $user1->username = "admin" $user1->email = "admin@example.com"; @@ -320,19 +321,19 @@ defined with "autoincrement", the Active Record objects will be updated with the incremented values.</div> </p> -<p> +<p id="690500" class="block-content"> To update a record in the database, just change one or more properties of the Active Record object that has been loaded from the database and then call the <tt>save()</tt> method. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690162"> $user = UserRecord::finder()->findByName('admin'); $user->email="test@example.com"; //change property $user->save(); //update it. </com:TTextHighlighter> </p> -<p> +<p id="690501" class="block-content"> Active Record objects have a simple life-cycle illustrated in the following diagram. <img src=<%~ object_states.png %> alt="Active Records Life Cycle" id="fig:cycle.png" class="figure"/> We see that new ActiveRecord objects are created by either using one of the <tt>find*()</tt> @@ -346,22 +347,22 @@ internal states are changed. Calling the <tt>delete()</tt> method on the object ends the object life-cycle, no futher actions can be performed on the object. </p> -<h2>Deleting existing records</h2> -<p> +<h2 id="138052">Deleting existing records</h2> +<p id="690502" class="block-content"> To delete an existing record that is already loaded, just call the <tt>delete()</tt> method. You can also delete records in the database by primary keys without loading any records using the <tt>deleteByPk()</tt> method. For example, to delete one or records with tables having a scalar primary key. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690163"> $finder->deleteByPk($primaryKey); //delete 1 record $finder->deleteByPk($key1,$key2,...); //delete multiple records $finder->deleteByPk(array($key1,$key2,...)); //delete multiple records </com:TTextHighlighter> </p> -<p> +<p id="690503" class="block-content"> For composite primary keys (determined automatically from the table definitions): -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690164"> $finder->deleteByPk(array($key1,$key2)); //delete 1 record //delete multiple records @@ -372,10 +373,10 @@ $finder->deleteByPk(array( array($key1,$key2), array($key3,$key4), .. )); </com:TTextHighlighter> </p> -<h2>Transactions</h2> -<p>All Active Record objects contains the property <tt>DbConnection</tt> +<h2 id="138053">Transactions</h2> +<p id="690504" class="block-content">All Active Record objects contains the property <tt>DbConnection</tt> that can be used to obtain a transaction object. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_690165"> $finder = UserRecord::finder(); $transaction = $finder->DbConnection->beginTransaction(); @@ -392,8 +393,8 @@ catch(Exception $e) // an exception is raised if a query fails } </com:TTextHighlighter> -<h2>References</h2> -<ul> +<h2 id="138054">References</h2> +<ul id="u3" class="block-content"> <li>Fowler et. al. <i>Patterns of Enterprise Application Architecture</i>, Addison Wesley, 2002.</li> </ul> diff --git a/demos/quickstart/protected/pages/Database/DAO.page b/demos/quickstart/protected/pages/Database/DAO.page index ec16aec5..63f00706 100644 --- a/demos/quickstart/protected/pages/Database/DAO.page +++ b/demos/quickstart/protected/pages/Database/DAO.page @@ -1,33 +1,33 @@ <com:TContent ID="body" >
<!-- $Id $ -->
-<h1>Data Access Objects (DAO)</h1>
-<p>
+<h1 id="136039">Data Access Objects (DAO)</h1>
+<p id="680461" class="block-content">
Data Access Objects (DAO) separates a data resource's client interface from its data access mechanisms. It adapts a specific data resource's access API to a generic client interface. As a result, data access mechanisms can be changed independently of the code that uses the data.
</p>
-<p>
+<p id="680462" class="block-content">
Since version 3.1, PRADO starts to provide a DAO that is a thin wrap around <a href="http://www.php.net/manual/en/ref.pdo.php">PHP Data Objects (PDO)</a>. Although PDO has a nice feature set and good APIs, we choose to implement the PRADO DAO on top of PDO because the PRADO DAO classes are component classes and are thus configurable in a PRADO application. Users can use these DAO classes in a more PRADO-preferred way.
</p>
<div class="note"><b class="tip">Note:</b>
Since the PRADO DAO is based on PDO, the PDO PHP extension needs to be installed. In addition, you need to install the corresponding PDO driver for the database to be used in your application. See more details in the <a href="http://www.php.net/manual/en/ref.pdo.php">PHP Manual</a>.
</div>
-<p>
+<p id="680463" class="block-content">
The PRADO DAO mainly consists of the following four classes (in contrast to PDO which uses only two classes, <tt>PDO</tt> and <tt>PDOStatement</tt>):
</p>
-<ul>
+<ul id="u1" class="block-content">
<li><tt>TDbConnection</tt> - represents a connection to a database.</li>
<li><tt>TDbCommand</tt> - represents an SQL statement to execute against a database.</li>
<li><tt>TDbDataReader</tt> - represents a forward-only stream of rows from a query result set.</li>
<li><tt>TDbTransaction</tt> - represents a DB transaction.</li>
</ul>
-<p>
+<p id="680464" class="block-content">
In the following, we introduce the usage of PRADO DAO in different scenarios.
</p>
-<h2>Establishing Database Connection</h2>
-<p>
+<h2 id="136040">Establishing Database Connection</h2>
+<p id="680465" class="block-content">
To establish a database connection, one creates a <tt>TDbConnection</tt> instance and activate it. A data source name (DSN) is needed to specify the information required to connect to the database. The database username and password may need to be supplied to establish the connection.
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_680140">
$connection=new TDbConnection($dsn,$username,$password);
// call setAttribute() to pass in additional connection parameters
// $connection->Persistent=true; // use persistent connection
@@ -35,51 +35,51 @@ $connection->Active=true; // connection is established ....
$connection->Active=false; // connection is closed
</com:TTextHighlighter>
-<p>
+<p id="680466" class="block-content">
Complete specification of DSN may be found in the <a href="http://www.php.net/manual/en/ref.pdo.php#pdo.drivers">PDO documentation</a>. Below is a list of commonly used DSN formats:
</p>
-<ul>
+<ul id="u2" class="block-content">
<li>MySQL - <tt>mysql:host=localhost;dbname=test</tt></li>
<li>SQLite - <tt>sqlite:/path/to/dbfile</tt></li>
<li>ODBC - <tt>odbc:SAMPLE</tt>
</ul>
-<p>
+<p id="680467" class="block-content">
In case any error occurs when establishing the connection (such as bad DSN or username/password), a <tt>TDbException</tt> will be raised.
</p>
-<h2>Executing SQL Statements</h2>
-<p>
+<h2 id="136041">Executing SQL Statements</h2>
+<p id="680468" class="block-content">
Once a database connection is established, SQL statements can be executed through <tt>TDbCommand</tt>. One creates a <tt>TDbCommand</tt> by calling <tt>TDbConnection.createCommand()</tt> with the specified SQL statement:
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_680141">
$command=$connection->createCommand($sqlStatement);
// if needed, the SQL statement may be updated as follows:
$command->Text=$newSqlStatement;
</com:TTextHighlighter>
-<p>
+<p id="680469" class="block-content">
An SQL statement is executed via <tt>TDbCommand</tt> in one of the following two ways:
</p>
-<ul>
+<ul id="u4" class="block-content">
<li><tt>execute()</tt> - performs a non-query SQL statement, such as <tt>INSERT</tt>, <tt>UPDATE</tt> and <tt>DELETE</tt>. If successful, it returns the number of rows that are affected by the execution.</li>
<li><tt>query()</tt> - performs an SQL statement that returns rows of data, such as <tt>SELECT</tt>. If successful, it returns a <tt>TDbDataReader</tt> instance from which one can fetch the resulting rows of data.
</li>
</ul>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_680142">
$affectedRowCount=$command->execute(); // execute the non-query SQL
$dataReader=$command->query(); // execute a query SQL
$row=$command->queryRow(); // execute a query SQL and return the first row of result
$value=$command->queryScalar(); // execute a query SQL and return the first column value
</com:TTextHighlighter>
-<p>
+<p id="680470" class="block-content">
In case an error occurs during the execution of SQL statements, a <tt>TDbException</tt> will be raised.
</p>
-<h2>Fetching Query Results</h2>
-<p>
+<h2 id="136042">Fetching Query Results</h2>
+<p id="680471" class="block-content">
After <tt>TDbCommand.query()</tt> generates the <tt>TDbDataReader</tt> instance, one can retrieve rows of resulting data by calling <tt>TDbDataReader.read()</tt> repeatedly. One can also use <tt>TDbDataReader</tt> in PHP's <tt>foreach</tt> language construct to retrieve row by row.
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_680143">
// calling read() repeatedly until it returns false
while(($row=$dataReader->read())!==false) { ... }
// using foreach to traverse through every row of data
@@ -88,17 +88,17 @@ foreach($dataReader as $row) { ... } $rows=$dataReader->readAll();
</com:TTextHighlighter>
-<h2>Using Transactions</h2>
-<p>
+<h2 id="136043">Using Transactions</h2>
+<p id="680472" class="block-content">
When an application executes a few queries, each reading and/or writing information in the database, it is important to be sure that the database is not left with only some of the queries carried out. A transaction, represented as a <tt>TDbTransaction</tt> instance in PRADO, may be initiated in this case:
</p>
-<ul>
+<ul id="u5" class="block-content">
<li>Begin the transaction.</li>
<li>Execute queries one by one. Any updates to the database are not visible to the outside world.</li>
<li>Commit the transaction. Updates become visible if the transaction is successful.</li>
<li>If one of the queries fails, the entire transaction is rolled back.</li>
</ul>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_680144">
$transaction=$connection->beginTransaction();
try
{
@@ -114,14 +114,14 @@ catch(Exception $e) // an exception is raised if a query fails will be raised </com:TTextHighlighter>
-<h2>Binding Parameters</h2>
-<p>
+<h2 id="136044">Binding Parameters</h2>
+<p id="680473" class="block-content">
To avoid <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL injection attacks</a> and to improve performance of executing repeatedly used SQL statements, one can "prepare" an SQL statement with optional parameter placeholders that are to be replaced with the actual parameters during the parameter binding process.
</p>
-<p>
+<p id="680474" class="block-content">
The parameter placeholders can be either named (represented as unique tokens) or unnamed (represented as question marks). Call <tt>TDbCommand.bindParameter()</tt> or <tt>TDbCommand.bindValue()</tt> to replace these placeholders with the actual parameters. The parameters do not need to be quoted: the underlying database driver does it for you. Parameter binding must be done before the SQL statement is executed.
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_680145">
// an SQL with two placeholders ":username" and ":email"
$sql="INSERT INTO users(username, email) VALUES(:username,:email)";
$command=$connection->createCommand($sql);
@@ -135,19 +135,19 @@ $command->bindParameter(":username",$username2,PDO::PARAM_STR); $command->bindParameter(":email",$email2,PDO::PARAM_STR);
$command->execute();
</com:TTextHighlighter>
-<p>
+<p id="680475" class="block-content">
The methods <tt>bindParameter()</tt> and <tt>bindValue()</tt> are very similar. The only difference is that the former binds a parameter with a PHP variable reference while the latter with a value. For parameters that represent large block of data memory, the former is preferred for performance consideration.
</p>
-<p>
+<p id="680476" class="block-content">
For more details about binding parameters, see the <a href="http://www.php.net/manual/en/function.pdostatement-bindparam.php">relevant PHP documentation</a>.
</p>
-<h2>Binding Columns</h2>
-<p>
+<h2 id="136045">Binding Columns</h2>
+<p id="680477" class="block-content">
When fetching query results, one can also bind columns with PHP variables so that they are automatically populated with the latest data each time a row is fetched.
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_680146">
$sql="SELECT username, email FROM users";
$dataReader=$connection->createCommand($sql)->query();
// bind the 1st column (username) with the $username variable
diff --git a/demos/quickstart/protected/pages/Database/SqlMap.page b/demos/quickstart/protected/pages/Database/SqlMap.page index 4b462168..bac1ba44 100644 --- a/demos/quickstart/protected/pages/Database/SqlMap.page +++ b/demos/quickstart/protected/pages/Database/SqlMap.page @@ -1,8 +1,8 @@ <com:TContent ID="body"> <!-- $Id $ --> -<h1>Data Mapper</h1> -<p>Data Mappers moves data between objects and a database while keeping them +<h1 id="140062">Data Mapper</h1> +<p id="700505" class="block-content">Data Mappers moves data between objects and a database while keeping them independent of each other and the mapper itself. If you started with <a href="?page=Database.ActiveRecord">Active Records</a>, you may eventually faced with more complex business @@ -12,28 +12,28 @@ that is, the object schema and the relational schema don't match up. </p> -<p>The Data Mapper separates the in-memory objects from the database. Its responsibility +<p id="700506" class="block-content">The Data Mapper separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other. With Data Mapper the in-memory objects needn't know even that there's a database present; they need no SQL interface code, and certainly no knowledge of the database schema. (The database schema is always ignorant of the objects that use it.) </p> -<h2>When to Use It</h2> -<p>The primary occasion for using Data Mapper is when you want the database schema +<h2 id="140063">When to Use It</h2> +<p id="700507" class="block-content">The primary occasion for using Data Mapper is when you want the database schema and the object model to evolve independently. Data Mapper's primary benefit is that when working on the business (or domain) objects you can ignore the database, both in design and in the build and testing process. The domain objects have no idea what the database structure is, because all the correspondence is done by the mappers. </p> -<p>This helps you in the code because you can understand and work with the domain objects +<p id="700508" class="block-content">This helps you in the code because you can understand and work with the domain objects without having to understand how they're stored in the database. You can modify the business models or the database without having to alter either. With complicated mappings, particularly those involving <b>existing databases</b>, this is very valuable. </p> -<p>The price, of course, is the extra layer that you don't get with +<p id="700509" class="block-content">The price, of course, is the extra layer that you don't get with <a href="?page=Database.ActiveRecord">Active Record</a>, so the test for using these patterns is the complexity of the business logic. If you have fairly simple business logic, an <a href="?page=Database.ActiveRecord">Active Record</a> @@ -41,8 +41,8 @@ For more complicated logic a Data Mapper may be more suitable. </p> -<h2>SqlMap Data Mapper</h2> -<p>The SqlMap DataMapper framework makes it easier to use a database with a PHP application. +<h2 id="140064">SqlMap Data Mapper</h2> +<p id="700510" class="block-content">The SqlMap DataMapper framework makes it easier to use a database with a PHP application. SqlMap DataMapper couples objects with stored procedures or SQL statements using a XML descriptor. Simplicity is the biggest advantage of the SqlMap DataMapper over object relational mapping tools. To use SqlMap DataMapper you rely on your own objects, @@ -51,7 +51,7 @@ your fingertip </p> -<p> +<p id="700511" class="block-content"> <img src=<%~ diagram.png %> alt="SqlMap Data Mapper Overview" id="fig:sqlmap.png" class="figure"/> Here's a high level description of the work flow illustrated in the figure abov. @@ -59,23 +59,23 @@ used to set runtime values in your SQL statement or stored procedure. If a runtime value is not needed, the parameter can be omitted. </p> -<p>Execute the mapping by passing the parameter and the name you gave the statement or +<p id="700512" class="block-content">Execute the mapping by passing the parameter and the name you gave the statement or procedure in your XML descriptor. This step is where the magic happens. The framework will prepare the SQL statement or stored procedure, set any runtime values using your parameter, execute the procedure or statement, and return the result. </p> -<p>In the case of an update, the number of rows affected is returned. In the case of a +<p id="700513" class="block-content">In the case of an update, the number of rows affected is returned. In the case of a query, a single object, or a collection of objects is returned. Like the parameter, the result object, or collection of objects, can be a plain-old object or a primitive PHP type. </p> -<h2>Setting up a database connection and initializing the SqlMap</h2> -<p> +<h2 id="140065">Setting up a database connection and initializing the SqlMap</h2> +<p id="700514" class="block-content"> A database connection for SqlMap can be set as follows. See <a href="?page=Database.DAO">Establishing Database Connection</a> for futher details regarding creation of database connection in general. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_700166"> //create a connection and give it to the SqlMap manager. $dsn = 'pgsql:host=localhost;dbname=test'; //Postgres SQL $conn = new TDbConnection($dsn, 'dbuser','dbpass'); @@ -85,7 +85,7 @@ $sqlmap = $manager->getSqlMapGateway(); </com:TTextHighlighter> </p> -<p> +<p id="700515" class="block-content"> The <tt>TSqlMapManager</tt> is responsible for setting up the database connection and configuring the SqlMap with given XML file(s). The <tt>configureXml()</tt> method accepts a string that points to a SqlMap XML configuration file. Once @@ -93,11 +93,11 @@ $sqlmap = $manager->getSqlMapGateway(); of the SqlMap gateway interface (use this object to insert/delete/find records). </p> -<p> +<p id="700516" class="block-content"> SqlMap database connection can also be configured using a <tt><module></tt> tag in the <a href="?page=Configurations.AppConfig">application.xml</a> or <a href="?page=Configurations.PageConfig">config.xml</a> as follows. -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_700167"> <modules> <module id="my-sqlmap" class="System.Data.SqlMap.TSqlMapConfig" EnableCache="true" ConfigFile="my-sqlmap.xml" > @@ -108,7 +108,7 @@ $sqlmap = $manager->getSqlMapGateway(); </com:TTextHighlighter> </p> -<p> +<p id="700517" class="block-content"> The <tt>ConfigFile</tt> attribute should point to a SqlMap configuration file (to be detailed later) either using absolute path, relative path or the Prado's namespace dot notation path (must omit the ".xml" extension). @@ -122,9 +122,9 @@ $sqlmap = $manager->getSqlMapGateway(); </div> </p> -<p>To obtain the SqlMap gateway interface from the <module> configuration, simply +<p id="700518" class="block-content">To obtain the SqlMap gateway interface from the <module> configuration, simply do, for example, -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_700168"> class MyPage extends TPage { public function onLoad($param) @@ -137,11 +137,11 @@ class MyPage extends TPage </com:TTextHighlighter> </p> -<h2>A quick example</h2> -<p>Let us +<h2 id="140066">A quick example</h2> +<p id="700519" class="block-content">Let us consider the following "users" table that contains two columns named "username" and "email", where "username" is also the primary key. -<com:TTextHighlighter Language="sql" CssClass="source"> +<com:TTextHighlighter Language="sql" CssClass="source block-content" id="code_700169"> CREATE TABLE users ( username VARCHAR( 20 ) NOT NULL , @@ -150,9 +150,9 @@ CREATE TABLE users ); </com:TTextHighlighter> </p> -<p>Next we define our plain <tt>User</tt> class as follows. Notice that +<p id="700520" class="block-content">Next we define our plain <tt>User</tt> class as follows. Notice that the <tt>User</tt> is very simple. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_700170"> class User { public $username; @@ -162,9 +162,9 @@ class User </p> </p> -<p>Next, we need to define a SqlMap XMl configuration file, lets name +<p id="700521" class="block-content">Next, we need to define a SqlMap XMl configuration file, lets name the file as <tt>my-sqlmap.xml</tt> -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_700171"> <?xml version="1.0" encoding="utf-8" ?> <sqlMapConfig> <select id="SelectUsers" resultClass="User"> @@ -173,12 +173,12 @@ class User </sqlMapConfig> </com:TTextHighlighter> </p> -<p>The <select> tag returns defines an SQL statement. The <tt>id</tt> +<p id="700522" class="block-content">The <select> tag returns defines an SQL statement. The <tt>id</tt> attribute will be used as the identifier for the query. The <tt>resultClass</tt> attribute value is the name of the class the the objects to be returned. We can now query the objects as follows: -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_700172"> //assume that $sqlmap is an TSqlMapGateway instance $userList = $sqlmap->queryForList("SelectUsers"); @@ -187,18 +187,18 @@ $user = $sqlmap->queryForObject("SelectUsers"); </com:TTextHighlighter> </p> -<p>The above example shows demonstrates only a fraction of the capabilities +<p id="700523" class="block-content">The above example shows demonstrates only a fraction of the capabilities of the SqlMap Data Mapper. Further details can be found in the <a href="http://www.pradosoft.com/demo/sqlamp/">SqlMap Manual</a>. </p> -<h2>Combining SqlMap with Active Records</h2> -<p>The above example may seem trival and it also seems that there is +<h2 id="140067">Combining SqlMap with Active Records</h2> +<p id="700524" class="block-content">The above example may seem trival and it also seems that there is alot work just to retrieve some data. However, notice that the <tt>User</tt> class is totally unware of been stored in the database, and the database is unware of the <tt>User</tt> class. </p> -<p> +<p id="700525" class="block-content"> One of advantages of SqlMap is the ability to map complex object relationship, collections from an existing database. On the other hand, <a href="?page=Database.ActiveRecord">Active Record</a> @@ -208,9 +208,9 @@ $user = $sqlmap->queryForObject("SelectUsers"); complicated relationships and collections as Active Record objects and then using these Active Records to do the updates, inserts and deletes. </p> -<p>Continuing with the previous example, we change the definition of the +<p id="700526" class="block-content">Continuing with the previous example, we change the definition of the <tt>User</tt> class to become an Active Record. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_700173"> class UserRecord extends TActiveRecord { public $username; //the column named "username" in the "users" table @@ -229,9 +229,9 @@ class UserRecord extends TActiveRecord </com:TTextHighlighter> </p> -<p>We also need to change the definition of the SqlMap XML configuration. We +<p id="700527" class="block-content">We also need to change the definition of the SqlMap XML configuration. We just need to change the value of <tt>resultClass</tt> attribute to <tt>UserRecord</tt>. -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_700174"> <?xml version="1.0" encoding="utf-8" ?> <sqlMapConfig> <select id="SelectUsers" resultClass="UserRecord"> @@ -242,10 +242,10 @@ class UserRecord extends TActiveRecord </p> -<p>The PHP code for retrieving the users remains the same, but SqlMap +<p id="700528" class="block-content">The PHP code for retrieving the users remains the same, but SqlMap returns Active Records instead, and we can take advantage of the Active Record methods. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_700175"> //assume that $sqlmap is an TSqlMapGateway instance $user = $sqlmap->queryForObject("SelectUsers"); @@ -254,8 +254,8 @@ $user->save(); //save it using Active Record </com:TTextHighlighter> </p> -<h2>References</h2> -<ul> +<h2 id="140068">References</h2> +<ul id="u1" class="block-content"> <li>Fowler et. al. <i>Patterns of Enterprise Application Architecture</i>, Addison Wesley, 2002.</li> <li>xxxx. <i>iBatis Data Mapper</i>, diff --git a/demos/quickstart/protected/pages/Fundamentals/Applications.page b/demos/quickstart/protected/pages/Fundamentals/Applications.page index 48db41e8..8fd22fa2 100644 --- a/demos/quickstart/protected/pages/Fundamentals/Applications.page +++ b/demos/quickstart/protected/pages/Fundamentals/Applications.page @@ -1,12 +1,12 @@ <com:TContent ID="body" >
<h1 id="1201">Applications</h1>
-<p>
+<p id="160157" class="block-content">
An application is an instance of <tt>TApplication</tt> or its derived class. It manages modules that provide different functionalities and are loaded when needed. It provides services to end-users. It is the central place to store various parameters used in an application. In a PRADO application, the application instance is the only object that is globally accessible via <tt>Prado::getApplication()</tt> function call.
</p>
-<p>
+<p id="160158" class="block-content">
Applications are configured via <a href="?page=Configurations.AppConfig">application configurations</a>. They are usually created in entry scripts like the following,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_160071">
require_once('/path/to/prado.php');
$application = new TApplication;
$application->run();
@@ -15,11 +15,11 @@ where the method <tt>run()</tt> starts the application to handle user requests. </p>
<h2 id="1202">Directory Organization</h2>
-<p>
+<p id="160159" class="block-content">
A minimal PRADO application contains two files: an entry file and a page template file. They must be organized as follows,
+<img src="<%~directory.gif%>" class="figure"/>
</p>
-<img src="<%~directory.gif%>" />
-<ul>
+<ul id="u2" class="block-content">
<li><tt>wwwroot</tt> - Web document root or sub-directory.</li>
<li><tt>index.php</tt> - entry script of the PRADO application.</li>
<li><tt>assets</tt> - directory storing published private files. See <a href="?page=Advanced.Assets">assets</a> section.</li>
@@ -29,12 +29,12 @@ A minimal PRADO application contains two files: an entry file and a page templat <li><tt>Home.page</tt> - default page returned when users do not explicitly specify the page requested. This is a page template file. The file name without suffix is the page name. The page class is <tt>TPage</tt>. If there is also a class file <tt>Home.php</tt>, the page class becomes <tt>Home</tt>.</li>
</ul>
-<p>
+<p id="160160" class="block-content">
A product PRADO application usually needs more files. It may include an application configuration file named <tt>application.xml</tt> under the application base path <tt>protected</tt>. The pages may be organized in directories, some of which may contain page configuration files named <tt>config.xml</tt>. Fore more details, please see <a href="?page=Configurations.Overview">configurations</a> section.
</p>
<h2 id="1203">Application Deployment</h2>
-<p>
+<p id="160161" class="block-content">
Deploying a PRADO application mainly involves copying directories. For example, to deploy the above minimal application to another server, follow the following steps,
</p>
<ol>
@@ -44,10 +44,10 @@ Deploying a PRADO application mainly involves copying directories. For example, </ol>
<h2 id="1204">Application Lifecycles</h2>
-<p>
+<p id="160162" class="block-content">
Like page lifecycles, an application also has lifecycles. Application modules can register for the lifecycle events. When the application reaches a particular lifecycle and raises the corresponding event, the registered module methods are invoked automatically. Modules included in the PRADO release, such as <tt>TAuthManager</tt>, are using this way to accomplish their goals.
</p>
-<p>
+<p id="160163" class="block-content">
The application lifecycles can be depicted as follows,
</p>
<img src="<%~applifecycles.gif%>" />
diff --git a/demos/quickstart/protected/pages/Fundamentals/Architecture.page b/demos/quickstart/protected/pages/Fundamentals/Architecture.page index 5811da71..4fa6434f 100644 --- a/demos/quickstart/protected/pages/Fundamentals/Architecture.page +++ b/demos/quickstart/protected/pages/Fundamentals/Architecture.page @@ -1,12 +1,12 @@ <com:TContent ID="body" >
<h1 id="601">Architecture</h1>
-<p>
+<p id="100111" class="block-content">
PRADO is primarily a presentational framework, although it is not limited to be so. The framework focuses on making Web programming, which deals most of the time with user interactions, to be component-based and event-driven so that developers can be more productive. The following class tree depicts some of the major classes provided by PRADO,
</p>
<img src="<%~classtree.gif%>" />
-<p>
+<p id="100112" class="block-content">
When a PRADO application is processing a page request, its static object diagram can be shown as follows,
</p>
<img src="<%~objectdiagram.gif%>" />
diff --git a/demos/quickstart/protected/pages/Fundamentals/Components.page b/demos/quickstart/protected/pages/Fundamentals/Components.page index dc4da67c..fdadc9af 100644 --- a/demos/quickstart/protected/pages/Fundamentals/Components.page +++ b/demos/quickstart/protected/pages/Fundamentals/Components.page @@ -1,13 +1,13 @@ <com:TContent ID="body" >
<h1 id="701">Components</h1>
-<p>
+<p id="110113" class="block-content">
A component is an instance of <tt>TComponent</tt> or its child class. The base class <tt>TComponent</tt> implements the mechanism of component properties and events.
</p>
<h2 id="702">Component Properties</h2>
-<p>
+<p id="110114" class="block-content">
A component property can be viewed as a public variable describing a specific aspect of the component, such as the background color, the font size, etc. A property is defined by the existence of a getter and/or a setter method in the component class. For example, in <tt>TControl</tt>, we define its <tt>ID</tt> property using the following getter and setter methods,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110056">
class TControl extends TComponent {
public function getID() {
...
@@ -18,34 +18,34 @@ class TControl extends TComponent { }
</com:TTextHighlighter>
</p>
-<p>
+<p id="110115" class="block-content">
To get or set the <tt>ID</tt> property, do as follows, just like working with a variable,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110057">
$id = $component->ID;
$component->ID = $id;
</com:TTextHighlighter>
This is equivalent to the following,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110058">
$id = $component->getID();
$component->setID( $id );
</com:TTextHighlighter>
</p>
-<p>
+<p id="110116" class="block-content">
A property is read-only if it has a getter method but no setter method. Since PHP method names are case-insensitive, property names are also case-insensitive. A component class inherits all its ancestor classes' properties.
</p>
<h3 id="706">Subproperties</h3>
-<p>
+<p id="110117" class="block-content">
A subproperty is a property of some object-typed property. For example, <tt>TWebControl</tt> has a <tt>Font</tt> property which is of <tt>TFont</tt> type. Then the <tt>Name</tt> property of <tt>Font</tt> is referred to as a subproperty (with respect to <tt>TWebControl</tt>).
</p>
-<p>
+<p id="110118" class="block-content">
To get or set the <tt>Name</tt> subproperty, use the following method,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110059">
$name = $component->getSubProperty('Font.Name');
$component->setSubProperty('Font.Name', $name);
</com:TTextHighlighter>
This is equivalent to the following,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110060">
$name = $component->getFont()->getName();
$component->getFont()->setName( $name );
</com:TTextHighlighter>
@@ -54,12 +54,12 @@ $component->getFont()->setName( $name ); </p>
<h2 id="703">Component Events</h2>
-<p>
+<p id="110119" class="block-content">
Component events are special properties that take method names as their values. Attaching (setting) a method to an event will hook up the method to the places at which the event is raised. Therefore, the behavior of a component can be modified in a way that may not be foreseen during the development of the component.
</p>
-<p>
+<p id="110120" class="block-content">
A component event is defined by the existence of a method whose name starts with the word <tt>on</tt>. The event name is the method name and is thus case-insensitve. For example, in <tt>TButton</tt>, we have
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110061">
class TButton extends TWebControl {
public function onClick( $param ) {
...
@@ -67,7 +67,7 @@ class TButton extends TWebControl { }
</com:TTextHighlighter>
This defines an event named <tt>OnClick</tt>, and a handler can be attached to the event using one of the following ways,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110062">
$button->OnClick = $callback;
$button->OnClick->add( $callback );
$button->OnClick[] = $callback;
@@ -77,40 +77,40 @@ where <tt>$callback</tt> refers to a valid PHP callback (e.g. a function name, a </p>
<h2 id="704">Namespaces</h2>
-<p>
+<p id="110121" class="block-content">
A namespace refers to a logical grouping of some class names so that they can be differentiated from other class names even if their names are the same. Since PHP does not support namespace intrinsically, you cannot create instances of two classes who have the same name but with different definitions. To differentiate from user defined classes, all PRADO classes are prefixed with a letter 'T' (meaning 'Type'). Users are advised not to name their classes like this. Instead, they may prefix their class names with any other letter(s).
</p>
-<p>
+<p id="110122" class="block-content">
A namespace in PRADO is considered as a directory containing one or several class files. A class may be specified without ambiguity using such a namespace followed by the class name. Each namespace in PRADO is specified in the following format,
<div class="source">
PathAlias.Dir1.Dir2
</div>
where <tt>PathAlias</tt> is an alias of some directory, while <tt>Dir1</tt> and <tt>Dir2</tt> are subdirectories under that directory. A class named <tt>MyClass</tt> defined under <tt>Dir2</tt> may now be fully qualified as <tt>PathAlias.Dir1.Dir2.MyClass</tt>.
</p>
-<p>
+<p id="110123" class="block-content">
To use a namespace in code, do as follows,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110063">
Prado::using('PathAlias.Dir1.Dir2.*');
</com:TTextHighlighter>
which appends the directory referred to by <tt>PathAlias.Dir1.Dir2</tt> into PHP include path so that classes defined under that directory may be instantiated without the namespace prefix. You may also include an individual class definition by
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110064">
Prado::using('PathAlias.Dir1.Dir2.MyClass');
</com:TTextHighlighter>
which will include the class file if <tt>MyClass</tt> is not defined.
</p>
-<p>
+<p id="110124" class="block-content">
For more details about defining path aliases, see <a href="?page=Configurations.AppConfig">application configuration</a> section.
</p>
<h2 id="705">Component Instantiation</h2>
-<p>
+<p id="110125" class="block-content">
Component instantiation means creating instances of component classes. There are two types of component instantation: static instantiation and dynamic instantiation. The created components are called static components and dynamic components, respectively.
</p>
<h3 id="707">Dynamic Component Instantiation</h3>
-<p>
+<p id="110126" class="block-content">
Dynamic component instantiation means creating component instances in PHP code. It is the same as the commonly referred object creation in PHP. A component can be dynamically created using one of the following two methods in PHP,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_110065">
$component = new ComponentClassName;
$component = Prado::createComponent('ComponentType');
</com:TTextHighlighter>
@@ -118,9 +118,9 @@ where <tt>ComponentType</tt> refers to a class name or a type name in namespace </p>
<h3 id="708">Static Component Instantiation</h3>
-<p>
+<p id="110127" class="block-content">
Static component instantiation is about creating components via <a href="?page=Configurations.Overview">configurations</a>. The actual creation work is done by the PRADO framework. For example, in an <a href="?page=Configurations.AppConfig">application configuration</a>, one can configure a module to be loaded when the application runs. The module is thus a static component created by the framework. Static component instantiation is more commonly used in <a href="?page=Configurations.Templates1">templates</a>. Every component tag in a template specifies a component that will be automatically created by the framework when the template is loaded. For example, in a page template, the following tag will lead to the creation of a <tt>TButton</tt> component on the page,
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_110066">
<com:TButton Text="Register" />
</com:TTextHighlighter>
</p>
diff --git a/demos/quickstart/protected/pages/Fundamentals/Controls.page b/demos/quickstart/protected/pages/Fundamentals/Controls.page index d36bff7a..a8b6815a 100644 --- a/demos/quickstart/protected/pages/Fundamentals/Controls.page +++ b/demos/quickstart/protected/pages/Fundamentals/Controls.page @@ -1,16 +1,16 @@ <com:TContent ID="body" >
<h1 id="801">Controls</h1>
-<p>
+<p id="120128" class="block-content">
A control is an instance of class <tt>TControl</tt> or its subclass. A control is a component defined in addition with user interface. The base class <tt>TControl</tt> defines the parent-child relationship among controls which reflects the containment relationship among user interface elements.
</p>
<h2 id="802">Control Tree</h2>
-<p>
+<p id="120129" class="block-content">
Controls are related to each other via parent-child relationship. Each parent control can have one or several child controls. A parent control is in charge of the state transition of its child controls. The rendering result of the child controls are usually used to compose the parent control's presentation. The parent-child relationship brings together controls into a control tree. A page is at the root of the tree, whose presentation is returned to the end-users.
</p>
-<p>
+<p id="120130" class="block-content">
The parent-child relationship is usually established by the framework via <a href="?page=Configurations.Templates1">templates</a>. In code, you may explicitly specify a control as a child of another using one of the following methods,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_120067">
$parent->Controls->add($child);
$parent->Controls[]=$child;
</com:TTextHighlighter>
@@ -18,28 +18,28 @@ where the property <tt>Controls</tt> refers to the child control collection of t </p>
<h2 id="803">Control Identification</h2>
-<p>
+<p id="120131" class="block-content">
Each control has an <tt>ID</tt> property that can be uniquely identify itself among its sibling controls. In addition, each control has a <tt>UniqueID</tt> and a <tt>ClientID</tt> which can be used to globally identify the control in the tree that the control resides in. <tt>UniqueID</tt> and <tt>ClientID</tt> are very similar. The former is used by the framework to determine the location of the corresponding control in the tree, while the latter is mainly used on the client side as HTML tag IDs. In general, you should not rely on the explicit format of <tt>UniqueID</tt> or <tt>ClientID</tt>.
</p>
<h2 id="804">Naming Containers</h2>
-<p>
+<p id="120132" class="block-content">
Each control has a naming container which is a control creating a unique namespace for differentiating between controls with the same <tt>ID</tt>. For example, a <tt>TRepeater</tt> control creates multiple items each having child controls with the same <tt>ID</tt>s. To differentiate these child controls, each item serves as a naming container. Therefore, a child control may be uniquely identified using its naming container's <tt>ID</tt> together with its own <tt>ID</tt>. As you may already have understood, <tt>UniqueID</tt> and <tt>ClientID</tt> rely on the naming containers.
</p>
-<p>
+<p id="120133" class="block-content">
A control can serve as a naming container if it implements the <tt>INamingContainer</tt> interface.
</p>
<h2 id="805">ViewState and ControlState</h2>
-<p>
+<p id="120134" class="block-content">
HTTP is a stateless protocol, meaning it does not provide functionality to support continuing interaction between a user and a server. Each request is considered as discrete and independent of each other. A Web application, however, often needs to know what a user has done in previous requests. People thus introduce sessions to help remember such state information.
</p>
-<p>
+<p id="120135" class="block-content">
PRADO borrows the viewstate and controlstate concept from Microsoft ASP.NET to provides additional stateful programming mechanism. A value storing in viewstate or controlstate may be available to the next requests if the new requests are form submissions (called postback) to the same page by the same user. The difference between viewstate and controlstate is that the former can be disabled while the latter cannot.
</p>
-<p>
+<p id="120136" class="block-content">
Viewstate and controlstate are implemented in <tt>TControl</tt>. They are commonly used to define various properties of controls. To save and retrieve values from viewstate or controlstate, use following methods,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_120068">
$this->getViewState('Name',$defaultValue);
$this->setViewState('Name',$value,$defaultValue);
$this->getControlState('Name',$defaultValue);
diff --git a/demos/quickstart/protected/pages/Fundamentals/Hangman.page b/demos/quickstart/protected/pages/Fundamentals/Hangman.page index 56180b9e..01a7dc80 100644 --- a/demos/quickstart/protected/pages/Fundamentals/Hangman.page +++ b/demos/quickstart/protected/pages/Fundamentals/Hangman.page @@ -1,13 +1,12 @@ <com:TContent ID="body" >
<h1 id="1301">Sample: Hangman Game</h1>
-<p>
+<p id="60043" class="block-content">
Having seen the simple "Hello World" application, we now build a more complex application called "Hangman Game". In this game, the player is asked to guess a word, a letter at a time. If he guesses a letter right, the letter will be shown in the word. The player can continue to guess as long as the number of his misses is within a prespecified bound. The player wins the game if he finds out the word within the miss bound, or he loses.
</p>
-<p>
+<p id="60044" class="block-content">
To facilitate the building of this game, we show the state transition diagram of the gaming process in the following,
-</p>
-<p>
+<br /><br />
To be continued...
</p>
<com:RunBar PagePath="Fundamentals.Samples.Hangman.Home" />
diff --git a/demos/quickstart/protected/pages/Fundamentals/Modules.page b/demos/quickstart/protected/pages/Fundamentals/Modules.page index df67f0f3..0ac82016 100644 --- a/demos/quickstart/protected/pages/Fundamentals/Modules.page +++ b/demos/quickstart/protected/pages/Fundamentals/Modules.page @@ -1,49 +1,49 @@ <com:TContent ID="body" >
<h1 id="1001">Modules</h1>
-<p>
+<p id="140141" class="block-content">
A module is an instance of a class implementing the <tt>IModule</tt> interface. A module is commonly designed to provide specific functionality that may be plugged into a PRADO application and shared by all components in the application.
</p>
-<p>
+<p id="140142" class="block-content">
PRADO uses configurations to specify whether to load a module, load what kind of modules, and how to initialize the loaded modules. Developers may replace the core modules with their own implementations via application configuration, or they may write new modules to provide additional functionalities. For example, a module may be developed to provide common database logic for one or several pages. For more details, please see the <a href="?page=Configurations.Overview">configurations</a>.
</p>
-<p>
+<p id="140143" class="block-content">
There are three core modules that are loaded by default whenever an application runs. They are <a href="#request">request module</a>, <a href="#response">response module</a>, and <a href="#error">error handler module</a>. In addition, <a href="#session">session module</a> is loaded when it is used in the application. PRADO provides default implementation for all these modules. <a href="#custom">Custom modules</a> may be configured or developed to override or supplement these core modules.
</p>
<a name="request"></a>
<h2 id="1002">Request Module</h2>
-<p>
+<p id="140144" class="block-content">
Request module represents provides storage and access scheme for user request sent via HTTP. User request data comes from several sources, including URL, post data, session data, cookie data, etc. These data can all be accessed via the request module. By default, PRADO uses <tt>THttpRequest</tt> as request module. The request module can be accessed via the <tt>Request</tt> property of application and controls.
</p>
<a name="response"></a>
<h2 id="1003">Response Module</h2>
-<p>
+<p id="140145" class="block-content">
Response module implements the mechanism for sending output to client users. Response module may be configured to control how output are cached on the client side. It may also be used to send cookies back to the client side. By default, PRADO uses <tt>THttpResponse</tt> as response module. The response module can be accessed via the <tt>Response</tt> property of application and controls.
</p>
<a name="session"></a>
<h2 id="1004">Session Module</h2>
-<p>
+<p id="140146" class="block-content">
Session module encapsulates the functionalities related with user session handling. Session module is automatically loaded when an application uses session. By default, PRADO uses <tt>THttpSession</tt> as session module, which is a simple wrapper of the session functions provided by PHP. The session module can be accessed via the <tt>Session</tt> property of application and controls.
</p>
<a name="error"></a>
<h2 id="1005">Error Handler Module</h2>
-<p>
+<p id="140147" class="block-content">
Error handler module is used to capture and process all error conditions in an application. PRADO uses <tt>TErrorHandler</tt> as error handler module. It captures all PHP warnings, notices and exceptions, and displays in an appropriate form to end-users. The error handler module can be accessed via the <tt>ErrorHandler</tt> property of the application instance.
</p>
<a name="custom"></a>
<h2 id="1006">Custom Modules</h2>
-<p>
+<p id="140148" class="block-content">
PRADO is released with a few more modules besides the core ones. They include caching modules (<tt>TSqliteCache</tt> and <tt>TMemCache</tt>), user management module (<tt>TUserManager</tt>), authentication and authorization module (<tt>TAuthManager</tt>), etc.
</p>
-<p>
+<p id="140149" class="block-content">
When <tt>TPageService</tt> is requested, it also loads modules specific for page service, including asset manager (<tt>TAssetManager</tt>), template manager (<tt>TTemplateManager</tt>), theme/skin manager (<tt>TThemeManager</tt>).
</p>
-<p>
+<p id="140150" class="block-content">
Custom modules and core modules are all configurable via <a href="?page=Configurations.Overview">configurations</a>.
</p>
diff --git a/demos/quickstart/protected/pages/Fundamentals/Pages.page b/demos/quickstart/protected/pages/Fundamentals/Pages.page index 3403bddc..8042ddcd 100644 --- a/demos/quickstart/protected/pages/Fundamentals/Pages.page +++ b/demos/quickstart/protected/pages/Fundamentals/Pages.page @@ -1,21 +1,21 @@ <com:TContent ID="body" >
<h1 id="901">Pages</h1>
-<p>
+<p id="130137" class="block-content">
Pages are top-most controls that have no parent. The presentation of pages are directly displayed to end-users. Users access pages by sending page service requests.
</p>
-<p>
+<p id="130138" class="block-content">
Each page must have a <a href="?page=Configurations.Templates1">template</a> file. The file name suffix must be <tt>.page</tt>. The file name (without suffix) is the page name. PRADO will try to locate a page class file under the directory containing the page template file. Such a page class file must have the same file name (suffixed with <tt>.php</tt>) as the template file. If the class file is not found, the page will take class <tt>TPage</tt>.
</p>
<h2 id="902">PostBack</h2>
-<p>
+<p id="130139" class="block-content">
A form submission is called <i>postback</i> if the submission is made to the page containing the form. Postback can be considered an event happened on the client side, raised by the user. PRADO will try to identify which control on the server side is responsible for a postback event. If one is determined, for example, a <tt>TButton</tt>, we call it the postback event sender which will translate the postback event into some specific server-side event (e.g. <tt>OnClick</tt> and <tt>OnCommand</tt> events for <tt>TButton</tt>).
</p>
<h2 id="903">Page Lifecycles</h2>
-<p>
+<p id="130140" class="block-content">
Understanding the page lifecycles is crucial to grasp PRADO programming. Page lifecycles refer to the state transitions of a page when serving this page to end-users. They can be depicted in the following statechart,
<img src="<%~lifecycles.gif %>" />
</p>
diff --git a/demos/quickstart/protected/pages/Fundamentals/Services.page b/demos/quickstart/protected/pages/Fundamentals/Services.page index 920c6bea..803f76e0 100644 --- a/demos/quickstart/protected/pages/Fundamentals/Services.page +++ b/demos/quickstart/protected/pages/Fundamentals/Services.page @@ -1,29 +1,29 @@ <com:TContent ID="body" >
<h1 id="1101">Services</h1>
-<p>
+<p id="150151" class="block-content">
A service is an instance of a class implementing the <tt>IService</tt> interface. Each kind of service processes a specific type of user requests. For example, the page service responds to users' requests for PRADO pages.
</p>
-<p>
+<p id="150152" class="block-content">
A service is uniquely identified by its <tt>ID</tt> property. By default when <tt>THttpRequest</tt> is used as the <a href="?page=Fundamentals.Modules#request">request module</a>, GET variable names are used to identify which service a user is requesting. If a GET variable name is equal to some service <tt>ID</tt>, the request is considered for that service, and the value of the GET variable is passed as the service parameter. For page service, the name of the GET variable must be <tt>page</tt>. For example, the following URL requests for the <tt>Fundamentals.Services</tt> page,
-<com:TTextHighlighter Language="none" CssClass="source">
+<com:TTextHighlighter Language="none" CssClass="source block-content" id="code_150069">
http://hostname/index.php?page=Fundamentals.Services
</com:TTextHighlighter>
</p>
-<p>
+<p id="150153" class="block-content">
Developers may implement additional services for their applications. To make a service available, configure it in <a href="?page=Configurations.AppConfig">application configurations</a>.
</p>
<h2 id="1102">Page Service</h2>
-<p>
+<p id="150154" class="block-content">
PRADO implements <tt>TPageService</tt> to process users' page requests. Pages are stored under a directory specified by the <tt>BasePath</tt> property of the page service. The property defaults to <tt>pages</tt> directory under the application base path. You may change this default by configuring the service in the application configuration.
</p>
-<p>
+<p id="150155" class="block-content">
Pages may be organized into subdirectories under the <tt>BasePath</tt>. In each directory, there may be a page configuration file named <tt>config.xml</tt>, which contains configurations effective only when a page under that directory or a sub-directory is requested. For more details, see the <a href="?page=Configurations.PageConfig">page configuration</a> section.
</p>
-<p>
+<p id="150156" class="block-content">
Service parameter for the page service refers to the page being requested. A parameter like <tt>Fundamentals.Services</tt> refers to the <tt>Services</tt> page under the <tt><BasePath>/Fundamentals</tt> directory. If such a parameter is absent in a request, a default page named <tt>Home</tt> is assumed. Using <tt>THttpRequest</tt> as the request module (default), the following URLs will request for <tt>Home</tt>, <tt>About</tt> and <tt>Register</tt> pages, respectively,
-<com:TTextHighlighter Language="none" CssClass="source">
+<com:TTextHighlighter Language="none" CssClass="source block-content" id="code_150070">
http://hostname/index.php
http://hostname/index.php?page=About
http://hostname/index.php?page=Users.Register
diff --git a/demos/quickstart/protected/pages/GettingStarted/AboutPrado.page b/demos/quickstart/protected/pages/GettingStarted/AboutPrado.page index dc8de7ae..56eca64e 100644 --- a/demos/quickstart/protected/pages/GettingStarted/AboutPrado.page +++ b/demos/quickstart/protected/pages/GettingStarted/AboutPrado.page @@ -1,26 +1,26 @@ <com:TContent ID="body" >
<h1 id="201">What is PRADO?</h1>
-<p>
+<p id="20003" class="block-content">
PRADO is a component-based and event-driven programming framework for developing Web applications in PHP 5. PRADO stands for <b>P</b>HP <b>R</b>apid <b>A</b>pplication <b>D</b>evelopment <b>O</b>bject-oriented.
</p>
-<p>
+<p id="20004" class="block-content">
A primary goal of PRADO is to enable maximum reusability in Web programming. By reusability, we mean not only reusing one's own code, but also reusing other people's code in an easy way. The latter is more important as it saves the effort of reinventing the wheels and may cut off development time dramatically. The introduction of the concept of component is for this purpose.
</p>
-<p>
+<p id="20005" class="block-content">
To achieve the above goal, PRADO stipulates a protocol of writing and using components to construct Web applications. A component is a software unit that is self-contained and can be reused with trivial customization. New components can be created by simple composition of existing components.
</p>
-<p>
+<p id="20006" class="block-content">
To facilitate interacting with components, PRADO implements an event-driven programming paradigm that allows delegation of extensible behavior to components. End-user activities, such as clicking on a submit button, are captured as server events. Methods or functions may be attached to these events so that when the events happen, they are invoked automatically to respond to the events. Compared with the traditional Web programming in which developers have to deal with the raw POST or GET variables, event-driven programming helps developers better focus on the necessary logic and reduces significantly the low-level repetitive coding.
</p>
-<p>
+<p id="20007" class="block-content">
In summary, developing a PRADO Web application mainly involves instantiating prebuilt component types, configuring them by setting their properties, responding to their events by writing handler functions, and composing them into pages for the application. It is very similar to RAD toolkits, such as Borland Delphi and Microsoft Visual Basic, that are used to develop desktop GUI applications.
</p>
<h2 id="202">Why PRADO?</h2>
-<p>
+<p id="20008" class="block-content">
PRADO is mostly quoted as a unique framework. In fact, it is so unique that it may turn your boring PHP programming into a fun task. The following list is a short summary of the main features of PRADO,
</p>
-<ul>
+<ul id="prado-features" class="block-content">
<li>Reusability - Code following the PRADO component protocol are highly reusable. Everything in PRADO is a reusable component.</li>
<li>Event-driven programming - End-user activities, such as clicking on a submit button, are captured as server events so that developers have better focus on dealing with user interactions.</li>
<li>Team integration - Presentation and logic are separately stored. PRADO applications are themable.</li>
@@ -33,35 +33,35 @@ PRADO is mostly quoted as a unique framework. In fact, it is so unique that it m </ul>
<h2 id="203">What Is PRADO Best For?</h2>
-<p>
+<p id="20009" class="block-content">
PRADO is best suitable for creating Web front-ends that are highly user-interactive and require small to medium traffic. It can be used to develop systems as simple as a blog system to systems as complex as a content management system (CMS) or a complete e-commerce solution. PRADO can help you cut your development time significantly.
</p>
-<p>
+<p id="20010" class="block-content">
PRADO does not exclude other back-end solutions such as most DB abstraction layers. In fact, they can be used like what you usually do with traditional PHP programming.
</p>
-<p>
+<p id="20011" class="block-content">
Without caching techniques, PRADO may not be suitable for developing extremely high-traffic Web applications, such as popular portals, forums, etc. In these applications, every niche of potential performance gain must be exploited and server caching (e.g. Zend optimizer) is almost a must. PRADO implements a generic cache technique and enables selective caching of part of Web contents.
</p>
<h2 id="204">How Is PRADO Compared with Other Frameworks?</h2>
-<p>
+<p id="20012" class="block-content">
PRADO is described as a unique framework. Its uniqueness mainly lies in the component-based and event-driven programming paradigm that it tries to promote. Although this programming paradigm is not new in desktop application programming and not new in a few Web programming languages, PRADO is perhaps the first PHP framework enabling it.
</p>
-<p>
+<p id="20013" class="block-content">
Most PHP frameworks are trying to establish a loose standard of organizing PHP programming, most preferably the MVC (model-view-controller) model. It is difficult to compare PRADO with these frameworks because they have different focuses. What we can say is, PRADO is more like a high-level language built upon PHP, while the MVC frameworks stand for the best programming practices. Both aim to help developers to rapidly complete Web application development. The advantage of PRADO is its rich set of prebuilt powerful components and extreme reusability of the PRADO code, while the advantage of the MVC frameworks is the complete separation of model, view and controller, which greatly facilitates team integration.
</p>
<h2 id="205">History of PRADO</h2>
-<p>
+<p id="20014" class="block-content">
The very original inspiration of PRADO came from Apache Tapestry. During the design and implementation, I borrowed many ideas from Borland Delphi and Microsoft ASP.NET. The first version of PRADO came out in June 2004 and was written in PHP 4. Driven by the Zend PHP 5 coding contest, I rewrote PRADO in PHP 5, which proved to be a wise move, thanks to the new object model provided by PHP 5. PRADO won the grand prize in the Zend contest, earning the highest votes from both the public and the judges' panel.
</p>
-<p>
+<p id="20015" class="block-content">
In August 2004, PRADO started to be hosted on SourceForge as an open source project. Soon after, the project site <a href="http://www.xisc.com/">xisc.com</a> was announced to public. With the fantastic support of PRADO developer team and PRADO users, PRADO evolved to version 2.0 in mid 2005. In this version, Wei Zhuo contributed to PRADO with the excellent I18N and L10N support.
</p>
-<p>
+<p id="20016" class="block-content">
In May 2005, we decided to completely rewrite the PRADO framework to resolve a few fundamental issues found in version 2.0 and to catch up with some cool features available in Microsoft ASP.NET 2.0. After nearly a year's hard work with over 50,000 lines of new code, version 3.0 was finally made available in April 2006.
</p>
-<p>
+<p id="20017" class="block-content">
Starting from version 3.0, significant efforts are allocated to ensure the quality and stability of PRADO. If we say PRADO v2.x and v1.x are proof-of-concept work, we can say PRADO 3.x has grown up to a project that is suitable for serious business application development.
</p>
diff --git a/demos/quickstart/protected/pages/GettingStarted/CommandLine.page b/demos/quickstart/protected/pages/GettingStarted/CommandLine.page index 690de59b..a3f7df00 100644 --- a/demos/quickstart/protected/pages/GettingStarted/CommandLine.page +++ b/demos/quickstart/protected/pages/GettingStarted/CommandLine.page @@ -1,24 +1,24 @@ <com:TContent ID="body" >
<h1 id="501">Command Line Tool</h1>
-<p>The optional <tt>prado-cli.php</tt> PHP script file in the <tt>framework</tt>
+<p id="70046" class="block-content">The optional <tt>prado-cli.php</tt> PHP script file in the <tt>framework</tt>
directory provides command line tools to perform various tedious takes in Prado.
The <tt>prado-cli.php</tt> can be used to create Prado project skeletons, create
initial test fixtures, and access to an interactive PHP shell.
</p>
<h2 id="502">Requirements</h2>
-<p>
+<p id="70047" class="block-content">
To use the command line tool, you need to use your command prompt, command console
or terminal. In addition, PHP must be able to execute PHP scripts from
the command line.
</p>
<h2 id="503">Usage</h2>
-<p>
+<p id="70048" class="block-content">
If you type <tt>php path/to/framework/prado-cli.php</tt>, you should see
the following information. Alternatively, if you are not on Windows,
you may try to change the <tt>prado-cli.php</tt> into an executable
and execute it as a script</p>
-<com:TTextHighlighter Language="cli" CssClass="source">
+<com:TTextHighlighter Language="cli" CssClass="source block-content" id="code_70006">
Command line tools for Prado 3.0.5.
usage: php prado-cli.php action <parameter> [optional]
example: php prado-cli.php -c mysite
@@ -35,12 +35,12 @@ actions: application in the given [directory].
</com:TTextHighlighter>
-<p>The <b><parameter></b> are required parameters and <b>[optional]</b>
+<p id="70049" class="block-content">The <b><parameter></b> are required parameters and <b>[optional]</b>
are optional parameters. </p>
<h2 id="504">Creating a new Prado project skeleton</h2>
-<p>To create a Prado project skeleton, do the following:</p>
+<p id="70050" class="block-content">To create a Prado project skeleton, do the following:</p>
<ol>
<li>Change to the directory where you want to create the project skeleton.</li>
<li>Type, <tt>php ../prado/framework/prado-cli.php -c helloworld</tt>, where
@@ -50,18 +50,18 @@ are optional parameters. </p> </ol>
<h2 id="505">Interactive Shell</h2>
-<p>
+<p id="70051" class="block-content">
The interactive shell allows you to evaluate PHP statements from the command line.
The <tt>prado-cli.php</tt> script can be used to start the shell and load an existing
Prado project. For example, let us load the blog demo project. Assume that your
command line is in the <tt>prado</tt> distribution directory and you type.
</p>
-<p>
-<com:TTextHighlighter Language="cli" CssClass="source">
+<p id="70052" class="block-content">
+<com:TTextHighlighter Language="cli" CssClass="source block-content" id="code_70007">
$: php framework/prado-cli.php shell demos/blog
</com:TTextHighlighter>
The output should be
-<com:TTextHighlighter Language="cli" CssClass="source">
+<com:TTextHighlighter Language="cli" CssClass="source block-content" id="code_70008">
Command line tools for Prado 3.0.5.
** Loaded Prado application in directory "demos\blog\protected".
PHP-Shell - Version 0.3.1
@@ -75,18 +75,18 @@ Then we will get an instance of the Prado blog application, and from that instance we want an instance of the <tt>'data'</tt> module. Notice that
a <b>semicolon</b> at the end of the line <b>suppresses the output</b>.
-<com:TTextHighlighter Language="cli" CssClass="source">
+<com:TTextHighlighter Language="cli" CssClass="source block-content" id="code_70009">
>> $app = Prado::getApplication();
>> $db = $app->getModule('data');
</com:TTextHighlighter>
Lastly, we want to use the data module to query for a post with <tt>ID=1</tt>. Notice that
we <b>leave out the semicolon</b> to show the results.
-<com:TTextHighlighter Language="cli" CssClass="source">
+<com:TTextHighlighter Language="cli" CssClass="source block-content" id="code_70010">
>> $db->queryPostByID(1)
</com:TTextHighlighter>
There should not be any errors and you should see the following.
-<com:TTextHighlighter Language="cli" CssClass="source">
+<com:TTextHighlighter Language="cli" CssClass="source block-content" id="code_70011">
PostRecord#1
(
[ID] => 1
diff --git a/demos/quickstart/protected/pages/GettingStarted/HelloWorld.page b/demos/quickstart/protected/pages/GettingStarted/HelloWorld.page index 97d4f72d..0d51ab6d 100644 --- a/demos/quickstart/protected/pages/GettingStarted/HelloWorld.page +++ b/demos/quickstart/protected/pages/GettingStarted/HelloWorld.page @@ -1,26 +1,27 @@ <com:TContent ID="body" >
<h1 id="401">My First PRADO Application</h1>
-<p>
+<div id="hello1" class="block-content">
+<p id="50034">
In this section, we guide you through creating your first PRADO application, the famous "Hello World" application.
</p>
-<p>
+<p id="50035">
"Hello World" perhaps is the simplest <i>interactive</i> PRADO application that you can create. It displays to end-users a page with a submit button whose caption is <tt>Click Me</tt>. After the user clicks on the button, its caption is changed to <tt>Hello World</tt>.
</p>
-<p>
+<p id="50036">
There are many approaches that can achieve the above goal. One can submit the page to the server, examine the POST variable, and generate a new page with the button caption updated. Or one can simply use JavaScript to update the button caption upon its <tt>onclick</tt> client event.
</p>
-<p>
+</div>
+<p id="50037" class="block-content">
PRADO promotes component-based and event-driven Web programming. The button is represented by a <tt>TButton</tt> object. It encapsulates the button caption as the <tt>Text</tt> property and associates the user button click action with a server-side <tt>OnClick</tt> event. To respond to the user clicking on the button, one simply needs to attach a function to the button's <tt>OnClick</tt> event. Within the function, the button's <tt>Text</tt> property is modified as "Hello World". The following diagram shows the above sequence,
+<img src="<%~sequence.gif%>" class="figure"/>
</p>
-<img src="<%~sequence.gif%>" />
-<p>
+<p id="50038" class="block-content">
Our PRADO application consists of three files, <tt>index.php</tt>, <tt>Home.page</tt> and <tt>Home.php</tt>, which are organized as follows,
-</p>
-<img src="<%~directory.gif%>" />
-<p>
+<img src="<%~directory.gif%>" class="figure"/>
+
where each directory is explained as follows. Note, the above directory structure can be customized. For example, one can move the <tt>protected</tt> directory out of Web directories. You will know how to do this after you go through this tutorial.
</p>
-<ul>
+<ul id="dir-struct" class="block-content">
<li><tt>assets</tt> - directory storing published private files. See <a href="?page=Advanced.Assets">assets</a> section for more details. This directory must be writable by the Web server process.</li>
<li><tt>protected</tt> - application base path storing application data and private script files. This directory should be configured as inaccessible to end-users.</li>
<li><tt>runtime</tt> - application runtime storage path storing application runtime information, such as application state, cached data, etc. This directory must be writable by the Web server process.</li>
@@ -28,26 +29,26 @@ where each directory is explained as follows. Note, the above directory structur </ul>
<div class="tip">
-<b class="tip">Tip:</b>You may also use the <tt>framework/prado-cli.php</tt>
-<a href="?page=GettingStarted.CommandLine">command line script</a>
+<b class="tip">Tip:</b>You may also use the <tt>framework/prado-cli.php</tt>
+<a href="?page=GettingStarted.CommandLine">command line script</a>
to create the Prado project directory structure. For example, type the command
<tt>php path/to/prado-cli.php -c helloworld</tt> in the directory
where you want to create the <tt>helloworld</tt> project.
</div>
-<p>
+<p id="50040">
The three files that we need are explained as follows.
</p>
-<ul>
+<ul id="file-list" class="block-content">
<li><tt>index.php</tt> - entry script of the PRADO application. This file is required by all PRADO applications and is the only script file that is directly accessible by end-users. Content in <tt>index.php</tt> mainly consists of the following three lines,
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_50003">
require_once('path/to/prado.php'); // include the prado script
$application=new TApplication; // create a PRADO application instance
$application->run(); // run the application
</com:TTextHighlighter>
</li>
<li><tt>Home.page</tt> - template for the default page returned when users do not explicitly specify the page requested. A template specifies the presentational layout of components. In this example, we use two components, <tt>TForm</tt> and <tt>TButton</tt>, which correspond to the <form> and <input> HTML tags, respectively. The template contains the following content,
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_50004">
<html>
<body>
<com:TForm>
@@ -58,7 +59,7 @@ $application->run(); // run the application </com:TTextHighlighter>
</li>
<li><tt>Home.php</tt> - page class for the <tt>Home</tt> page. It mainly contains the method responding to the <tt>OnClick</tt> event of the button.
-<com:TTextHighlighter CssClass="source">
+<com:TTextHighlighter CssClass="source block-content" id="code_50005">
class Home extends TPage
{
public function buttonClicked($sender,$param)
@@ -70,11 +71,13 @@ class Home extends TPage </com:TTextHighlighter>
</li>
</ul>
-<p>
+<div id="hello-end" class="block-content">
+<p id="50041">
The application is now ready and can be accessed via: <tt>http://Web-server-address/helloworld/index.php</tt>, assuming <tt>helloworld</tt> is directly under the Web <tt>DocumentRoot</tt>. Try to change <tt>TButton</tt> in <tt>Home.page</tt> to <tt>TLinkButton</tt> and see what happens.
</p>
-<p>
+<p id="50042">
Complete source code of this demo can be found in the PRADO release. You can also try the <a href="http://www.pradosoft.com/demos/helloworld/">online demo</a>.
</p>
+</div>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/GettingStarted/Installation.page b/demos/quickstart/protected/pages/GettingStarted/Installation.page index 07a76042..f38fe32a 100644 --- a/demos/quickstart/protected/pages/GettingStarted/Installation.page +++ b/demos/quickstart/protected/pages/GettingStarted/Installation.page @@ -1,22 +1,29 @@ <com:TContent ID="body" >
<h1 id="301">Installing PRADO</h1>
-<p>
+<div id="install-info" class="block-content">
+<p id="30018">
If you are viewing this page from your own Web server, you are already done with the installation.
</p>
-<p>
+<p id="30019">
The minimum requirement by PRADO is that the Web server support PHP 5. PRADO has been tested with Apache Web server on Windows and Linux. Highly possibly it may also run on other platforms with other Web servers, as long as PHP 5 is supported.
</p>
-<p>
+</div>
+
+<div id="install-steps" class="block-content">
+<p id="30020">
Installation of PRADO mainly involves downloading and unpacking.
</p>
<ol>
<li>Go to <a href="http://www.pradosoft.com/">pradosoft.com</a> to grab the latest version of PRADO.</li>
<li>Unpack the PRADO release file to a Web-accessible directory.
</ol>
-<p>
+</div>
+<div id="install-after" class="block-content">
+<p id="30021">
Your installation of PRADO is done and you can start to play with the demo applications included in the PRADO release via URL <tt>http://web-server-address/prado/demos/</tt>. Here we assume PRADO is unpacked to the <tt>prado</tt> subdirectory under the <tt>DocumentRoot</tt> of the Web server.
</p>
-<p>
+<p id="30022">
If you encounter any problems with the demo applications, please use the PRADO requirement checker script, accessible via <tt>http://web-server-address/prado/requirements/index.php</tt>, to check first if your server configuration fulfills the conditions required by PRADO.
</p>
+</div>
</com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/GettingStarted/Introduction.page b/demos/quickstart/protected/pages/GettingStarted/Introduction.page index 52b7d9af..ab672baa 100644 --- a/demos/quickstart/protected/pages/GettingStarted/Introduction.page +++ b/demos/quickstart/protected/pages/GettingStarted/Introduction.page @@ -1,12 +1,14 @@ <com:TContent ID="body" >
<h1 id="101">Welcome to the PRADO Quickstart Tutorial</h1>
-<p>
+<div id="intro" class="block-content">
+<p id="10001">
This Quickstart tutorial is provided to help you quickly start building your own Web applications based on PRADO version 3.x.
</p>
-<p>
+<p id="10002">
You may refer to the following resources if you find this tutorial does not fulfill all your needs.
</p>
-<ul>
+</div>
+<ul class="block-content" id="intro-links">
<li><a href="http://www.pradosoft.com/docs/classdoc/">PRADO Classes</a></li>
<li><a href="http://www.pradosoft.com/docs/manual/">PRADO API Documentation</a></li>
<li><a href="http://www.pradosoft.com/forum/">PRADO Forum</a></li>
diff --git a/demos/quickstart/protected/pages/GettingStarted/Upgrading.page b/demos/quickstart/protected/pages/GettingStarted/Upgrading.page index cff4e72f..d93fdca7 100644 --- a/demos/quickstart/protected/pages/GettingStarted/Upgrading.page +++ b/demos/quickstart/protected/pages/GettingStarted/Upgrading.page @@ -2,59 +2,62 @@ <h1 id="501">Upgrading from v2.x and v1.x</h1>
-<p>
+<div id="from-2-or-1" class="block-content">
+<p id="40023">
PRADO v3.0 is NOT backward compatible with earlier versions of PRADO.
</p>
-<p>
+<p id="40024">
A good news is, properties and events of most controls remain intact, and the syntax of control templates remains largely unchanged. Therefore, developers' knowledge of earlier versions of PRADO are still applicable in v3.0.
</p>
-<p>
+<p id="40025">
We summarize in the following the most significant changes in v3.0 to help developers upgrade their v2.x and v1.x PRADO applications more easily, if needed.
</p>
+</div>
<h2 id="502">Component Definition</h2>
-<p>
+<p id="40026" class="block-content">
Version 3.0 has completely discarded the need of component specification files. It relies more on conventions for defining component properties and events. In particular, a property is defined by the existence of a getter method and/or a setter method, while an event is defined by the existence of an <tt>on</tt>-method. Property and event names in v3.0 are both case-insensitive. As a consequence, developers are now required to take care of type conversions when a component property is being set. For example, the following code is used to define the setter method for the <tt>Enabled</tt> property of <tt>TControl</tt>, which is of <tt>boolean</tt> type,
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="block-content source" ID="code1">
public function setEnabled($value)
{
$value=TPropertyValue::ensureBoolean($value);
$this->setViewState('Enabled',$value,true);
}
</com:TTextHighlighter>
-<p>
+<p id="40027" class="block-content">
where <tt>TPropertyValue::ensureBoolean()</tt> is used to ensure that the input value be a boolean. This is because when the property is configured in template, a string value is passed to the setter. In previous versions, PRADO knows the property type based on the component specification files and does the type conversion for you.
</p>
<h2 id="503">Application Controller</h2>
-<p>
+<p id="40028" class="block-content">
Application controller now implements a modular architecture. Modules can be plugged in and configured in application specifications. Each module assumes a particular functionality, and they are coordinated together by the <a href="?page=Fundamentals.Applications">application lifecycle</a>. The concept of v2.x modules is replaced in v3.0 by <a href="?page=Configurations.PageConfig">page directories</a>. As a result, the format of v3.0 <a href="?page=Configurations.AppConfig">application specification</a> is also different from earlier versions.
</p>
<h2 id="504">Pages</h2>
-<p>
+<p id="40029" class="block-content">
Pages in v3.0 are organized in directories which may be compared to the module concept in v2.x. Pages are requested using the path to them. For example, a URL <tt>index.php?page=Controls.Samples.Sample1</tt> would be used to request for a page named <tt>Sample1</tt> stored under the <tt>[BasePath]/Controls/Samples</tt> directory, where <tt>[BasePath]</tt> refers to the root page path. The file name of a page template must be ended with <tt>.page</tt>, mainly to differentiate page templates from non-page control templates whose file names must be ended with <tt>.tpl</tt>.
</p>
<h2 id="505">Control Relationship</h2>
-<p>
+<p id="40030" class="block-content">
Version 3.0 redefines the relationships between controls. In particular, the parent-child relationship now refers to the enclosure relationship between controls' presentation. And a new naming-container relationship is introduced to help better manage control IDs. For more details, see the <a href="?page=Fundamentals.Controls">controls</a> section.
</p>
<h2 id="506">Template Syntax</h2>
-<p>
+<div id="template-syntax" class="block-content">
+<p id="40031">
The syntax of control templates in v3.0 remains similar to those in earlier versions, with many enhancements. A major change is about the databinding expression. In v3.0, this is done by the following,
</p>
-<com:TTextHighlighter Language="prado" CssClass="source">
+<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_40002">
<com:MyComponent PropertyName=<%# PHP expression %> .../>
</com:TTextHighlighter>
-<p>
+<p id="40032">
Expression and statement tags are also changed similarly. For more details, see the <a href="?page=Configurations.Templates1">template definition</a> section.
</p>
-
+</div>
<h2 id="507">Theme Syntax</h2>
-<p>
+<p id="40033" class="block-content">
Themes in v3.0 are defined like control templates with a few restrictions.
</p>
diff --git a/demos/quickstart/protected/pages/Services/SoapService.page b/demos/quickstart/protected/pages/Services/SoapService.page index 4a83c8ed..03ebc164 100644 --- a/demos/quickstart/protected/pages/Services/SoapService.page +++ b/demos/quickstart/protected/pages/Services/SoapService.page @@ -1,15 +1,15 @@ <com:TContent ID="body" >
-<h1>SOAP Service</h1>
+<h1 id="134038">SOAP Service</h1>
-<p>
+<p id="670450" class="block-content">
SOAP forms the foundation layer of the Web services stack. It provides a neat way for PHP applications to communicate with each other or with applications written in other languages. PRADO provides <tt>TSoapService</tt> that makes developing a SOAP server application an extremely easy task.
</p>
-<p>
+<p id="670451" class="block-content">
To use <tt>TSoapService</tt>, configure it in the application specification like following:
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_670133">
<services>
<service id="soap" class="System.Web.Services.TSoapService">
<soap id="stockquote" provider="path.to.StockQuote" />
@@ -19,10 +19,10 @@ To use <tt>TSoapService</tt>, configure it in the application specification like </service>
</services>
</com:TTextHighlighter>
-<p>
+<p id="670452" class="block-content">
The example specifies a SOAP service provider named <tt>stockquote</tt> which implements the <tt>getPrice</tt> SOAP method in the provider class <tt>StockQuote</tt>,
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_670134">
class StockQuote
{
/**
@@ -41,35 +41,37 @@ class StockQuote <tt>TSoapService</tt> is based on <a href="http://www.php.net/manual/en/ref.soap.php">PHP SOAP extension</a> and thus requires the extension to be installed.
</div>
-<p>
+<p id="670453" class="block-content">
With the above simple code, we already finish a simple SOAP service that allows other applications to query the price of a specific stock. For example, a typical SOAP client may be written as follows to query the stock price of IBM,
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_670135">
$client=new SoapClient('http://path/to/index.php?soap=stockquote.wsdl');
echo $client->getPrice('IBM');
</com:TTextHighlighter>
-<p>
+<p id="670454" class="block-content">
Notice the URL used to construct <tt>SoapClient</tt> (a class provided by PHP SOAP extension). This is the URL for the <a href="http://en.wikipedia.org/wiki/WSDL">WSDL</a> that describes the communication protocol for the SOAP service we just implemented. WSDL is often too complex to be manually written. Fortunately, <tt>TSoapService</tt> can generate this for us using a WSDL generator. In general, the URL for the automatically generated WSDL in PRADO has the following format:
</p>
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_670136">
http://path/to/index.php?SoapServiceID=SoapProviderID.wsdl
</com:TTextHighlighter>
-<p>
+<p id="670455" class="block-content">
In order for the WSDL generator to generate WSDL for a SOAP service, the provider class needs to follow certain syntax. In particular, for methods to be exposed as SOAP methods, a keyword <tt>@soapmethod</tt> must appear in the phpdoc comment of the method with the following lines specifying method parameters and return value:
</p>
-<ul>
+<ul id="u1" class="block-content">
<li>parameter: <tt>@param parameter-type $parameter-name description</tt></li>
<li>return value: <tt>@return value-type description</tt></li>
</ul>
-<p>
+<p id="670456" class="block-content">
Valid parameter and return types include: <tt>string</tt>, <tt>int</tt>, <tt>boolean</tt>, <tt>float</tt>, <tt>array</tt>, <tt>mixed</tt>, etc. You may also specify a class name as the type, which translates into a complex SOAP type. For example, for a complex type <tt>Contact</tt>
</p>
-<com:TTextHighlighter Language="php" CssClass="source">
-class Contact
-{
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_670137">
+/**
+ * Extends TComponent to provide property setter/getter methods
+ */
+class Contact {
/**
* @var string $name
* @soapproperty
@@ -80,26 +82,33 @@ class Contact * @var Address $address
* @soapproperty
*/
- public $address;
+ private $_address;
+
+ public function setAddress($value) {
+ $this->_address=$value;
+ }
+
+ public function getAddress() {
+ if($this->_address===null)
+ $this->_address=new Address;
+ return $this->_address;
+ }
}
-class Address
-{
+class Address{
/**
- * @var string city
+ * @var string $city
* @soapproperty
*/
public $city;
}
-class ContactManager
-{
+class ContactManager {
/**
* @return Contact[] an array of contacts
* @soapmethod
*/
- function getAllContacts()
- {
+ function getAllContacts() {
return array(new Contact);
}
@@ -107,16 +116,19 @@ class ContactManager * @return Contact one contact
* @soapmethod
*/
- function getContact($name)
- {
+ function getContact($name) {
return new Contact;
}
}
</com:TTextHighlighter>
-<p>For a complex soap object, the properties of the object are specified with
+<p id="670457" class="block-content">For a complex soap object, the properties of the object are specified with
<tt>@soapproperty</tt> keyword in the property phpdocs. Furthermore, the
propert's type name must be specified as <tt>@var type $name</tt> where <tt>type
-</tt> is any valid type in mentioned earlier.
+</tt> is any valid type in mentioned earlier and <tt>$name</tt> will defined
+a property <tt>name</tt> (notice that if your class is a TComponent, you can
+provide property setter/getter methods).
+</p>
+<p id="670458" class="block-content">
An array of complex objects can also be returned by adding a pair of
enclosing square brackets after the type name. For example, to return an
array of <tt>Contact</tt> type, we define <tt>@return Contact[] ...</tt>.
@@ -128,16 +140,16 @@ A very useful tool to test out your web services is the free tool The tool requires a MS .NET runtime to be installed.
</div>
-<p>
+<p id="670459" class="block-content">
<tt>TSoapService</tt> may be configured and customized in several ways. In the example above, the <tt><soap></tt> element actually specifies a SOAP service using the default <tt>TSoapServer</tt> implementation. Attributes in <tt><soap></tt> are passed to <tt>TSoapServer</tt> as its initial property values. For example, the <tt>provider</tt> attribute initializes the <tt>Provider</tt> property of <tt>TSoapServer</tt>. By setting <tt>SessionPersistent</tt> to be true in <tt><soap></tt> element, the provider instance will persist within the user session. You may develop your own SOAP server class and use it by specifying the <tt>class</tt> attribute of <tt><soap></tt>.
</p>
-<p>By default, PHP's soap server will create objects of the type <tt>StdClass</tt>
+<p id="670460" class="block-content">By default, PHP's soap server will create objects of the type <tt>StdClass</tt>
when objects are received from the client. The soap server can be configured to
automatically create objects of certain type objects are received as method
parameters. For example, if we have a Soap method that accepts
a <tt>Contact</tt> object as parameter.
-<com:TTextHighlighter Language="php" CssClass="source">
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_670138">
/**
* @param Contact $contact
* @return boolean true if saved, false otherwise
@@ -152,7 +164,7 @@ The do this, we need to set the <tt>ClassMaps</tt> property of the <tt>TSoapServer</tt> in the <tt><soap></tt> tags as
a comma separated string of class names that we wish to be automatically
converted.
-<com:TTextHighlighter Language="xml" CssClass="source">
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_670139">
<soap id="contact-manager" provider="path.to.ContactManager"
ClassMaps="Contact, Address"/>
</com:TTextHighlighter>
diff --git a/demos/quickstart/protected/pages/Tutorial/AjaxChat.page b/demos/quickstart/protected/pages/Tutorial/AjaxChat.page index 2d49c9f6..ec6fc149 100644 --- a/demos/quickstart/protected/pages/Tutorial/AjaxChat.page +++ b/demos/quickstart/protected/pages/Tutorial/AjaxChat.page @@ -1,67 +1,67 @@ <com:TContent ID="body"> - <h1>Building an AJAX Chat Application</h1> - <p>This tutorial introduces the Prado web application framework's + <h1 id="18008">Building an AJAX Chat Application</h1> + <p id="90081" class="block-content">This tutorial introduces the Prado web application framework's <a href="?page=Database.ActiveRecord">ActiveRecord</a> - and <a href="?page=ActiveControls.Home">Active Controls</a> to build a Chat - web application. It is assumed that you + and <a href="?page=ActiveControls.Home">Active Controls</a> to build a Chat + web application. It is assumed that you are familiar with PHP and you have access to a web server that is able to serve PHP5 scripts. This basic chat application will utilize the following ideas/components in Prado. - <ul> + </p> + <ul id="u1" class="block-content"> <li>Building a custom User Manager class.</li> <li>Authenticating and adding a new user to the database.</li> <li>Using ActiveRecord to interact with the database.</li> <li>Using Active Controls and callbacks to implement the user interface.</li> <li>Separating application logic and application flow.</li> </ul> - </p> - <p>In this tutorial you will build an AJAX Chat web application that allows - multiple users to communicate through their web browser. + <p id="90082" class="block-content">In this tutorial you will build an AJAX Chat web application that allows + multiple users to communicate through their web browser. The application consists of two pages: a login page that asks the user to enter their nickname and the main application chat page. - You can try the application <a href="../chat/index.php">locally</a> or at + You can try the application <a href="../chat/index.php">locally</a> or at <a href="http://www.pradosoft.com/demos/chat/">Pradosoft.com</a>. - The main application chat page is shown bellow. + The main application chat page is shown bellow. <img src=<%~ chat1.png %> class="figure" /> </p> - <h1>Download, Install and Create a New Application</h1> - <p>The download and installation steps are similar to those in + <h1 id="18009">Download, Install and Create a New Application</h1> + <p id="90083" class="block-content">The download and installation steps are similar to those in the <a href="?page=Tutorial.CurrencyConverter#download">Currency converter tutorial</a>. To create the application, we run from the command line the following. - See the <a href="?page=GettingStarted.CommandLine">Command Line Tool</a> + See the <a href="?page=GettingStarted.CommandLine">Command Line Tool</a> for more details. -<com:TTextHighlighter Language="text" CssClass="source"> +<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_90027"> php prado/framework/prado-cli.php -c chat -</com:TTextHighlighter> +</com:TTextHighlighter> </p> - <p>The above command creates the necessary directory structure and minimal + <p id="90084" class="block-content">The above command creates the necessary directory structure and minimal files (including "index.php" and "Home.page") to run a Prado web application. Now you can point your browser's URL to the web server to serve up the <tt>index.php</tt> script in the <tt>chat</tt> directory. - You should see the message "Welcome to Prado!" + You should see the message "Welcome to Prado!" </p> - <h1>Authentication and Authorization</h1> - <p>The first task for this application is to ensure that each user - of the chat application is assigned with a unique (chosen by the user) + <h1 id="18010">Authentication and Authorization</h1> + <p id="90085" class="block-content">The first task for this application is to ensure that each user + of the chat application is assigned with a unique (chosen by the user) username. To achieve this, we can secure the main chat application page to deny access to anonymous users. First, let us create the <tt>Login</tt> page with the following code. We save the <tt>Login.php</tt> and <tt>Login.page</tt> in the <tt>chat/protected/pages/</tt> directory (there should be a <tt>Home.page</tt> file created by the command line tool). </p> -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90028"> <?php class Login extends TPage { } ?> </com:TTextHighlighter> -<com:TTextHighlighter Language="prado" CssClass="source"> -<!doctype html public "-//W3C//DTD XHTML 1.0 Strict//EN" +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_90029"> +<!doctype html public "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> @@ -87,7 +87,7 @@ class Login extends TPage </body> </html> </com:TTextHighlighter> - <p>The login page contains + <p id="90086" class="block-content">The login page contains a <com:DocLink ClassPath="System.Web.UI.TForm" Text="TForm" />, a <com:DocLink ClassPath="System.Web.UI.WebControls.TTextBox" Text="TTextBox" />, a <com:DocLink ClassPath="System.Web.UI.WebControls.TRequiredFieldValidator" Text="TRequiredFieldValidator" /> @@ -99,12 +99,12 @@ class Login extends TPage due to the <com:DocLink ClassPath="System.Web.UI.WebControls.TRequiredFieldValidator" Text="TRequiredFieldValidator" /> requiring the user to enter some text in the textbox before proceeding. </p> -<h2>Securing the <tt>Home</tt> page</h2> -<p>Now we wish that if the user is trying to access the main application +<h2 id="18019">Securing the <tt>Home</tt> page</h2> +<p id="90087" class="block-content">Now we wish that if the user is trying to access the main application page, <tt>Home.page</tt>, before they have logged in, the user is presented with the <tt>Login.page</tt> first. We add a <tt>chat/protected/application.xml</tt> configuration file to import some classes that we shall use later. -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_90030"> <?xml version="1.0" encoding="utf-8"?> <application id="Chat" Mode="Debug"> <paths> @@ -117,7 +117,7 @@ file to import some classes that we shall use later. </com:TTextHighlighter> Next, we add a <tt>chat/protected/pages/config.xml</tt> configuration file to secure the <tt>pages</tt> directory. -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_90031"> <?xml version="1.0" encoding="utf-8"?> <configuration> <modules> @@ -131,41 +131,41 @@ secure the <tt>pages</tt> directory. </authorization> </configuration> </com:TTextHighlighter> -We setup the authentication using the default classes as explained in the +We setup the authentication using the default classes as explained in the <a href="?page=Advanced.Auth">authentication/authorization quickstart</a>. -In the authorization definition, we allow anonymous users to access the +In the authorization definition, we allow anonymous users to access the <tt>Login</tt> page (anonymous users is specified by the <tt>?</tt> question mark). -We allow any users with role equal to "normal" (to be defined later) +We allow any users with role equal to "normal" (to be defined later) to access all the pages, that is, the <tt>Login</tt> and <tt>Home</tt> pages. Lastly, we deny all users without any roles to access any page. The authorization rules are executed on first match basis. </p> -<p>If you now try to access the <tt>Home</tt> page by pointing your browser +<p id="90088" class="block-content">If you now try to access the <tt>Home</tt> page by pointing your browser to the <tt>index.php</tt> you will be redirected to the <tt>Login</tt> page. </p> -<h1>Active Record for <tt>chat_users</tt> table</h1> -<p>The <com:DocLink ClassPath="System.Secutity.TUserManager" Text="TUserManager" /> +<h1 id="18011">Active Record for <tt>chat_users</tt> table</h1> +<p id="90089" class="block-content">The <com:DocLink ClassPath="System.Secutity.TUserManager" Text="TUserManager" /> class only provides a read-only list of users. We need to be able to add or login new users dynamically. So we need to create our own user manager class. -First, we shall setup a database with a <tt>chat_users</tt> table and create an ActiveRecord +First, we shall setup a database with a <tt>chat_users</tt> table and create an ActiveRecord that can work with the <tt>chat_users</tt> table with ease. For the demo, we use <tt>sqlite</tt> as our database for ease of distributing the demo. The demo can be extended to use other databases such as MySQL or Postgres SQL easily. We define the <tt>chat_users</tt> table as follows. -<com:TTextHighlighter Language="text" CssClass="source"> -CREATE TABLE chat_users -( - username VARCHAR(20) NOT NULL PRIMARY KEY, - last_activity INTEGER NOT NULL DEFAULT "0" +<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_90032"> +CREATE TABLE chat_users +( + username VARCHAR(20) NOT NULL PRIMARY KEY, + last_activity INTEGER NOT NULL DEFAULT "0" ); </com:TTextHighlighter> Next we define the corresponding <tt>ChatUserRecord</tt> class and save it as <tt>chat/protected/App_Code/ChatUserRecord.php</tt> (you need to create the <tt>App_Code</tt> directory as well). We also save the sqlite database file as <tt>App_Code/chat.db</tt>. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90033"> class ChatUserRecord extends TActiveRecord { public $username; @@ -181,9 +181,9 @@ class ChatUserRecord extends TActiveRecord </com:TTextHighlighter> Before using the <tt>ChatUserRecord</tt> class we to configure a default database connection for ActiveRecord to function. In the <tt>chat/protected/application.xml</tt> -we import classes from the <tt>App_Code</tt> directory and add an +we import classes from the <tt>App_Code</tt> directory and add an <a href="?page=Database.ActiveRecord">ActiveRecord configuration module</a>. -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_90034"> <?xml version="1.0" encoding="utf-8"?> <application id="Chat" Mode="Debug"> <paths> @@ -201,14 +201,14 @@ we import classes from the <tt>App_Code</tt> directory and add an </com:TTextHighlighter> </p> -<h2>Custom User Manager class</h2> -<p>To implement a custom user manager module class we just need +<h2 id="18020">Custom User Manager class</h2> +<p id="90090" class="block-content">To implement a custom user manager module class we just need to extends the <tt>TModule</tt> class and implement the <tt>IUserManager</tt> interface. The <tt>getGuestName()</tt>, <tt>getUser()</tt> and <tt>validateUser()</tt> methods are required by the <tt>IUserManager</tt> interface. We save the custom user manager class as <tt>App_Code/ChatUserManager.php</tt>. -</p> -<com:TTextHighlighter Language="php" CssClass="source"> +</p> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90035"> class ChatUserManager extends TModule implements IUserManager { public function getGuestName() @@ -219,7 +219,7 @@ class ChatUserManager extends TModule implements IUserManager public function getUser($username=null) { $user=new TUser($this); - $user->setIsGuest(true); + $user->setIsGuest(true); if($username !== null && $this->usernameExists($username)) { $user->setIsGuest(false); @@ -228,7 +228,7 @@ class ChatUserManager extends TModule implements IUserManager } return $user; } - + public function addNewUser($username) { $user = new ChatUserRecord(); @@ -249,7 +249,7 @@ class ChatUserManager extends TModule implements IUserManager } } </com:TTextHighlighter> -<p> +<p id="90091" class="block-content"> The <tt>getGuestName()</tt> method simply returns the name for a guest user and is not used in our application. The <tt>getUser()</tt> method returns a <tt>TUser</tt> object if the username @@ -257,25 +257,25 @@ exists in the database, the <tt>TUser</tt> object is set with role of "normal" that corresponds to the <tt><authorization></tt> rules defined in our <tt>config.xml</tt> file. </p> -<p>The <tt>addNewUser()</tt> and <tt>usernameExists()</tt> -method uses the ActiveRecord corresponding to the <tt>chat_users</tt> table to +<p id="90092" class="block-content">The <tt>addNewUser()</tt> and <tt>usernameExists()</tt> +method uses the ActiveRecord corresponding to the <tt>chat_users</tt> table to add a new user and to check if a username already exists, respectively. </p> -<p>The next thing to do is change the <tt>config.xml</tt> configuration to use +<p id="90093" class="block-content">The next thing to do is change the <tt>config.xml</tt> configuration to use our new custom user manager class. We simply change the <tt><module></tt> configuration with <tt>id="users"</tt>.</p> -<com:TTextHighlighter Language="xml" CssClass="source"> +<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_90036"> <module id="users" class="ChatUserManager" /> </com:TTextHighlighter> -<h1>Authentication</h1> -<p>To perform authentication, we just want the user to enter a unique -username. We add a +<h1 id="18012">Authentication</h1> +<p id="90094" class="block-content">To perform authentication, we just want the user to enter a unique +username. We add a <com:DocLink ClassPath="System.Web.UI.WebControls.TCustomValidator" Text="TCustomValidator" /> for validate the uniqueness of the username and add an <tt>OnClick</tt> event handler for the login button.</p> -<com:TTextHighlighter Language="prado" CssClass="source"> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_90037"> <com:TCustomValidator ControlToValidate="username" Display="Dynamic" @@ -287,7 +287,7 @@ for the login button.</p> <com:TButton Text="Login" OnClick="createNewUser" /> </com:TTextHighlighter> In the <tt>Login.php</tt> file, we add the following 2 methods. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90038"> function checkUsername($sender, $param) { $manager = $this->Application->Modules['users']; @@ -301,7 +301,7 @@ function createNewUser($sender, $param) { $manager = $this->Application->Modules['users']; $manager->addNewUser($this->username->Text); - + //do manual login $user = $manager->getUser($this->username->Text); $auth = $this->Application->Modules['auth']; @@ -314,15 +314,15 @@ function createNewUser($sender, $param) } </com:TTextHighlighter> The <tt>checkUserName()</tt> method uses the <tt>ChatUserManager</tt> class -(recall that in the <tt>config.xml</tt> configuration we set the +(recall that in the <tt>config.xml</tt> configuration we set the ID of the custom user manager class as "users") to validate the username is not taken. </p> -<p> -In the <tt>createNewUser</tt> method, when the validation passes (that is, +<p id="90095" class="block-content"> +In the <tt>createNewUser</tt> method, when the validation passes (that is, when the user name is not taken) we add a new user. Afterward we perform -a manual login process: -<ul> +a manual login process:</p> +<ul id="u2" class="block-content"> <li>First we obtain a <tt>TUser</tt> instance from our custom user manager class using the <tt>$manager->getUser(...)</tt> method.</li> <li>Using the <tt>TAuthManager</tt> we set/update the user object in the @@ -330,20 +330,22 @@ our custom user manager class using the <tt>$manager->getUser(...)</tt> method.< <li>Then we set/update the <tt>Application</tt>'s user instance with our new user object.</li> </ul> +</p> +<p id="finally" class="block-content"> Finally, we redirect the client to the default <tt>Home</tt> page. </p> -<h2>Default Values for ActiveRecord</h2> -<p>If you try to perform a login now, you will receive an error message like -"<i>Property '<tt>ChatUserRecord::$last_activity</tt>' must not be null as defined +<h2 id="18021">Default Values for ActiveRecord</h2> +<p id="90096" class="block-content">If you try to perform a login now, you will receive an error message like +"<i>Property '<tt>ChatUserRecord::$last_activity</tt>' must not be null as defined by column '<tt>last_activity</tt>' in table '<tt>chat_users</tt>'.</i>". This means that the <tt>$last_activity</tt> property value was null when we tried to insert a new record. We need to either define a default value in the corresponding column in the table and allow null values or set the default -value in the <tt>ChatUserRecord</tt> class. We shall demonstrate the later by +value in the <tt>ChatUserRecord</tt> class. We shall demonstrate the later by altering the <tt>ChatUserRecord</tt> with the addition of a set getter/setter methods for the <tt>last_activity</tt> property. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90039"> private $_last_activity; public function getLast_Activity() @@ -362,13 +364,13 @@ Notice that we renamed <tt>$last_activity</tt> to <tt>$_last_activity</tt> (note the underscore after the dollar sign). </p> -<h1>Main Chat Application</h1> -<p>Now we are ready to build the main chat application. We use a simple +<h1 id="18013">Main Chat Application</h1> +<p id="90097" class="block-content">Now we are ready to build the main chat application. We use a simple layout that consist of one panel holding the chat messages, one panel to hold the users list, a textarea for the user to enter the text message and a button to send the message. -<com:TTextHighlighter Language="prado" CssClass="source"> -<!doctype html public "-//W3C//DTD XHTML 1.0 Strict//EN" +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_90040"> +<!doctype html public "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> @@ -378,7 +380,7 @@ and a button to send the message. { width: 500px; height: 300px; - float: left; + float: left; border: 1px solid ButtonFace; overflow: auto; } @@ -400,7 +402,7 @@ and a button to send the message. .message-input textarea { margin-top: 3px; - padding: 0.4em 0.2em; + padding: 0.4em 0.2em; width: 493px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 0.85em; @@ -414,7 +416,7 @@ and a button to send the message. </head> <body> <com:TForm> -<h1>Prado Chat Demo</h1> +<h1 id="18014">Prado Chat Demo</h1> <div id="messages" class="messages"> <com:TPlaceHolder ID="messageList" /> </div> @@ -422,9 +424,9 @@ and a button to send the message. <com:TPlaceHolder ID="userList" /> </div> <div class="message-input"> - <com:TActiveTextBox ID="userinput" + <com:TActiveTextBox ID="userinput" Columns="40" Rows="2" TextMode="MultiLine" /> - <com:TActiveButton ID="sendButton" CssClass="send-button" + <com:TActiveButton ID="sendButton" CssClass="send-button" Text="Send" /> </div> </com:TForm> @@ -436,23 +438,23 @@ We added two Active Control components: a <com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveTextBox" Text="TActiveTextBox" /> and a <com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveButton" Text="TActiveButton" />. -We also added a +We also added a <com:DocLink ClassPath="System.Web.UI.WebControls.TJavascriptLogger" Text="TJavascriptLogger" /> that will be very useful for understanding how the Active Controls work. </p> -<h2>Exploring the Active Controls</h2> -<p>We should have some fun before we proceeding with setting up the chat buffering. We want +<h2 id="18022">Exploring the Active Controls</h2> +<p id="90098" class="block-content">We should have some fun before we proceeding with setting up the chat buffering. We want to see how we can update the current page when we receive a message. First, we add an <tt>OnClick</tt> event handler for the <tt>Send</tt> button. -<com:TTextHighlighter Language="prado" CssClass="source"> -<com:TActiveButton ID="sendButton" CssClass="send-button" +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_90041"> +<com:TActiveButton ID="sendButton" CssClass="send-button" Text="Send" OnClick="processMessage"/> </com:TTextHighlighter> And the corresponding event handler method in the <tt>Home.php</tt> class (we need to create this new file too). -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90042"> class Home extends TPage { function processMessage($sender, $param) @@ -465,12 +467,12 @@ If you now type something in the main application textbox and click the send but you should see whatever you have typed echoed in the <tt>TJavascriptLogger</tt> console. </p> -<p>To append or add some content to the message list panel, we need to use -some methods in the +<p id="90099" class="block-content">To append or add some content to the message list panel, we need to use +some methods in the <com:DocLink ClassPath="System.Web.UI.ActiveControls.TCallbackClientScript" Text="TCallbackClientScript" /> class which is available through the <tt>CallbackClient</tt> property of the current <tt>TPage</tt> object. For example, we do can do -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90043"> function processMessage($sender, $param) { $this->CallbackClient->appendContent("messages", $this->userinput->Text); @@ -480,24 +482,24 @@ This is one way to update some part of the existing page during a callback (AJAX and will be the primary way we will use to implement the chat application. </p> -<h1>Active Record for <tt>chat_buffer</tt> table</h1> -<p>To send a message to all the connected users we need to buffer or store +<h1 id="18015">Active Record for <tt>chat_buffer</tt> table</h1> +<p id="90100" class="block-content">To send a message to all the connected users we need to buffer or store the message for each user. We can use the database to buffer the messages. The <tt>chat_buffer</tt> table is defined as follows. -<com:TTextHighlighter Language="text" CssClass="source"> -CREATE TABLE chat_buffer -( - id INTEGER PRIMARY KEY, - for_user VARCHAR(20) NOT NULL, - from_user VARCHAR(20) NOT NULL, - message TEXT NOT NULL, - created_on INTEGER NOT NULL DEFAULT "0" +<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_90044"> +CREATE TABLE chat_buffer +( + id INTEGER PRIMARY KEY, + for_user VARCHAR(20) NOT NULL, + from_user VARCHAR(20) NOT NULL, + message TEXT NOT NULL, + created_on INTEGER NOT NULL DEFAULT "0" ); </com:TTextHighlighter> The corresponding <tt>ChatBufferRecord</tt> class is saved as <tt>App_Code/ChatBufferRecord.php</tt>. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90045"> class ChatBufferRecord extends TActiveRecord { public $id; @@ -528,12 +530,12 @@ class ChatBufferRecord extends TActiveRecord </com:TTextHighlighter> </p> -<h1>Chat Application Logic</h1> -<p>We finally arrive at the guts of the chat application logic. First, we +<h1 id="18016">Chat Application Logic</h1> +<p id="90101" class="block-content">We finally arrive at the guts of the chat application logic. First, we need to save a received message into the chat buffer for <b>all</b> the current users. We add this logic in the <tt>ChatBufferRecord</tt> class. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90046"> public function saveMessage() { foreach(ChatUserRecord::finder()->findAll() as $user) @@ -557,19 +559,20 @@ we update the message sender's last activity timestamp. The above piece of code demonstrates the simplicity and succinctness of using ActiveRecords for simple database designs. </p> -<p>The next piece of the logic is to retrieve the users' messages from the buffer. +<p id="90102" class="block-content">The next piece of the logic is to retrieve the users' messages from the buffer. We simply load all the messages for a particular username and format that message appropriately (remember to escape the output to prevent Cross-Site Scripting attacks). After we load the messages, we delete those loaded messages and any older -messages that may have been left in the buffer. +messages that may have been left in the buffer. </p> -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90047"> public function getUserMessages($user) { $content = ''; foreach($this->findAll('for_user = ?', $user) as $message) $content .= $this->formatMessage($message); - $this->deleteAll('for_user = ? OR created_on < ?', $user, time() - 300); //5 min inactivity + $this->deleteAll('for_user = ? OR created_on < ?',
+ $user, time() - 300); //5 min inactivity return $content; } @@ -577,14 +580,15 @@ protected function formatMessage($message) { $user = htmlspecialchars($message->from_user); $content = htmlspecialchars($message->message); - return "<div class=\"message\"><strong>{$user}:</strong> <span>{$content}</span></div>"; + return "<div class=\"message\"><strong>{$user}:</strong>"
+ ." <span>{$content}</span></div>"; } </com:TTextHighlighter> To retrieve a list of current users (formatted), we add this logic to the <tt>ChatUserRecord</tt> class. We delete any users that may have been inactive for awhile. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90048"> public function getUserList() { $this->deleteAll('last_activity < ?', time()-300); //5 min inactivity @@ -604,11 +608,11 @@ a TRepeater in the template or a custom component). </div> </p> -<h1>Putting It Together</h1> -<p>Now comes to put the application flow together. In the <tt>Home.php</tt> we update +<h1 id="18017">Putting It Together</h1> +<p id="90103" class="block-content">Now comes to put the application flow together. In the <tt>Home.php</tt> we update the <tt>Send</tt> buttons <tt>OnClick</tt> event handler to use the application logic we just implemented. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90049"> function processMessage($sender, $param) { if(strlen($this->userinput->Text) > 0) @@ -617,7 +621,7 @@ function processMessage($sender, $param) $record->message = $this->userinput->Text; $record->from_user = $this->Application->User->Name; $record->saveMessage(); - + $this->userinput->Text = ''; $messages = $record->getUserMessages($this->Application->User->Name); $this->CallbackClient->appendContent("messages", $messages); @@ -630,17 +634,17 @@ for the current user and update the client side message list using a callback response (AJAX style). </p> -<p>At this point the application is actually already functional, just not very +<p id="90104" class="block-content">At this point the application is actually already functional, just not very user friendly. If you open two different browsers, you should be able to communicate between the two users whenever the <tt>Send</tt> button is clicked. </p> -<p>The next part is perhaps the more tricker and fiddly than the other tasks. We +<p id="90105" class="block-content">The next part is perhaps the more tricker and fiddly than the other tasks. We need to improve the user experience. First, we want a list of current users as well. So we add the following method to <tt>Home.php</tt>, we can call this method when ever some callback event is raised, e.g. when the <tt>Send</tt> button is clicked. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90050"> protected function refreshUserList() { $lastUpdate = $this->getViewState('userList',''); @@ -654,13 +658,13 @@ protected function refreshUserList() </com:TTextHighlighter> </p> -<p>Actually, we want to periodically update the messages and user list as new +<p id="90106" class="block-content">Actually, we want to periodically update the messages and user list as new users join in and new message may arrive from other users. So we need to refresh the message list as well.</p> -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90051"> function processMessage($sender, $param) { - ... + ... $this->refreshUserList(); $this->refreshMessageList(); ... @@ -681,14 +685,14 @@ protected function refreshMessageList() } </com:TTextHighlighter> The anchor using <tt>time()</tt> as ID for a focus point is so that when the -message list on the client side gets very long, the focus method will +message list on the client side gets very long, the focus method will scroll the message list to the latest message (well, it works in most browsers). </p> -<p>Next, we need to redirect the user back to the login page if the user has +<p id="90107" class="block-content">Next, we need to redirect the user back to the login page if the user has been inactive for some time, say about 5 mins, we can add this check to any stage of the page life-cycle. Lets add it to the <tt>onLoad()</tt> stage. -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90052"> public function onLoad($param) { $username = $this->Application->User->Name; @@ -704,18 +708,18 @@ public function onLoad($param) </com:TTextHighlighter> </p> -<h1>Improving User Experience</h1> -<p>The last few details are to periodically check for new messages and +<h1 id="18018">Improving User Experience</h1> +<p id="90108" class="block-content">The last few details are to periodically check for new messages and refresh the user list. We can accomplish this by polling the server using a <com:DocLink ClassPath="System.Web.UI.ActiveControls.TTimeTriggeredCallback" Text="TTimeTriggeredCallback" /> control. We add a <tt>TTimeTriggeredCallback</tt> to the <tt>Home.page</tt> and call the <tt>refresh</tt> handler method defined in <tt>Home.php</tt>. We set the polling interval to 2 seconds. -<com:TTextHighlighter Language="prado" CssClass="source"> -<com:TTimeTriggeredCallback OnCallback="refresh" +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_90053"> +<com:TTimeTriggeredCallback OnCallback="refresh" Interval="2" StartTimerOnLoad="true" /> </com:TTextHighlighter> -<com:TTextHighlighter Language="php" CssClass="source"> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code_90054"> function refresh($sender, $param) { $this->refreshUserList(); @@ -724,12 +728,12 @@ function refresh($sender, $param) </com:TTextHighlighter> </p> -<p>The final piece requires us to use some javascript. We want that when the +<p id="90109" class="block-content">The final piece requires us to use some javascript. We want that when the user type some text in the textarea and press the <tt>Enter</tt> key, we want it to send the message without clicking on the <tt>Send</tt> button. We add to the <tt>Home.page</tt> some javascript. -<com:TTextHighlighter Language="javascript" CssClass="source"> +<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_90055"> <com:TClientScript> Event.observe($("<%= $this->userinput->ClientID %>"), "keypress", function(ev) { @@ -742,11 +746,11 @@ Event.observe($("<%= $this->userinput->ClientID %>"), "keypress", function }); </com:TClientScript> </com:TTextHighlighter> -Details regarding the javascript can be explored in the +Details regarding the javascript can be explored in the <a href="?page=Advanced.Scripts">Introduction to Javascript</a> section of the quickstart. </p> -<p>This completes the tutorial on making a basic chat web application using +<p id="90110" class="block-content">This completes the tutorial on making a basic chat web application using the Prado framework. Hope you have enjoyed it. </p> diff --git a/demos/quickstart/protected/pages/Tutorial/CurrencyConverter.page b/demos/quickstart/protected/pages/Tutorial/CurrencyConverter.page index c11c1b94..43666560 100644 --- a/demos/quickstart/protected/pages/Tutorial/CurrencyConverter.page +++ b/demos/quickstart/protected/pages/Tutorial/CurrencyConverter.page @@ -1,59 +1,60 @@ <com:TContent ID="body"> - <h1>Building a Simple Currency Converter</h1> - <p>This tutorial introduces the Prado web application framework and teaches + <h1 id="16001">Building a Simple Currency Converter</h1> + <p id="80053" class="block-content">This tutorial introduces the Prado web application framework and teaches you how to build a simple web application in a few simple steps. This tutorial assumes that you are familiar with PHP and you have access to a web server that is able to serve PHP5 scripts. - </p> - - <p>In this tutorial you will build a simple web application that converts - a dollar amount to an other currency, given the rate of that currency + </p> + + <p id="80054" class="block-content">In this tutorial you will build a simple web application that converts + a dollar amount to an other currency, given the rate of that currency relative to the dollar. The completed application is shown bellow. <img src=<%~ example2.png %> class="figure" /> - You can try the application <a href="../currency-converter/index.php">locally</a> or at + You can try the application <a href="../currency-converter/index.php">locally</a> or at <a href="http://www.pradosoft.com/demos/currency-converter/">Pradosoft.com</a>. Notice that the application still functions exactly the same if javascript is not available on the user's browser. </p> - + <h1 id="download">Downloading and Installing Prado</h1> - <p>To install Prado, simply download the latest version of Prado from + <p id="80055" class="block-content">To install Prado, simply download the latest version of Prado from <a href="http://www.pradosoft.com/">http://www.pradosoft.com</a> - and unzip the file to a directory <b>not</b> accessible by your web server + and unzip the file to a directory <b>not</b> accessible by your web server (you may unzip it to a directory accessible by the web server if you wish - to see the demos and test). For further detailed installation, see the + to see the demos and test). For further detailed installation, see the <a href="?page=GettingStarted.Installation">Quickstart Installation</a> guide. </p> - - <h1>Creating a new Prado web Application</h1> - <p>The quickest and simplest way to create a new Prado web application is + + <h1 id="16002">Creating a new Prado web Application</h1> + <p id="80056" class="block-content">The quickest and simplest way to create a new Prado web application is to use the command tool <tt>prado-cli.php</tt> found in the <tt>framework</tt> - directory of the Prado distribution. We create a new application by running + directory of the Prado distribution. We create a new application by running the following command in your - command prompt or console. The command creates a new directory named - <tt>currency-converter</tt> in your current working directory. + command prompt or console. The command creates a new directory named + <tt>currency-converter</tt> in your current working directory. You may need to change to the appropriate directory first. -<com:TTextHighlighter Language="text" CssClass="source"> + See the <a href="?page=GettingStarted.CommandLine">Command Line Tool</a>
+ for more details.
+ </p>
+<com:TTextHighlighter Language="text" CssClass="source block-content" id="code111"> php prado/framework/prado-cli.php -c currency-converter -</com:TTextHighlighter> - See the <a href="?page=GettingStarted.CommandLine">Command Line Tool</a> - for more details. - </p> - - <p>The above command creates the necessary directory structure and minimal +</com:TTextHighlighter> + + <p id="80057" class="block-content">The above command creates the necessary directory structure and minimal files (including "index.php" and "Home.page") to run a Prado web application. Now you can point your browser's url to the web server to serve up the <tt>index.php</tt> script in the <tt>currency-converter</tt> directory. - You should see the message "Welcome to Prado!" + You should see the message "Welcome to Prado!" </p> - - <h1>Creating the Currency Converter User Interface</h1> - <p>We start by editing the <tt>Home.page</tt> file found in the + + <h1 id="16003">Creating the Currency Converter User Interface</h1> + <p id="80058" class="block-content">We start by editing the <tt>Home.page</tt> file found in the <tt>currency-converter/protected/pages/</tt> directory. Files ending - with ".page" are page templates that contains HTML and Prado controls. - We simply add two textboxes, three labels and one button as follows. -<com:TTextHighlighter Language="prado" CssClass="source"> + with ".page" are page templates that contains HTML and Prado controls. + We simply add two textboxes, three labels and one button as follows.
+ </p> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="form1"> <com:TForm> <fieldset> <legend>Currency Converter</legend> @@ -74,87 +75,93 @@ php prado/framework/prado-cli.php -c currency-converter </div> </fieldset> </com:TForm> -</com:TTextHighlighter> +</com:TTextHighlighter>
+ <p id="refresh" class="block-content"> If you refresh the page, you should see something similar to the following figure. It may not look very pretty or orderly, but we shall change that later using CSS. <img src=<%~ example1.png %> class="figure" /> </p> - - <p> - The first component we add is a + + <p id="80059" class="block-content"> + The first component we add is a <com:DocLink ClassPath="System.Web.UI.TForm" Text="TForm" /> that basically corresponds to the HTML <tt><form></tt> element. - In Prado, only <b>one</b> <tt>TForm</tt> element is allowed per page. - </p> - - <p>The next two pair of component we add is the + In Prado, only <b>one</b> <tt>TForm</tt> element is allowed per page. + </p> + + <p id="80060" class="block-content">The next two pair of component we add is the <com:DocLink ClassPath="System.Web.UI.WebControls.TLabel" Text="TLabel" /> - and + and <com:DocLink ClassPath="System.Web.UI.WebControls.TTextBox" Text="TTextBox" /> that basically defines a label and a textbox for the user of the application - to enter the currency exchange rate. + to enter the currency exchange rate. The <tt>ForControl</tt> property value determines which component that the label is for. This allows the user of the application to click on the label to focus on the field (a good thing). You could have used a plain HTML <tt><label></tt> element to do the same thing, but - you would have to find the correct <tt>ID</tt> of the textbox (or - <tt><input></tt> in HTML) as Prado components may/will render the + you would have to find the correct <tt>ID</tt> of the textbox (or + <tt><input></tt> in HTML) as Prado components may/will render the <tt>ID</tt> value differently in the HTML output. </p> - - <p>The next pair of components are similar and defines the textbox + + <p id="80061" class="block-content">The next pair of components are similar and defines the textbox to hold the dollar value to be converted. The <tt>TLabel</tt> with <tt>ID</tt> value "total" defines a simple label. Notice that the <tt>ForControl</tt> property is absent. This means that this label is simply a simple label which we are going to use to display the converted total amount. </p> - - <p>The final component is a + + <p id="80062" class="block-content">The final component is a <com:DocLink ClassPath="System.Web.UI.WebControls.TButton" Text="TButton" /> that the user will click to calculate the results. The <tt>Text</tt> property sets the button label. </p> - - <h1>Implementing Currency Conversion</h1> - - <p>If you tried clicking on the "Convert" button then the page will refresh + + <h1 id="16004">Implementing Currency Conversion</h1> + + <p id="80063" class="block-content">If you tried clicking on the "Convert" button then the page will refresh and does not do anything else. For the button to do some work, we need to add a "Home.php" to where "Home.page" is. The <tt>Home</tt> class should extends the <com:DocLink ClassPath="System.Web.UI.TPage" Text="TPage" />, the default base - class for all Prado pages. -<com:TTextHighlighter Language="php" CssClass="source"> + class for all Prado pages.
+ </p> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code3"> <?php class Home extends TPage { - + } ?> -</com:TTextHighlighter> +</com:TTextHighlighter>
+ <p id="1111" class="block-content"> Prado uses PHP's <tt>__autoload</tt> method to load classes. The convention - is to use the class name with ".php" extension as filename. + is to use the class name with ".php" extension as filename. </p> - - <p>So far there is nothing interesting about Prado, we just declared some + + <p id="80064" class="block-content">So far there is nothing interesting about Prado, we just declared some "web components" in some template file named Home.page and created a "Home.php" file with a <tt>Home</tt> class. The more interesting bits are in Prado's event-driven architecture as we shall see next. </p> - - <p>We want that when the user click on the "Convert" button, we take the + + <p id="80065" class="block-content">We want that when the user click on the "Convert" button, we take the values in the textbox, do some calculation and present the user with the converted total. To handle the user clicking of the "Convert" button we simply add an <tt>OnClick</tt> property to the "Convert" button in - the "Home.page" template and add a corresponding event handler method - in the "Home.php". -<com:TTextHighlighter Language="prado" CssClass="source"> + the "Home.page" template and add a corresponding event handler method + in the "Home.php".
+ </p> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code4"> <com:TButton Text="Convert" OnClick="convert_clicked" /> -</com:TTextHighlighter> +</com:TTextHighlighter> + <p id="222" class="block-content">
The value of the <tt>OnClick</tt>, "<tt>convert_clicked</tt>", will be the method - name in the "Home.php" that will called when the user clicks on the - "Convert" button. -<com:TTextHighlighter Language="php" CssClass="source"> + name in the "Home.php" that will called when the user clicks on the + "Convert" button.
+ </p> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code5"> class Home extends TPage { public function convert_clicked($sender, $param) @@ -164,67 +171,78 @@ class Home extends TPage $this->total->Text = $rate * $dollars; } } -</com:TTextHighlighter> +</com:TTextHighlighter>
+<div id="3332" class="block-content">
+ <p id="333"> If you run the application in your web browser, enter some values and click the "Convert" button then you should see that calculated value displayed next to the "Amount in Other Currency" label. </p> - - <p>In the "<tt>convert_clicked</tt>" method the first parameter, <tt>$sender</tt>, - corresponds to the object that raised the event, in this case, + + <p id="80066">In the "<tt>convert_clicked</tt>" method the first parameter, <tt>$sender</tt>, + corresponds to the object that raised the event, in this case, the "Convert" button. The second parameter, <tt>$param</tt> contains any additional data that the <tt>$sender</tt> object may wish to have added. </p> - - <p>We shall now examine, the three lines that implements the simply currency - conversion in the "<tt>convert_clicked</tt>" method. -<com:TTextHighlighter Language="php" CssClass="source"> -$rate = floatval($this->currencyRate->Text); -</com:TTextHighlighter> + + <p id="80067">We shall now examine, the three lines that implements the simply currency + conversion in the "<tt>convert_clicked</tt>" method.
+ </p>
+</div> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code6" > +$rate = floatval($this->currencyRate->Text); +</com:TTextHighlighter>
+ <p id="444" class="block-content"> The statement <tt>$this->currencyRate</tt> corresponds to the <tt>TTextBox</tt> component with <tt>ID</tt> value "currencyRate" in the "Home.page" template. The <tt>Text</tt> property of the <tt>TTextBox</tt> contains the value that the user entered. So, we obtain this value by <tt>$this->currencyRate->Text</tt> which we convert the - value to a float value. -<com:TTextHighlighter Language="php" CssClass="source"> -$dollars = floatval($this->dollars->Text); -</com:TTextHighlighter> + value to a float value.
+ </p> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code7"> +$dollars = floatval($this->dollars->Text); +</com:TTextHighlighter>
+<div id="5551" class="block-content">
+ <p id="555"> The next line does a similar things, it takes the user value from - the <tt>TTextBox</tt> with <tt>ID</tt> value "dollars and converts it to + the <tt>TTextBox</tt> with <tt>ID</tt> value "dollars and converts it to a float value. </p> - - <p>The third line calculates the new amount and set this value in the + + <p id="80068">The third line calculates the new amount and set this value in the <tt>Text</tt> property of the <tt>TLabel</tt> with <tt>ID="total"</tt>. - Thus, we display the new amount to the user in the label. -<com:TTextHighlighter Language="php" CssClass="source"> -$this->total->Text = $rate * $dollars; -</com:TTextHighlighter> + Thus, we display the new amount to the user in the label.
</p> - - <h1>Adding Validation</h1> - <p>The way we convert the user entered value to float ensures that the - total amount is always a number. So the user is free to enter what +</div>
+<com:TTextHighlighter Language="php" CssClass="source block-content" id="code8"> +$this->total->Text = $rate * $dollars; +</com:TTextHighlighter> + + <h1 id="16005">Adding Validation</h1> + <p id="80069" class="block-content">The way we convert the user entered value to float ensures that the + total amount is always a number. So the user is free to enter what ever they like, they could even enter letters. The user's experience in using the application can be improved by adding validators - to inform the user of the allowed values in the currency rate and the + to inform the user of the allowed values in the currency rate and the amount to be calcuated. </p> - - <p>For the currency rate, we should ensure that - <ol> + + <p id="80070">For the currency rate, we should ensure that</p> + <ol id="o111" class="block-content"> <li>the user enters a value,</li> - <li>the currency rate is a valid number,</li> + <li>the currency rate is a valid number,</li> <li>the currency rate is positive.</li> - </ol> - To ensure 1 we add one - <com:DocLink ClassPath="System.Web.UI.WebControls.TRequiredFieldValidator" Text="TRequiredFieldValidator" />. To ensure 2 and 3, we add one + </ol>
+ <p id="666" class="block-content"> + To ensure 1 we add one + <com:DocLink ClassPath="System.Web.UI.WebControls.TRequiredFieldValidator" Text="TRequiredFieldValidator" />. To ensure 2 and 3, we add one <com:DocLink ClassPath="System.Web.UI.WebControls.TCompareValidator" Text="TCompareValidator" />. We may add these validators any where within the "Home.page" template. Further details regarding these validator and other - validators can be found in the - <a href="?page=Controls.Validation">Validation Controls</a> page. -<com:TTextHighlighter Language="prado" CssClass="source"> + validators can be found in the + <a href="?page=Controls.Validation">Validation Controls</a> page.
+ </p> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code9"> <com:TRequiredFieldValidator ControlToValidate="currencyRate" ErrorMessage="Please enter a currency rate." /> @@ -235,18 +253,19 @@ $this->total->Text = $rate * $dollars; Operator="GreaterThan" ErrorMessage="Please enter a positive currency rate." /> </com:TTextHighlighter> - </p> - - <p>For the amount to be calculated, we should ensure that - <ol> + + <p id="80071" >For the amount to be calculated, we should ensure that</p> + <ol id="o222" class="block-content"> <li>the user enters a value,</li> <li>the value is a valid number (not including any currency or dollar signs).</li> - </ol> + </ol>
+ <p id="777" class="block-content"> To ensure 1 we just add another <tt>TRequiredFieldValidator</tt>, for 2 we could use a <com:DocLink ClassPath="System.Web.UI.WebControls.TDataTypeValidator" Text="TDataTypeValidator" />. For simplicity we only allow the user to enter - a number for the amount they wish to convert. -<com:TTextHighlighter Language="prado" CssClass="source"> + a number for the amount they wish to convert.
+ </p> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code9a"> <com:TRequiredFieldValidator ControlToValidate="dollars" ErrorMessage="Please enter the amount you wish to calculate." /> @@ -256,16 +275,17 @@ $this->total->Text = $rate * $dollars; ErrorMessage="Please enter a number." /> </com:TTextHighlighter> </p> - - <p>Now if you try to enter some invalid data in the application or left out + + <p id="80072" class="block-content">Now if you try to enter some invalid data in the application or left out any of the fields the validators will be activated and present the user with error messages. Notice that the error messages are presented without reloading the page. Prado's validators by default validates using both javascript and server side. The server side validation is <b>always performed</b>. For the server side, we - should skip the calculation if the validators are not satisfied. This can - done as follows. -<com:TTextHighlighter Language="php" CssClass="source"> + should skip the calculation if the validators are not satisfied. This can + done as follows.
+ </p> +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code10" > public function convert_clicked($sender, $param) { if($this->Page->IsValid) @@ -274,42 +294,43 @@ public function convert_clicked($sender, $param) $dollars = floatval($this->dollars->Text); $this->total->Text = $rate * $dollars; } -} -</com:TTextHighlighter> - </p> - - <h1>Improve User Experience With Active Controls</h1> - <p>In this simple application we may further improve the user experience +} +</com:TTextHighlighter> + + <h1 id="16006">Improve User Experience With Active Controls</h1> + <p id="80073" class="block-content">In this simple application we may further improve the user experience by decreasing the responsiveness of the application. One way to achieve a faster response is calculate and present the results without reloading the whole page. </p> - - <p>We can replace the <tt>TButton</tt> with the Active Control counter part, + + <p id="80074" class="block-content">We can replace the <tt>TButton</tt> with the Active Control counter part, <com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveButton" Text="TActiveButton" />, that can trigger a server side click event without reloading the page. - In addition, we can change the "totals" <tt>TLabel</tt> with the - Active Control counter part, + In addition, we can change the "totals" <tt>TLabel</tt> with the + Active Control counter part, <com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveLabel" Text="TActiveLabel" />, such that the server side can update the browser without - reloading the page. -<com:TTextHighlighter Language="prado" CssClass="source"> + reloading the page.
+ </p> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code11"> <div class="total-field"> <span class="total-label">Amount in Other Currency:</span> <com:TActiveLabel ID="total" CssClass="result" /> </div> <div class="convert-button"> <com:TActiveButton Text="Convert" OnClick="convert_clicked" /> -</div> -</com:TTextHighlighter> +</div> +</com:TTextHighlighter>
+ <p id="1232" class="block-content"> The server side logic remains the same, we just need to import the Active Controls name space as they are not included by default. We - add the following line to the begin of "Home.php". -<com:TTextHighlighter Language="php" CssClass="source"> -Prado::using('System.Web.UI.ActiveControls.*'); -</com:TTextHighlighter> + add the following line to the begin of "Home.php".
</p> - - <p>If you try the application now, you may notice that the page no longer +<com:TTextHighlighter Language="php" CssClass="source block-content" id="code12"> +Prado::using('System.Web.UI.ActiveControls.*'); +</com:TTextHighlighter> + + <p id="80075" class="block-content">If you try the application now, you may notice that the page no longer needs to reload to calculate and display the converted total amount. However, since there is not page reload, there is no indication or not obvious that by clicking on the "Convert" button any has happened. @@ -317,59 +338,61 @@ Prado::using('System.Web.UI.ActiveControls.*'); to "calculating..." when the user clicks on the "Convert" button. The text of the "total" label will still be updated with the new calculate amount as before. </p> - - <p>To indicate that the calculation is in progress, we can change the text + + <p id="80076" class="block-content">To indicate that the calculation is in progress, we can change the text of the "total" label as follows. We add a <tt>ClientSide.OnLoading</tt> property to the "Convert" button (since this button is responsible for requesting - the calculation). -<com:TTextHighlighter Language="prado" CssClass="source"> + the calculation).
+ </p> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code13"> <com:TActiveButton Text="Convert" OnClick="convert_clicked" > <prop:ClientSide.OnLoading> $('<%= $this->total->ClientID %>').innerHTML = "calculating..." </prop:ClientSide.OnLoading> -</com:TActiveButton> +</com:TActiveButton> </com:TTextHighlighter> - </p> - - <p>The <tt>ClientSide.OnLoading</tt> and various - <com:DocLink ClassPath="System.Web.UI.ActiveControls.TCallbackClientSide" Text="other properties" /> accept a javascript block as their content or value. - The javascript code <tt>$('...')</tt> is a javascript function that is + + <p id="80077" class="block-content">The <tt>ClientSide.OnLoading</tt> and various + <com:DocLink ClassPath="System.Web.UI.ActiveControls.TCallbackClientSide" Text="other properties" /> accept a javascript block as their content or value. + The javascript code <tt>$('...')</tt> is a javascript function that is equivalent to <tt>document.getElementById('...')</tt> that takes a string with the ID of an HTML element. Since Prado renders its components's IDs, we need to use the rendered ID of the "total" label, that is, <tt>$this->total->ClientID</tt>. We place this bit of code within a <tt><%= %></tt> to obtain the rendered HTML ID for the "total" label. The rest of the javascript code <tt>innerHTML = "calculating..."</tt> simply changes the content of the "total" label. </p> - - <h1>Adding Final Touches</h1> - <p>So far we have built a simple currency converter web application with + + <h1 id="16007">Adding Final Touches</h1> + <p id="80078" class="block-content">So far we have built a simple currency converter web application with little attention of the looks and feel. Now we can add a stylesheet to improve the overall appearance of the application. We can simply add the stylesheet inline with the template code or we may create a "theme". </p> - - <p>To create and use a theme with Prado applications, we simply create a new + + <p id="80079" class="block-content">To create and use a theme with Prado applications, we simply create a new directory "themes/Basic" in the <tt>currency-converter</tt> directory. You may need to create the <tt>themes</tt> directory first. Any directory within the <tt>themes</tt> are considered as a theme with the - name of the theme being the directory name. See the + name of the theme being the directory name. See the <a href="?page=Advanced.Themes">Themes and Skins</a> for further details. </p> - - <p>We simply create a CSS file named "common.css" and save it in the + + <p id="80080" class="block-content">We simply create a CSS file named "common.css" and save it in the <tt>themes/Basic</tt> directory. Then we add the following code - to the beginning of "Home.page" (we add a little more HTML as well). -<com:TTextHighlighter Language="prado" CssClass="source"> + to the beginning of "Home.page" (we add a little more HTML as well).
+ </p> +<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code14"> <%@ Theme="Basic" %> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > <com:THead Title="Currency Converter" /> -<body> -</com:TTextHighlighter> - The first line <tt><%@ Theme="Basic" %></tt> defines the - theme to be used for this page. The +<body> +</com:TTextHighlighter>
+ <p id="4334" class="block-content"> + The first line <tt><%@ Theme="Basic" %></tt> defines the + theme to be used for this page. The <com:DocLink ClassPath="System.Web.UI.WebControls.THead" Text="THead" /> corresponds to the HTML <tt><head></tt> element. In addition to display the <tt>Title</tt> property by the <tt>THead</tt>, all CSS diff --git a/demos/quickstart/themes/PradoSoft/style.css b/demos/quickstart/themes/PradoSoft/style.css index 82aa3dd5..dac27dde 100644 --- a/demos/quickstart/themes/PradoSoft/style.css +++ b/demos/quickstart/themes/PradoSoft/style.css @@ -1,3 +1,11 @@ +html
+{
+ background-image: url('mantisbg.jpg');
+ background-repeat: no-repeat;
+ background-position: top right;
+
+}
+
body {
font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif;
font-weight:normal;
@@ -5,14 +13,12 @@ body { color:black;
margin:0px 0px 0px 0px;
padding:0px;
- background-image: url('mantisbg.jpg');
- background-repeat: no-repeat;
- background-position: top right;
}
h1, h2, h3, h4
{
color: #333;
+ margin-bottom: 0;
}
h1, h2
@@ -67,7 +73,7 @@ a }
-.languages
+.languages
{
text-align: right;
margin: 0.5em 1em;
@@ -113,7 +119,6 @@ a }
#content {
- background:#fff;
padding: 1em 1em 1em 1em;
line-height: 135%;
}
@@ -563,7 +568,7 @@ div b.tip padding-right: 0.5em;
}
-img.figure
+#content img.figure, #content p img.figure
{
display: block;
margin: 1em auto;
@@ -593,4 +598,4 @@ table.tabular table.tabular td
{
padding: 0.75em;
-}
\ No newline at end of file +}
diff --git a/framework/3rdParty/WsdlGen/WsdlGenerator.php b/framework/3rdParty/WsdlGen/WsdlGenerator.php index cc18595e..4d6b5686 100644 --- a/framework/3rdParty/WsdlGen/WsdlGenerator.php +++ b/framework/3rdParty/WsdlGen/WsdlGenerator.php @@ -269,7 +269,7 @@ class WsdlGenerator foreach($properties as $property) { $comment = $property->getDocComment(); - if($property->isPublic() && strpos($comment, '@soapproperty') !== false) + if(strpos($comment, '@soapproperty') !== false) { if (preg_match('/@var\s+(\w+(\[\])?)\s+\$(\w+)/mi', $comment, $match)) { $param = array(); diff --git a/framework/I18N/TGlobalizationAutoDetect.php b/framework/I18N/TGlobalizationAutoDetect.php index 7393d79a..442135ff 100644 --- a/framework/I18N/TGlobalizationAutoDetect.php +++ b/framework/I18N/TGlobalizationAutoDetect.php @@ -25,6 +25,8 @@ Prado::using('System.I18N.core.HTTPNegotiator'); */
class TGlobalizationAutoDetect extends TGlobalization
{
+ private $_detectedLanguage;
+
public function init($xml)
{
parent::init($xml);
@@ -33,7 +35,15 @@ class TGlobalizationAutoDetect extends TGlobalization $http = new HTTPNegotiator();
$languages = $http->getLanguages();
if(count($languages) > 0)
+ {
+ $this->_detectedLanguage=$languages[0];
$this->setCulture($languages[0]);
+ }
+ }
+
+ public function getDetectedLanguage()
+ {
+ return $this->_detectedLanguage;
}
}
diff --git a/framework/Web/Services/TSoapService.php b/framework/Web/Services/TSoapService.php index 1472ffc4..e4a1c67e 100644 --- a/framework/Web/Services/TSoapService.php +++ b/framework/Web/Services/TSoapService.php @@ -361,7 +361,7 @@ class TSoapServer extends TApplicationComponent $options['uri']=$this->_uri; if(is_string($this->_classMap)) { - foreach(preg_split('/\s?,\s?/', $this->_classMap) as $className) + foreach(preg_split('/\s*,\s*/', $this->_classMap) as $className) $options['classmap'][$className]=$className; //complex type uses the class name in the wsdl } return $options; diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php index faf0c7fd..ef4a5c1e 100644 --- a/framework/Web/UI/TTemplateManager.php +++ b/framework/Web/UI/TTemplateManager.php @@ -250,6 +250,14 @@ class TTemplate extends TApplicationComponent implements ITemplate }
/**
+ * @return string template file path if available, null otherwise.
+ */
+ public function getTemplateFile()
+ {
+ return $this->_tplFile;
+ }
+
+ /**
* @return boolean whether this template is a source template, i.e., this template is loaded from
* some external storage rather than from within another template.
*/
diff --git a/tests/simple_unit/ActiveRecord/CriteriaTestCase.php b/tests/simple_unit/ActiveRecord/CriteriaTestCase.php new file mode 100644 index 00000000..f1545e1d --- /dev/null +++ b/tests/simple_unit/ActiveRecord/CriteriaTestCase.php @@ -0,0 +1,36 @@ +<?php
+
+Prado::using('System.Data.ActiveRecord.TActiveRecord');
+require_once(dirname(__FILE__).'/records/DepartmentRecord.php');
+require_once(dirname(__FILE__).'/records/DepSections.php');
+
+class CriteriaTestCase extends UnitTestCase
+{
+ function setup()
+ {
+ $conn = new TDbConnection('pgsql:host=localhost;dbname=test', 'test','test');
+ TActiveRecordManager::getInstance()->setDbConnection($conn);
+ }
+
+ function test_orderby_only()
+ {
+ $criteria = new TActiveRecordCriteria;
+ $criteria->OrdersBy['name'] = 'asc';
+ $records = DepartmentRecord::finder()->findAll($criteria);
+ $this->assertEqual(count($records), 8);
+ $this->assertEqual($records[0]->name, '+GX Service');
+ $this->assertEqual($records[7]->name, 'Marketing');
+ }
+
+ function test_orderby_only_desc()
+ {
+ $criteria = new TActiveRecordCriteria;
+ $criteria->OrdersBy['name'] = 'desc';
+ $records = DepartmentRecord::finder()->findAll($criteria);
+ $this->assertEqual(count($records), 8);
+ $this->assertEqual($records[7]->name, '+GX Service');
+ $this->assertEqual($records[0]->name, 'Marketing');
+ }
+}
+
+?>
\ No newline at end of file diff --git a/tests/simple_unit/Soap/ContactManager.php b/tests/simple_unit/Soap/ContactManager.php index e8b12d99..8bf3d756 100644 --- a/tests/simple_unit/Soap/ContactManager.php +++ b/tests/simple_unit/Soap/ContactManager.php @@ -56,7 +56,7 @@ class ContactManager{ * @soapmethod
*/
public function saveContact(Contact $Contact) {
- error_log(var_export($Contact,true));
+ //error_log(var_export($Contact,true));
//$Contact->save();
return true;
}
@@ -70,6 +70,14 @@ class ContactManager{ return array(array(1,2), array("12", 1.2));
}
+ /**
+ * @return array
+ * @soapmethod
+ */
+ public function getEmptyArray()
+ {
+ return array();
+ }
}
diff --git a/tests/simple_unit/Soap/SoapTestCase.php b/tests/simple_unit/Soap/SoapTestCase.php new file mode 100644 index 00000000..78a6875b --- /dev/null +++ b/tests/simple_unit/Soap/SoapTestCase.php @@ -0,0 +1,91 @@ +<?php
+
+ini_set("soap.wsdl_cache_enabled",0);
+
+require_once(dirname(__FILE__).'/ContactManager.php');
+
+class SoapTestCase extends UnitTestCase
+{
+ function getWsdlUri()
+ {
+ $script = str_replace('unit.php', 'ws.php',$_SERVER['SCRIPT_NAME']);
+ return "http://".$_SERVER['HTTP_HOST'].$script.'?soap=contacts.wsdl';
+ }
+
+ function getClient()
+ {
+ return new SoapClient($this->getWsdlUri());
+ }
+
+ function testContactArray()
+ {
+ $result = $this->getClient()->getContacts();
+ $this->assertEqual(count($result), 1);
+ $obj = $result[0];
+ $this->assertEqual($obj->name, "me");
+ $this->assertEqual($obj->id, 1);
+ $this->assertEqual($obj->address->street, "sesamstreet");
+ $this->assertNull($obj->address->nr);
+ $this->assertNull($obj->address->zipcode);
+ $this->assertEqual($obj->address->city, "sesamcity");
+ $this->assertEqual($obj->email, "me@you.com");
+ }
+
+ function testGetContactThrowsException()
+ {
+ try
+ {
+ $result = $this->getClient()->getContact(1);
+ $this->fail();
+ }
+ catch (SoapFault $f)
+ {
+ $this->pass();
+ }
+ }
+
+ function testGetNewContact()
+ {
+ $obj = $this->getClient()->newContact();
+ $this->assertNull($obj->name);
+ $this->assertNull($obj->id);
+ $this->assertNull($obj->address);
+ $this->assertNull($obj->email);
+ }
+
+ function testSaveContactReturnsTrue()
+ {
+ $c = new Contact;
+ $result = $this->getClient()->saveContact($c);
+ $this->assertTrue($result);
+ }
+
+ function getMixedArray()
+ {
+ $result = $this->getClient()>getList();
+ $expected = array(array(1,2), array("12", 1.2));
+ $this->assertEqual($result, $expected);
+ }
+
+ function testEmptyArray()
+ {
+ $result = $this->getClient()->getEmptyArray();
+ $this->assertTrue(is_array($result));
+ $this->assertEqual(count($result), 0);
+ }
+
+ function testUnknownFunctionThrowsException()
+ {
+ try
+ {
+ $this->getClient()->test();
+ $this->fail();
+ }
+ catch (SoapFault $f)
+ {
+ $this->pass();
+ }
+ }
+}
+
+?>
\ No newline at end of file diff --git a/tests/simple_unit/application.xml b/tests/simple_unit/application.xml new file mode 100644 index 00000000..971d5684 --- /dev/null +++ b/tests/simple_unit/application.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?>
+
+<application id="simple_unit" mode="Debug">
+ <services>
+ <service id="soap" class="System.Web.Services.TSoapService">
+ <soap id="contacts" provider="Application.Soap.ContactManager" ClassMaps="Contact, Address"/>
+ </service>
+ </services>
+</application>
\ No newline at end of file diff --git a/tests/simple_unit/ws.php b/tests/simple_unit/ws.php new file mode 100644 index 00000000..97e21cad --- /dev/null +++ b/tests/simple_unit/ws.php @@ -0,0 +1,9 @@ +<?php
+
+include_once '../../framework/prado.php';
+include_once './Soap/ContactManager.php';
+
+$app = new TApplication('.');
+$app->run();
+
+?>
\ No newline at end of file |