Professional Documents
Culture Documents
Qcubed Tutorial - Building A Wiki: Creating The Database Model
Qcubed Tutorial - Building A Wiki: Creating The Database Model
In this tutorial, we will create a very basic wiki which will allow anyone to modify the wiki pages. The idea of having a Wiki created in QCubed has been a subject of conversation for many times. But in fact, a wiki is very easy to do in QCubed, so why not build one? For this tutorial, We assume that you have a working copy of QCubed installed.
Code generation
After we have created the table in our database, we can let QCubed perform code generation. you can do this now by going to the QCubed start page and use the link "_devtools/codegen.php". After Code generation, QCubed will have created the data objects for our page table, as well as some default CRUD functionality for the table. The html pages 'drafts' folder, where you will find the html pages for listing, creating, modifying and deleting 'page' records. For our wiki, we don't need any of the default generated pages, as we will create our own page to display the wiki page.
} } WikiForm::Run('WikiForm'); ?>
wiki.tpl.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=<?php _p(QApplication::$EncodingType); ?>" <title>QCubed Wiki Example</title> <style type="text/css">@import url("<?php _p(__VIRTUAL_DIRECTORY__ . __CSS_ASSETS__); ?>/styles.css");< </head><body> <?php $this->RenderBegin(); ?> <?php $this->RenderEnd(); ?> </body></html>
For now, when you load this page, it will display a blank page, as we did not add anything to the page yet.
Adding controls
For our page to do something, we will need to add several controls. The first thing we want our page to do is to display the contents of the page we are at. If this page is not present, a default message should be displayed. Let's begin with adding this functionality.
The first time a Qcubed PHP script is loaded, it will call the Form_Create() function within the QForm class, so we put our initialization of the object in here. The initialization of the database object will retrieve the contents of page based on the URL. We can do this using the following code:
... protected function Form_Create() { $this->objWikiPage = Page::LoadByTitle(QApplication::QueryString('page')); } ...
Let's break down this single line: * Page is an object which is created by QCubed during code generation. * LoadByTitle?() is a static function created by QCubed during code generation. The function takes one parameter (the page title) and will return a Page object, which will contain the conents of the database record. * QApplication::QueryString?() is an array in which QCubed has stored all $_GET[] and $_POST[] parameters that were used to access the PHP script After this line of code is executed, the objWikiPage member variable will contain a page object based. If the page object cannot be found (which will be the case in our situation, since we have no contents in our Wiki yet), the page object will be "null".
In our form create, we also assigned some logic to display the contents of the page based on the existance of the database record in the table. If the record fo the page does not exist, we display a message that says so. To display these labels, we also need to render them in the template file:
... <?php $this->RenderBegin(); ?> <? $this->lblTitle->Render() ?> <? $this->lblContents->Render() ?> <?php $this->RenderEnd(); ?> ...
If we would run this page now, we would see one line which displays the text "this page does not exist yet".
When we now reload the page, we will see the page title "WikiStart" as well!
$this->btnEditPage->Text = "Edit"; $this->btnSavePage = new QButton($this); $this->btnSavePage->Text = "Save"; $this->btnSavePage->Visible = false; $this->btnCancelEdit = new QButton($this); $this->btnCancelEdit->Text = "Cancel"; $this->btnCancelEdit->Visible = false; ... ...
<?php $this->RenderBegin(); ?> <? $this->lblTitle->Render(); ?><br> <? $this->lblContents->Render(); ?><br> <? $this->txtEditContents->Render(); ?><br> <br> <? $this->btnEditPage->Render() ?> <? $this->btnSavePage->Render() ?> <? $this->btnCancelEdit-> <?php $this->RenderEnd(); ?> ...
Assign actions
Now that we have the buttons, we can assign actions to them. When the edit button is clicked, the Edit button and lblContent should be hidden, and the txtEditContent, Save and Cancel should be displayed. When the cancel button is clicked, reverse should happen. When the Save button is clicked, the contents of the textbox should be saved to the database and copied over to the lable to display it. We then call the cancel button routine, which will take care of resetting the buttons and labels to the correct state.
$this->txtEditContents = new QWriteBox($this); if ($this->objWikiPage) $this->txtEditContents->Text = $this->objWikiPage->Contents; else $this->txtEditContents->Text = "this page does not exit yet."; $this->txtEditContents->Visible = false;
$this->btnSavePage = new QButton($this); $this->btnSavePage->Text = "Save"; $this->btnSavePage->Visible = false; $this->btnSavePage->AddAction(new QClickEvent(), new QServerAction('btnSavePage_Click
$this->btnCancelEdit = new QButton($this); $this->btnCancelEdit->Text = "Cancel"; $this->btnCancelEdit->Visible = false; $this->btnCancelEdit->AddAction(new QClickEvent(), new QServerAction('btnCancelEdit_C } protected function btnEditPage_Click($strFormId, $strControlId, $strParameter) { $this->txtEditContents->Visible = true; $this->lblContents->Visible = false; $this->btnEditPage->Visible = false; $this->btnCancelEdit->Visible = true; $this->btnSavePage->Visible = true;
Add controls
} protected function btnSavePage_Click($strFormId, $strControlId, $strParameter) { if (!$this->objWikiPage) $this->objWikiPage = new Page(); $this->objWikiPage->Title = $this->lblTitle->Text; $this->objWikiPage->Contents = $this->txtEditContents->Text; $this->objWikiPage->Save(); $this->lblContents->Text = $this->objWikiPage->Contents; $this->btnCancelEdit_Click($strFormId, $strControlId, $strParameter); } protected function btnCancelEdit_Click($strFormId, $strControlId, $strParameter) { $this->txtEditContents->Visible = false; $this->lblContents->Visible = true; $this->btnEditPage->Visible = true; $this->btnCancelEdit->Visible = false; $this->btnSavePage->Visible = false; }
WikiWords?
All this will allow us to start editing the main "WikiStart" page. But a Wiki consists of more pages then just the front page. Links within a wiki are created by using WikiWords?. Whenever a wikiword is detected, it should be replaced with a link to the corresponding wiki page. To do this, we will use a regular expression to scan for wikiwords, and replace it with a link.
protected function FindWikiWords($contents) { $page = $_SERVER["SCRIPT_NAME"]; $contents = ereg_replace("( ){1}(([A-Z][a-z0-9]+){2,})", " <a href=\"" . $page . "?page=\\2\">\\2 return $contents; }
Every time we set the Text of the lblContents, we should call this function:
if ($this->objWikiPage) $this->lblContents->Text = $this->FindWikiWords($this->objWikiPage->Contents); else $this->lblContents->Text = "this page does not exit yet."; protected function btnSavePage_Click($strFormId, $strControlId, $strParameter) { if (!$this->objWikiPage) $this->objWikiPage = new Page(); $this->objWikiPage->Title = $this->lblTitle->Text; $this->objWikiPage->Contents = $this->txtEditContents->Text; $this->objWikiPage->Save(); $this->lblContents->Text = $this->FindWikiWords($this->objWikiPage->Contents); $this->btnCancelEdit_Click($strFormId, $strControlId, $strParameter); }
HtmlEntities?
The above function will work fine, but instead of displaying a link, it will display the HTML code within the Contents label. This is because by default, QCubed will perform a htmlentities() function on the text. If you do not want this, we need to disable this. This can be done by setting the property HtmlEntities? to false for the Assign actions 6