To get started, begin with the notion that the Wiki is nothing more than a single table with a few columns tracking the Content.To begin, lets assume we will need the following columns: WikiID - the primary key of the table, which will be stored as an integer, and will be autonumbered. Title - the visually provided title for the topic, stored as a string with a maximum length of 255. Topic - the physical reference topic value to be used when linking between topics. The syntax of this will be discussed
later. This will be a string with a character length of 50. Content - the content of the wiki article, stored as a string with an unlimited length. To create the table, execute the following code:
CREATE TABLE [OWS_Wiki](
[WikiID] [int] IDENTITY(1,1) NOT NULL,
[Title] [nvarchar](255) NULL,
[Topic] [nvarchar](50) NULL,
[Content] [ntext] NULL
)
Now with the table in place, create a new Open Web Studio configuration and get busy building. Click New on the Ribbon, starting the initial template. Click the
General tab and give the configuration a name, like "My Wiki". Press Save.
To start, we will assume that the topic which is to be viewed will be a variable value provided in the
Querystring. This will be consumed without our queries throughout the project, and is best created as a global query variable high up in our code tree. Expand the
Region - OnLoad, followed by
Region - Query Variables - each of which are simply place holders, logically organizing the code structure. Feel free to clear out the current members of this region, as they are place holders used to demonstrate what actions should appear within this section by default. With the Region - Query Variables selected - click the
Actions tab on the ribbon, and then choose the
Variable action. Double click the newly added action to provide the property window. Assign the following settings to the properties, and press Save: Variable Type -
Source - Topic Target - @Topic Target Left - ' Target Right - ' Empty Target - NULL Security - Escape Single Quotes, Escape HTML Symbols, Escape code tags ONCE This means that a variable from the QueryString with the name "Topic" will be utilized by our queries. Whenever "@Topic" appears in our queries, it will be replaced with the value from the QueryString with a single quote appearing to the left and right side of the value. If this variable is not present in the QueryString, or it is has a lenght of zero - NULL will be the resulting value assigned to @Topic. Finally - the resulting value will escape single quotes, html symbols and script syntax.
Now that the variable is in place, a template and query must be provided for viewing the contents of our table. Expand the
Region - OnRender, with Region - OnRender selected, click the
Template Action from the Actions tab on the Ribbon. Double click the newly added action to provide the property window. Assign the following settings to the properties, and press Save: Template - Query Content - Select * from OWS_Wiki where Topic=@Topic This will act as our Template Query, meaning that the physical output of our Open Web Studio configuration will be bound to the query provided above. Notice that it is consuming the variable we created in the previous step. Next, click the
Template Action from the Actions tab on the Ribbon. Double click the newly added action to provide the property window. Assign the following settings to the properties, and press Save: Template - Detail Content -
<h1>[Title]</h1><br />[Content]
This will act as our complete template, which will be bound the the Query provided in the previous step. The output of this is simple, just a header with the value of the Title column from our query, followed by a line break and then the Content column of our table.
Publishing at this time will provide a very rudimentary view for our Wiki content. Before we go down the road of viewing and testing the content - we definitely need a way to create content! This simple interface will extend a bit of the logic we already have in place, and provide a very easy interface for conducting both the Add and Edit operations. Keep in mind as you follow along that the logic used here is the standard approach that you should take for most of your configurations.
First, modify the View template from the previous step by double clicking on the previously added Detail Template. We will be adding two links with a bit of formatting to the top of the View so that you can easily Edit the current topic or jump to a new topic. With the last line being the original line from the previous step, the content line will now read:
<div>
<a href="?topic=[topic,q]&action=edit">edit</a>
|
<a href="#" onclick="var ntopic = prompt('What topic would you like?'); if (typeof ntopic != 'undefined')
{window.location='?topic='+ntopic.replace(/[^w]+/g,'_');} return false;">To jump to another topic, click here.</a>
</div>
<hr />
<h1>[Title]</h1><br />[Content]
Now, let's disect this content a bit and describe exactly what it provided. First, a div tag is provided to break up the physical logic of the layout. Next, an anchor tag
edit was added. Now, when we click on the Edit link, the current topic, from the querystring, will be posted back to the server, along with another variable, called "action" with the value "edit". In the next step we will provide the handling for this interaction - yeilding an edit form for adding and editing records in the system. Finally, we added a simple javascript prompt window. When clicked, the user will get the message "What topic would you like?", and following a provided value and "Ok", the window will post back to the server with the topic set to the provided topic value - stripped of any whitespace or symbolic characters and instead replacing them with a single underscore. Press Save, and continue with the editing.
To begin consuming the incoming querystring parameter "action", first let's review the exact utilization of this parameter. While it is not something specific to Open Web Studio, as it can truly be named anything, the structure which will be provided here is the standard practice for most interaction, regardless of whether ajax is utilized or not. The basic runtime will be the result of a set of If conditions, each of which will operate on the incoming condition of the querystring parameter "Action". The default condition, or Else, will be the general detail output which we have already created. To build your logic, start by adding an
If condition from the Actions tab on the Ribbon. Double click the newly added action to provide the property window. Assign the following settings to the properties, and press Save: Condition Type - Standard Left Condition - [action,q] Comparison - = Right Condition - edit Therefore, whenever the Querystring Parameter "action" has the value of "edit", this tree section will be executed. Next, at the same level in the tree as our If condition, we need to add an "Else" condition. Add an
Else condition from the Actions tab on the Ribbon. There are not any properties provided for "Else", but it is the default behaviour whenever the previous If conditions are not met. Now, move the current Query Template and Detail Template which were created in the previous step into the Else condition. Select the If condition, "If [action,q]=edit", and add a new
Template Action from the Ribbon. This query is actually exactly the same as the detail query, we are operating off the topic from the querystring, as was anticipated. Double click the newly added action to provide the property window. Assign the following settings to the properties, and press Save: Template - Query Content - Select * from OWS_Wiki where Topic=@Topic Next, click the
Template Action from the Actions tab on the Ribbon. Double click the newly added action to provide the property window. Assign the following settings to the properties, and press Save: Template - Detail Content -
<input id="frmWiki" name="frmWiki" type="hidden" value="[wikiid]"/>
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="50" class="SubHead">Title</td>
<td width="100%">
<input id="frmTitle" name="frmTitle" style="width:100%;" value="[COALESCE,title,,{ENCODEHTML}]"/>
</td>
</tr>
<tr>
<td width="50" class="SubHead">Topic</td>
<td width="100%">
<input id="frmTopic" name="frmTopic" style="width:100%;" value="[COALESCE,topic,,{ENCODEHTML}]"/>
</td>
</tr>
<tr>
<td colspan="2">
{TEXTEDITOR,frmContent,Content,,100%,400}
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button onclick="document.forms[0].submit();">Save</button><button onclick="history.go(-1);">Cancel</button>
</td>
</tr>
</table>
Now, let's digest this a bit, as you can see we consumed a few different type of tokens here. First, we provided an Input element named "frmWiki". Pay close attention throughout this developement that both the name and id are always provided for form elements. The explanation for this is fairly simple - the name attribute is the specific reference of the variable when it is consumed by the server, while the id is the attribute that is the specific reference for the object by the javascript on the client. Even when the configuration doesn't require any javascript, it is always best practice to provide both - especially with OWS. The "frmWiki" element is set to be a hidden element on the form, which will hide it from view, but it will be received when you press Save. The purpose of this, even though we have "topic" in the querystring is a bit of a match-up constraint. We are simply going to use this to verify that the current topic being edited matches the anticipated topic value which is received by the querystring. Below the hidden input element containing the primary key of the record, a simple card view style edit form is provided. The first row contains the Title input element, a text field with a width that will span with horizontal length of the page. It's value is the Title column retrieved from our Query. The
COALESCE token has been used here to provide a quick inline formatting of our value, encoding any HTML formatting contained within it so that characters like less-than and greater-than will appear in plain text. Again, this is a standard practice. The next line in the table contains the Topic input element, which follows the exact same behaviour as title. Following this is the row containing the Content of our topic. This content is contained within the Content column, and is provided visually within a Rich Text Editor by employingthe
TEXTEDITOR token. The parameters of this are very basic. The first is the name/id of the element as it will appear in the Form, the next two parameters are the name and source of the value to be displayed within the editor. In this case the Content column, and the default source which is the Query result. The last two parameters are the Width and Height of the editor, in this assignment 100% wide and 400 pixels tall. The last line of the table contains our Submit and Cancel buttons. To submit we are merely submitting the form back to the server. To cancel, we are using the javascript history object, passing negative one will revert back one page in the history. This will act as our complete template for the Edit, which will be bound the the Query provided in the previous step. Now, we need an Add form, which will automatically be displayed when No Records result from the Query. To do this, click the
Template Action from the Actions tab on the Ribbon. Double click the newly added action to provide the property window. Assign the following settings to the properties, and press Save: Template - Detail (No Results) Content -
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="50" class="SubHead">Title</td>
<td width="100%">
<input id="frmTitle" name="frmTitle" style="width:100%;" value="[COALESCE,topic,q,{ENCODEHTML}]"/>
</td>
</tr>
<tr>
<td width="50" class="SubHead">Topic</td>
<td width="100%">
<input id="frmTopic" name="frmTopic" style="width:100%;" value="[COALESCE,topic,q,{ENCODEHTML}]"/>
</td>
</tr>
<tr>
<td colspan="2">
{TEXTEDITOR,frmContent,frmContent,Form,100%,400}
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button onclick="document.forms[0].submit();">Save</button><button onclick="history.go(-1);">Cancel</button>
</td>
</tr>
</table>
Notice that only a few lines differ from the Detail Template. In this case, we won't have a result from the Query - so the "frmWikiID" value will not be provided. The Title and Topic values are now retrieiving their defaults from the parameter coming from the querystring. And finally, the Text Editor default value will be provided by the "frmContent" Form variable itself. In this demonstration we don't have any server side validation - but this would be utilized when that is provided, being that the server received the posted values, but they require modification so the form is redisplayed with those values in place.
Now that the form is in place, it's time to save the incoming value. When the save button is clicked, as specified in the previous step, the form will be posted back. Keep in mind that also present during the post back are the topic and action parameters from the querystring. With action set to "edit". Again, we need to provide additional functionality to extend what we have done within a previous step. Now, within the condition checking when "action" from the querystring is equal to "edit", add both an If and ELSE condition. Move all the existing steps within the action to be children of the ELSE condition. The If condition will check to see if "frmContent" has been received from the form, and if so - Save the record. With the newly added IF condition - set the parameters to the following: Condition Type - Standard Left Condition - [COALESCE,frmContent,Form,{LENGTH}] Comparison - > Right Condition - 0 In this case, as before, the
COALESCE token is being used to format an incoming value. In this case, when the form variable named "frmContent" has a length greater than zero, the IF condition is entered. With the If condition selected - click the
Actions tab on the ribbon, and then choose the
Variable action. Double click the newly added action to provide the property window. Assign the following settings to the properties, and press Save: Variable Type -