Web Development (CGI Library)

In this chapter we will learn about developing Web applications using a CGI Library written in the Ring language.

Configure the Apache web server

In this section we will learn about using Ring with the Apache HTTP Server. We can also use Ring with any web server that supports CGI.

Note

If you are developing your application using Ring Notepad then there’s no need to configure Apache manually.

Using XAMPP Apache web server

Here we will use the XAMPP application that has Apache web server already been included. You can download XAMPP package from this link

XAMPP : https://www.apachefriends.org/download.html

Install then open the configuration file from the XAMPP application or search for it in the following locations based on your operating system.

For Windows:

xampp\apache\conf\httpd.conf 

For Linux:

/opt/lampp/etc/httpd.conf 

For macOS:

/Applications/XAMPP/xamppfiles/etc/httpd.conf 

Search for the next line and make sure that it’s not commented

LoadModule cgi_module modules/mod_cgi.so 

Search for : AddHandler cgi-script

Then add “.ring” to the supported cgi extensions

Example

AddHandler cgi-script .cgi .ring 

Example

AddHandler cgi-script .cgi .pl .asp .ring 

Restart/Start the server using XAMPP “Manage Servers” or “Services” section

Create your web applications in a directory supported by the web server.

For Windows:

xampp\htdocs\mywebapplicationfolder 

For Linux:

/opt/lampp/htdocs/mywebapplicationfolder 

For macOS:

Open XAMPP application then go to "Volumes" section Mount the "/opt/lampp" volume Open Finder then you will find it mounted as an IP address under "Locations" on the left menu 

Setting the shebang line

For Ring files to run properly under CGI we need to set the shebang line to locate the executable file of Ring. So, Inside the source code file (*.ring), Add next line as the very first line in the file:

For Windows:

#!ring -cgi 

For Linux:

#!/usr/bin/ring -cgi 

For macOS:

#!/usr/local/bin/ring -cgi 

Note

Change the previous line based on the path to ring executable in your machine

Grant Ring files execution permission

In Linux and Mac operating systems ring files cannot be run properly using CGI until we grant them executable permission. You can do that using the properties section of your preferred File manager or you can do it using Terminal as follow:

sudo chmod +x ringAppFile.ring 

Note

If you are developing your application using Ring Notepad then this step will be done automatically.

Ring CGI Hello World Program

The next program is the Hello World program

For Windows:

#!ring -cgi See "content-type: text/html" +nl+nl+ "Hello World!" + nl 

For Linux:

#!/usr/bin/ring -cgi See "content-type: text/html" +nl+nl+ "Hello World!" + nl 

For macOS:

#!/usr/local/bin/ring -cgi See "content-type: text/html" +nl+nl+ "Hello World!" + nl 

Hello World Program using the Web Library

We can use the web library to write CGI Web applications quickly

Example (1) :

#!ring -cgi Load "weblib.ring" Import System.Web New Page { Text("Hello World!") } 

Example (2) :

#!ring -cgi Load "weblib.ring" Import System.Web WebPage() { Text("Hello World!") } 

Tip

the difference between ex. 1 and ex. 2 is using WebPage() function to return the page object instead of creating the object using new statement.

Web Library Features

The next features are provided by the Web library to quickly create web applications.

  • Generate HTML pages using functions

  • Generate HTML pages using objects

  • HTTP Get

  • HTTP Post

  • Files Upload

  • URL Encode

  • Templates

  • CRUD MVC Sample

  • Users Logic & Registration Sample

HTTP Get Example

The Page User Interface

#!ring -cgi Load "weblib.ring" Import System.Web New Page { Title = "Test HTTP Get" divstart([ :style = StyleSizeFull() ] ) boxstart() text( "Test HTTP GET" ) newline() boxend() divstart([ :style = Styledivcenter("600px","550px") + StyleGradient(21) ]) divstart([:style = stylefloatleft() + stylesize("100px","100%") + stylecolor("black") + stylegradient(58)]) formstart("ex5.ring") tablestart([ :style = stylesize("65%","90%") + stylemarginleft("35%") + stylemargintop("30%") ]) rowstart([]) cellstart([]) text ( "Name : " ) cellend() cellstart([]) cTextboxStyle = StyleMarginLeft("5%") + StyleWidth("250px") + StyleColor("black") + StyleBackColor("white") textbox([ :name = "Name", :style = cTextboxStyle ] ) cellend() rowend() rowstart([]) cellstart([]) text ( "Address : " ) cellend() cellstart([]) textbox([ :name = "Address", :style = cTextboxStyle] ) cellend() rowend() rowstart([]) cellstart([]) text ( "Phone : " ) cellend() cellstart([]) textbox([ :name = "Phone", :style = cTextboxStyle ]) cellend() rowend() rowstart([]) cellstart([]) text ( "Age : " ) cellend() cellstart([]) textbox([ :name = "Age", :style = cTextboxStyle ]) cellend() rowend() rowstart([]) cellstart([]) text ( "City: " ) cellend() cellstart([]) listbox([ :name = "City", :items = ["Cairo","Riyadh","Jeddah"], :style = stylemarginleft("5%") + stylewidth("400px") ] ) cellend() rowend() rowstart([]) cellstart([]) text ( "Country : " ) cellend() cellstart([]) combobox([ :name = "Country", :items = ["Egypt","Saudi Arabia","USA"], :style = stylemarginleft("5%") + stylewidth("400px")+ stylecolor("black")+ stylebackcolor("white")+ stylefontsize("14px") ]) cellend() rowend() rowstart([]) cellstart([]) text ( "Note : " ) cellend() cellstart([]) editbox([ :name = "Notes", :style = stylemarginleft("5%") + stylesize("400px","100px")+ stylecolor("black")+ stylebackcolor("white") , :value = "write comments here..." ] ) cellend() rowend() rowstart([]) cellstart([]) cellend() cellstart([]) submit([ :value = "Send" , :Style = stylemarginleft("5%") ]) cellend() rowend() tableend() formend() divend() divend() divend() } 

Screen Shot:

HTTP Get

The Response

#!ring -cgi Load "weblib.ring" Import System.Web New Page { divstart([ :style = styledivcenter("800px","500px") ]) boxstart() text ( "HTTP GET Response" ) newline() boxend() divstart([ :style = stylefloatleft()+stylewidth("10%")+ stylecolor("black")+stylegradient(58) ]) newline() text ( "Name : " ) newline() newline() text ( "Address : " ) newline() newline() text ( "Phone : " ) newline() newline() text ( "Age : " ) newline() newline() text ( "City : " ) newline() newline() text ( "Country : " ) newline() newline() text ( "Note : " ) newline() newline() divend() divstart([ :style = stylefloatleft()+stylewidth("90%")+ stylecolor("black")+stylegradient(47) ]) divstart([ :style = stylefloatleft() + stylewidth("1%") ]) newline() divend() divstart([ :style = stylefloatleft() + stylewidth("95%") ]) newline() text ( aPageVars["Name"] ) newline() newline() text ( aPageVars["Address"] ) newline() newline() text ( aPageVars["Phone"] ) newline() newline() text ( aPageVars["Age"] ) newline() newline() text ( aPageVars["City"] ) newline() newline() text (aPageVars["Country"] ) newline() newline() text ( aPageVars["Notes"] ) newline() newline() divend() divend() divend() } 

Screen Shot:

HTTP Get

HTTP POST Example

The Page User Interface

#!ring -cgi Load "weblib.ring" Import System.Web New Page { boxstart() text( "Post Test") newline() boxend() divstart([ :style=StyleFloatLeft()+StyleWidth("100px") ]) newline() text( "Number1 : " ) newline() newline() text( "Number2 : " ) newline() newline() divend() formpost("ex7.ring") divstart([ :style = styleFloatLeft()+StyleWidth("200px") ]) newline() textbox([ :name = "Number1" ]) newline() newline() textbox([ :name = "Number2" ]) newline() newline() submit([ :value = "Send" ] ) divend() formend() } 

Screen Shot:

HTTP Post

The Response

#!ring -cgi Load "weblib.ring" Import System.Web New Page { boxstart() text( "Post Result" ) newline() boxend() divstart([ :style = styleFloatLeft()+styleWidth("200px") ]) newline() text( "Number1 : " + aPageVars["Number1"] ) newline() newline() text( "Number2 : " + aPageVars["Number2"] ) newline() newline() text( "Sum : " + (0 + aPageVars["Number1"] + aPageVars["Number2"] ) ) newline() divend() } 

Screen Shot:

HTTP Post

Upload Files

The Page User Interface

#!ring -cgi Load "weblib.ring" Import System.Web New page { boxstart() text( "Upload File" ) newline() boxend() for x = 1 to 3 newline() next formupload("ex9.ring") text( "Customer Name : " ) textbox([ :name = "custname" ]) newline() newline() divstart([ :style = styleFloatLeft() + styleWidth("90px") ]) uploadfile("file") newline() newline() uploadfile("file2") newline() newline() submit([ :value = "Send" ]) divend() formend() } 

Screen Shot:

Upload File

The Response

#!ring -cgi Load "weblib.ring" Import System.Web cUploadPath = "C:/Apache2.2/htdocs/ringapp/upload/" cUploadFolder = "/ringapp/upload/" New page { boxstart() text( "Upload Result" ) newline() boxend() newline() divstart([ :style= styleFloatLeft() + styleWidth("100px") ]) text( "Name : " + aPageVars["custname"] ) newline() divend() if aPageVars["file"] != char(13) getuploadedfile(self,"file") ok if aPageVars["file2"] != char(13) getuploadedfile(self,"file2") ok } Func getuploadedfile oObj,cFile # here we use object.property # instead of object { } to avoid executing braceend method cFileName = cUploadPath + oObj.getfilename(aPageVars,cFile) write(cFileName,aPageVars[cFile]) system("chmod a+x "+cFileName) oObj.newline() oObj.text( "File "+cFileName+ " Uploaded ..." ) oObj.newline() imageURL = cUploadFolder + oObj.getfilename(aPageVars,cFile) oObj.link([ :url = imageURL, :title = "Download" ]) oObj.newline() oObj.image( [ :url = imageURL , :alt = :image ] ) oObj.newline() 

Screen Shot:

Upload File

Cookies

The Page User Interface

#!ring -cgi Load "weblib.ring" Import System.Web New page { boxstart() text( "Cookie Test" ) newline() boxend() newline() link([ :url = "ex11.ring", :title = "Use Cookies" ]) cookie("custname","Mahmoud Fayed") cookie("custage",28) } 

Screen Shot:

Cookies

The Response

#!ring -cgi Load "weblib.ring" Import System.Web New Page { boxstart() text( "Cookies Values" ) newline() boxend() link([ :url = "ex10.ring", :title = "back" ]) newline() divstart([:style="float:left;width:200px"]) text( "Name : " + aPageVars["custname"] ) newline() text( "Age : " + aPageVars["custage"] ) newline() divend() } 

Screen Shot:

Cookies

URL Encode

The Page User Interface

#!ring -cgi Load "weblib.ring" Import System.Web New Page { boxstart() text( "URLEncode" ) newline() boxend() link([ :url = "ex5.ring?Name="+URLEncode("-*{Mahmoud}*-")+ "&Address=Egypt&Phone=123456&Age=28&Notes=Programmer", :title = "Test URL Encode" ]) } 

Screen Shot:

URL Encode

Screen Shot:

URL Encode

Templates

Using Templates we can write Ring code inside HTML files

Syntax:

<%= Ring Expression %> <% Ring Statements %> 

The HTML Code

<h1>Listing Numbers</h1> <table> <tr> <th> <%= myheader.cColumn1 %> </th> <th> <%= myheader.cColumn2 %> </th> <th></th> <th></th> <th></th> </tr> <% for x in aNumbers %> <tr> <td> <%= x.nValue %> </td> <td> <%= x.nSquare %> </td> </tr> <% next %> </table> 

The Ring Code

#!ring -cgi Load "weblib.ring" Import System.Web New NumbersController { start() } Class NumbersController MyHeader aNumbers Func Start MyHeader = New Header { cColumn1 = "Number" cColumn2 = "Square" } aNumbers = list(20) for x = 1 to len(aNumbers) aNumbers[x] = new number { nValue = x nSquare = x*x } next cTemp = Template("mynumbers.html",self) New Page { boxstart() text( "Test Templates" ) newline() boxend() html(cTemp) } Class Header cColumn1 cColumn2 Class Number nValue nSquare 

Screen Shot:

Templates

HTML Special Characters

The text() function display HTML special characters.

If you want to write html code, use the html() function.

#!ring -cgi Load "weblib.ring" Import System.Web New Page { boxstart() text("HTML Special Characters") newline() boxend() text('  <html>  <body>  <p> "hello world" </p>  </body>  </html>  ') } 

Screen Shot:

HTML Special Characters

Hash Functions

The Page User Interface

#!ring -cgi Load "weblib.ring" Import System.Web New Page { boxstart() text( "Hash Test") newline() boxend() divstart([ :style = StyleFloatLeft() + StyleWidth("100px") ]) newline() text( "Value : " ) newline() newline() divend() formpost("ex16.ring") divstart([ :style = StyleFloatLeft() + StyleWidth("300px") ]) newline() textbox([ :name = "Value" ]) newline() newline() submit([ :value = "Send" ]) divend() formend() } 

Screen Shot:

Hash Functions

The Response

#!ring -cgi Load "weblib.ring" Import System.Web New Page { boxstart() text( "Hash Result" ) newline() boxend() divstart([ :style = styleFloatLeft() + styleWidth("100%") ]) newline() text( "Value : " + aPageVars["Value"] ) newline() text( "MD5 : " + MD5(aPageVars["Value"]) ) newline() text( "SHA1 : " + SHA1(aPageVars["Value"]) ) newline() text( "SHA256 : " + SHA256(aPageVars["Value"]) ) newline() text( "SHA224 : " + SHA224(aPageVars["Value"]) ) newline() text( "SHA384 : " + SHA384(aPageVars["Value"]) ) newline() text( "SHA512 : " + SHA512(aPageVars["Value"]) ) newline() divend() } 

Screen Shot:

Hash Functions

Random Image

#!ring -cgi Load "weblib.ring" Import System.Web cUploadPath = "C:/Apache2.2/htdocs/ringapp/upload/" New Page { boxstart() text( "Random Test") newline() boxend() divstart([ :style = styleFloatLeft() + styleWidth("400px") ]) newline() aList = dir(cUploadPath) if len(aList) > 0 nIndex = random(len(aList)) if nindex = 0 nIndex = 1 ok cItem = "upload/" + aList[nIndex][1] newline() image( [ :url = cItem , :alt = :image ] ) else text("No images!") newline() ok divend() } 

Screen Shot:

Random Image

HTML Lists

The next example print a list contains numbers from 1 to 10

Then print a list from Ring List.

Finally we have a list of buttons and when we press on a button we get a message contains the clicked button number.

To start the list we uses the ulstart() function.

To end the list we uses the ulend() function.

We uses listart() and liend() to determine the list item.

#!ring -cgi Load "weblib.ring" Import System.Web Func Main New Page { ulstart([]) for x = 1 to 10 listart([]) text(x) liend() next ulend() list2ul(["one","two","three","four","five"]) ulstart([]) for x = 1 to 10 listart([]) cFuncName = "btn"+x+"()" button([ :onclick = cFuncName , :value = x]) script(scriptfuncalert(cFuncName,string(x))) liend() next ulend() } 

Screen Shot:

HTML Lists

HTML Tables

In this example we will learn how to generate HTML tables using the tablestart(), tableend(), rowstart(), rowend() ,headerstart(), headerend(), cellstart() and cellend() functions.

#!ring -cgi Load "weblib.ring" Import System.Web Func Main New Page { divstart([ :style = styledivcenter("400px","500px") ] ) style(styletable() + styletablerows("t01")) tablestart([ :id = :t01 , :style = stylewidth("100%") ]) rowstart([]) headerstart([]) text("Number") headerend() headerstart([]) text("square") headerend() rowend() for x = 1 to 10 rowstart([]) cellstart([]) text(x) cellend() cellstart([]) text(x*x) cellend() rowend() next tableend() divend() } 

Screen Shot:

HTML Tables

Gradient

In this example we will learn how to use the StyleGradient() function.

The function takes the style number as input (range from 1 to 60).

#!ring -cgi Load "weblib.ring" Import System.Web Func Main New Page { boxstart() text("StyleGradient() Function") boxend() for x = 1 to 60 divstart([ :id = x , :align = "center" , :style = stylefloatleft() + stylesize(string(100/60*6)+"%","50px") + stylegradient(x) ]) h3(x) divend() next } 

Screen Shot:

Gradient

Generating Pages using Objects

Instead of using functions/methods to generate HTML pages, we can use an object for each element in the page.

This choice means more beautiful code but slower.

The fastest method is to print HTML code directly, then using functions then using templates then using objects (slower).

#!ring -cgi Load "weblib.ring" Import System.Web Func Main WebPage() { Title = "Using objects to create the Web Page content" h1 { text("welcome") } link { Title = "Google" Link = "http://www.google.com" } div { id = "div1" style = stylegradient(30) + stylesize("50%","50%") text("Outer Div") div { id = "div2" color = "white" backgroundcolor = "green" width = "50%" height = "50%" marginleft = "5%" margintop = "5%" text("Inner Div") } } div { id = "div3" color = "black" backgroundcolor = "silver" width = "100%" height = "100%" text("Form") form { method = "POST" Action = "helloworld.ring" Table { style = stylewidth("100%") + stylegradient(24) TR { TD { WIDTH="10%" text("Name : " ) } TD { Input { type = "text" } } } TR { TD { WIDTH="10%" text("Email : " ) } TD { Input { type = "text" } } } TR { TD { WIDTH="10%" text("Password : " ) } TD { Input { type = "password" } } } TR { TD { WIDTH="10%" text("Notes") } TD { TextArea { width="100%" rows = 10 cols = 10 text("type text here...") } } } TR { TD { WIDTH="10%" text("Gender") } TD { select { width = "100%" option { text("Male") } option { text("Female") } } } } TR { TD { WIDTH="10%" text("Role") } TD { select { multiple = "multiple" width = "100%" option { text("student") } option { text("admin") } } } } } Input { type = "submit" value = "send" } Image { src="upload/profile1.jpg" alt="profile"} Input { type = "checkbox" value = "Old Member"} text("old member") Input { type = "range" min=1 max=100} Input { type = "number" min=1 max=100} Input { type = "radio" color="black" name="one" value = "one"} text("one") } } div { color = "white" backgroundcolor = "blue" width = "100%" UL { LI { TEXT("ONE") } LI { TEXT("TWO") } LI { TEXT("THREE") } } } div { audio { src = "horse.ogg" type = "audio/ogg" } video { width = 320 height = 240 src = "movie.mp4" type = "video/mp4" } Input { type = "color" value = "#ff0000" onchange = "clickColor(0, -1, -1, 5)" } } } 

Screen Shot:

Using Objects Using Objects - part 2

HtmlPage Class

Using this class we can create HTML documents without printing the output to the standard output

So instead of using the WebLib in Web Applications only

We can use it in Console/GUI/Mobile Applications too

Example:

load "stdlib.ring" load "weblib.ring" import System.Web func main mypage = new HtmlPage { h1 { text("Customers Report") } Table { style = stylewidth("100%") + stylegradient(4) TR { TD { WIDTH="10%" text("Customers Count : " ) } TD { text (100) } } } Table { style = stylewidth("100%") + stylegradient(26) TR { style = stylewidth("100%") + stylegradient(24) TD { text("Name " ) } TD { text("Age" ) } TD { text("Country" ) } TD { text("Job" ) } TD { text("Company" ) } } for x = 1 to 100 TR { TD { text("Test" ) } TD { text("30" ) } TD { text("Egypt" ) } TD { text("Sales" ) } TD { text("Future" ) } } next } } write("report.html",mypage.output()) 

Using Bootstrap Library using Functions

The next example uses the Bootstrap JavaScript Library when generating the HTML page.

#!ring -cgi Load "weblib.ring" Import System.Web Func Main new BootstrapPage { divstart([ :class = "container" ]) divstart([ :class = "jumbotron" ]) h1("Bootstrap Page") divend() divstart([ :class = :row ]) divstart([ :class = "col-sm-4" ]) h3("Welcome to the Ring programming language") p([ :text = "Using a scripting language is very fun!" ]) divend() divstart([ :class = "col-sm-4" ]) h3("Welcome to the Ring programming language") p([ :text = "using a scripting language is very fun!" ]) divend() divstart([ :class = "col-sm-4" ]) h3("Welcome to the Ring programming language") p([ :text = "using a scripting language is very fun!" ]) divend() divend() divend() } 

Screen Shot:

Bootstrap

Using Bootstrap Library using Objects

The next example uses the Bootstrap JavaScript Library when generating the HTML page.

Instead of using functions to generate the HTML elements, we will use objects.

#!ring -cgi Load "weblib.ring" Import System.Web Func Main BootStrapWebPage() { div { classname = :container div { classname = :jumbotron H1 { text("Bootstrap Page") } } div { classname = :row for x = 1 to 3 div { classname = "col-sm-4" H3 { html("Welcome to the Ring programming language") } P { html("Using a scripting language is very fun!") } } next } div { classname = :row div { classname = "col-sm-4" Button { classname = "btn btn-info btn-lg" datatoggle= "modal" datatarget = "#myModal" text("Open Large Modal") } } div { classname = "col-sm-4" Button { classname = "btn btn-default btn-lg" text("default") } Button { classname = "btn btn-primary btn-md" text("primary") } Button { classname = "btn btn-success btn-sm" text("success") } Button { classname = "btn btn-info btn-xs" text("info") } Button { classname = "btn btn-warning" text("warning") } Button { classname = "btn btn-danger" text("danger") } Button { classname = "btn btn-link" text("link") } } div { classname = "col-sm-4" Button { classname = "btn btn-default btn-block" text("default") } Button { classname = "btn btn-primary btn-block" text("primary") } Button { classname = "btn btn-success btn-block" text("success") } Button { classname = "btn btn-info btn-block" text("info") } Button { classname = "btn btn-warning btn-block" text("warning") } Button { classname = "btn btn-danger btn-block" text("danger") } Button { classname = "btn btn-link btn-block" text("link") } } div { classname = "col-sm-4" div { classname = "btn-group" button { classname="btn btn-primary" text("one") } button { classname="btn btn-primary" text("two") } button { classname="btn btn-primary" text("three") } } } div { classname = "col-sm-4" div { classname = "btn-group btn-group-lg" button { classname="btn btn-primary" text("one") } button { classname="btn btn-primary" text("two") } button { classname="btn btn-primary" text("three") } } } div { classname = "col-sm-4" div { classname = "btn-group-vertical btn-group-lg" button { classname="btn btn-primary" text("one") } button { classname="btn btn-primary" text("two") } button { classname="btn btn-primary" text("three") } } } } div { classname="modal fade" id="myModal" role="dialog" div { classname = "modal-dialog modal-lg" div { classname="modal-content" div { classname="modal-header" button { classname="close" datadismiss="modal" html("&times") } h4 { classname="modal-title" text("Modal Header") } } div { classname = "modal-body" p { text("This is a large model.") } } div { classname="modal-footer" button { classname = "btn btn-default" datadismiss="modal" text("close") } } } } } } } 

Screen Shot:

Bootstrap Page using Objects

CRUD Example using MVC

The next example uses the weblib.ring & datalib.ring.

The datalib.ring contains classes for creating database applications using MVC pattern.

In this example we create an object from the SalaryController class then call the Routing method.

We define the website variable to contains the basic url of the page.

When we create the SalaryModel class from the ModelBase class, the salary table will be opened and the columns data will be defined as attributes in the model class.

The SalaryView class create an object from the SalaryLanguageEnglish class to be used for translation.

The method AddFuncScript is used to call the form for adding/modifying record data.

The method FormViewContent is used to determine the controls in the form when we add or modify a record.

#!ring -cgi Load "weblib.ring" Load "datalib.ring" Import System.Web website = "ex24.ring" New SalaryController { Routing() } Class SalaryModel from ModelBase Class SalaryController From ControllerBase Class SalaryView From ViewBase oLanguage = new SalaryLanguageEnglish Func AddFuncScript oPage,oController return oPage.scriptfuncajax("myadd",oController.cMainURL+ oController.cOperation+"=add","mysubpage") Func FormViewContent oController,oTranslation,oPage return [ [ oTranslation.aColumnsTitles[2], "textbox", "name", oController.oModel.Name, oPage.stylewidth("100%") ], [ oTranslation.aColumnsTitles[3], "textbox", "salary", oController.oModel.Salary, oPage.stylewidth("50%") ] ] Class SalaryLanguageEnglish cTitle = "Salary Table" cBack = "back" aColumnsTitles = ["ID","Name","Salary"] cOptions = "Options" cSearch = "Search" comboitems = ["Select Option...","Edit","Delete"] cAddRecord = "Add Record" cEditRecord = "Edit Record" cRecordDeleted = "Record Deleted!" aMovePages = ["First","Prev","Next","Last"] cPage = "Page" cOf = "of" cRecordsCount = "Records Count" cSave = "Save" temp = new page cTextAlign = temp.StyleTextRight() cNoRecords = "No records!" 

Screen Shot:

Salary Table Salary Table - Search

Users registration and Login

We have the users classes (Model, View & Controller) to deal with the users data like username & email.

The next code is stored in ex25_users.ring

Class UsersModel from ModelBase cSearchColumn = "username" Class UsersController From ControllerBase aColumnsNames = ["id","username","email"] Func UpdateRecord oModel.id = aPageVars[cRecID] oModel.updatecolumn("username", aPageVars[:username] ) oModel.updatecolumn("email", aPageVars[:email] ) oView.UpdateView(self) Class UsersView from ViewBase oLanguage = new UsersLanguageEnglish Func AddFuncScript oPage,oController return oPage.scriptfunc("myadd",oPage.scriptredirection("ex26.ring")) Func FormViewContent oController,oTranslation,oPage return [ [oTranslation.aColumnsTitles[2],"textbox","username", oController.oModel.UserName,oPage.stylewidth("100%")], [oTranslation.aColumnsTitles[3],"textbox","email", oController.oModel.Email,oPage.stylewidth("50%")] ] Class UsersLanguageEnglish cTitle = "Users Table" cBack = "back" aColumnsTitles = ["ID","User Name","Email"] cOptions = "Options" cSearch = "Search" comboitems = ["Select Option...","Edit","Delete"] cAddRecord = "Add Record" cEditRecord = "Edit Record" cRecordDeleted = "Record Deleted!" aMovePages = ["First","Prev","Next","Last"] cPage = "Page" cOf = "of" cRecordsCount = "Records Count" cSave = "Save" temp = new page cTextAlign = temp.StyleTextRight() cNoRecords = "No records!" 

In the file ex25.ring we load ex25_users.ring then create an object from UsersController class.

Using the created object, we call the routing method.

#!ring -cgi Load "weblib.ring" Load "datalib.ring" Load "ex25_users.ring" Import System.Web website = "ex25.ring" New UsersController { Routing() } 

Screen Shot:

Users Table

See the next code for the registration page

#!ring -cgi Load "weblib.ring" Load "datalib.ring" Import System.Web website = "ex26.ring" new page { boxstart() text( "Register") newline() boxend() divstart([:style = stylegradient(6) + stylesize("100%","95%") ]) link([ :url = website, :title = "back" , :style = stylecolor("white")]) newline() divstart([ :style= styledivcenter("500","160") + stylegradient(52) ]) formpost("ex27.ring") tablestart([ :Style = stylemarginleft("2%") + stylemargintop("2%") + stylewidth("90%") ]) rowstart([]) cellstart([:style = stylewidth("20%") + styleheight(30)]) text("User Name") cellend() cellstart([ :style = stylewidth("80%") ]) textbox([:name = "username", :style = stylewidth("100%")]) cellend() rowend() rowstart([]) cellstart([ :Style = styleheight(30)]) text("Password") cellend() cellstart([]) textbox([:name = "password" , :type = "password"]) cellend() rowend() rowstart([]) cellstart([ :style = styleheight(30)]) text("Email") cellend() cellstart([]) textbox([:name = "email" , :style = stylewidth("100%")]) cellend() rowend() rowstart([]) cellstart([ :style = styleheight(30)]) cellend() cellstart([ :style = styleheight(30)]) submit([:value = "Register" ]) cellend() rowend() tableend() formend() divend() divend() } 

Screen Shot:

Registration Page

The Registration response

#!ring -cgi Load "weblib.ring" Load "datalib.ring" Load "ex25_users.ring" Import System.Web oUser = new UsersModel oUser.Connect() if oUser.findwith("username",aPageVars["username"]) new page { text("The user name is already registered") } return ok if oUser.findwith("email",aPageVars["email"]) new page { text("This email is already registered") } return ok aPageVars["salt"] = str2hex(RandBytes(32)) aPageVars["pwhash"] = sha256(aPagevars["password"]+aPageVars["salt"]) aPageVars["sessionid"] = str2hex(randbytes(32)) oUser.Insert() new page { cookie("sessionid",aPageVars["sessionid"]) text("New User Created!") newline() text("User Name : " + aPageVars["username"]) newline() } oUser.Disconnect() 

See the next code for the Login page

#!ring -cgi Load "weblib.ring" Load "datalib.ring" Import System.Web website = "ex28.ring" new page { boxstart() text( "Login") newline() boxend() divstart([:style = stylegradient(6) + stylesize("100%","95%") ]) link([ :url = website, :title = "back" , :style = stylecolor("white")]) newline() divstart([ :style= styledivcenter("500","130") + stylegradient(52) ]) formpost("ex29.ring") tablestart([ :Style = stylemarginleft("2%") + stylemargintop("2%") + stylewidth("90%") ]) rowstart([]) cellstart([:style = stylewidth("20%") + styleheight(30)]) text("User Name") cellend() cellstart([ :style = stylewidth("80%") ]) textbox([:name = "username", :style = stylewidth("100%")]) cellend() rowend() rowstart([]) cellstart([ :style = styleheight(30)]) text("Password") cellend() cellstart([]) textbox([:name = "password" , :type = "password"]) cellend() rowend() rowstart([]) cellstart([ :style = styleheight(30) ]) cellend() cellstart([]) submit([:value = "Login" ]) cellend() rowend() tableend() formend() divend() divend() } 

Screen Shot:

Login Page

The response page

#!ring -cgi Load "weblib.ring" Load "datalib.ring" Load "ex25_users.ring" Import System.Web oUser = new UsersModel oUser.Connect() lResult = oUser.FindWith("username",aPageVars["username"]) new page { if lResult if sha256(aPagevars["password"]+oUser.Salt) = oUser.pwhash text ("Correct Password!") aPageVars["sessionid"] = str2hex(randbytes(32)) oUser.UpdateColumn("sessionid",aPageVars["sessionid"]) cookie("sessionid",aPageVars["sessionid"]) else text ("Bad password!") ok else text("Bad User Name!") ok } oUser.Disconnect() 

The next code for checking if the user needs to login or not

#!ring -cgi Load "weblib.ring" Load "datalib.ring" Load "ex25_users.ring" Import System.Web oUser = new UsersModel oUser.Connect() lResult = oUser.FindWith("sessionid",aPageVars["sessionid"]) new page { if lResult text("User Name : " + oUser.username ) else text("Please Login First!") ok } oUser.Disconnect() 

Database, ModelBase & ControllerBase classes

In this section we will see some code from datalib.ring

The next code presents the Database, ModelBase & ControllerBase classes

Import System.Web Class Database cServer = "localhost" cUserName = "root" cPassword = "root" cDatabase = "mahdb" Func Connect con = mysql_init() mysql_connect(con, cServer, cUserName, cPassWord,cDatabase) Func Disconnect mysql_close(con) Func Query cQuery mysql_query(con,cQuery) Func QueryResult return mysql_result(con) Func QueryResultWithColumns # return columns names + query result return mysql_result2(con) Func QueryValue aResult = mysql_result(con) if islist(aResult) and len(aResult) >= 1 aResult = aResult[1] if len(aResult) >= 1 return aResult[1] ok ok return 0 Func EscapeString x if isstring(x) return MySQL_Escape_String(con,x) else return MySQL_Escape_String(con,string(x)) ok Private con = NULL Class ModelBase from Database cTableName = "" cSearchColumn = "name" aColumns = [] aQueryResult = [] ID = 0 # set table name from class name classname = lower(classname(self)) if right(classname,5) = :model cTablename = left(classname,len(classname)-5) ok Func Insert cValues = "" for x in aColumns cValues += "'" + EscapeString(aPageVars[x]) + "'," Next cValues = left(cValues,len(cValues)-1) # remove last comma cColumns = "" for x in aColumns cColumns += x + "," next cColumns = left(cColumns,len(cColumns)-1) query("insert into " + cTableName + "("+cColumns+") values (" + cValues + ")" ) Func Update nID cStr = "" for x in aColumns cStr += x + " = '" + EscapeString(aPageVars[x]) + "' , " # the space after comma is necessary Next cStr = left(cStr,len(cStr)-2) query("update " + cTableName + " set " + cStr + " where id = " + nID ) Func UpdateColumn cColumn,cValue query("update " + cTableName + " set " + cColumn + " = '" + EscapeString(cValue) + "' where id = " + self.ID ) Func Count cValue query("SELECT count(*) FROM " + cTableName + " where "+cSearchColumn+" like '" + EscapeString(cValue) + "%'") return queryValue() Func Read nStart,nRecordsPerPage query("SELECT * FROM "+ cTableName+" limit " + EscapeString(nStart) + "," + EscapeString(nRecordsPerPage) ) aQueryResult = queryResult() Func Search cValue,nStart,nRecordsPerPage query("SELECT * FROM "+ cTableName+" where "+cSearchColumn+" like '" + EscapeString(cValue) + "%'" + " limit " + EscapeString(nStart) + "," + EscapeString(nRecordsPerPage) ) aQueryResult = queryResult() Func Find nID query("select * from " + cTableName + " where id = " + EscapeString(nID) ) aResult = queryResult()[1] # move the result from the array to the object attributes ID = nID cCode = "" for x = 2 to len(aResult) cCode += aColumns[x-1] + " = hex2str('" + str2hex(aResult[x]) + "')" + nl next eval(cCode) Func FindWith cColumn,cValue query("select * from " + cTableName + " where "+cColumn+" = '" + EscapeString(cValue) + "'" ) aResult = queryResult() if len(aResult) > 0 aResult = aResult[1] else return 0 ok # move the result from the array to the object attributes ID = aResult[1] cCode = "" for x = 2 to len(aResult) cCode += aColumns[x-1] + " = hex2str('" + str2hex(aResult[x]) + "')" + nl next eval(cCode) return 1 Func Delete ID query("delete from " + cTableName + " where id = " + EscapeString(ID) ) Func Clear cCode = "" for x in aColumns cCode += x + ' = ""' + nl next eval(cCode) Func LoadModel # create the columns array query("SELECT * FROM "+ cTableName + " limit 0,1") aQueryResult = QueryResultWithColumns()[1] for x = 2 to len(aQueryResult) aColumns + lower(trim(aQueryResult[x])) next # create attribute for each column for x in aColumns addattribute(self,x) next Func Connect Super.Connect() if nLoadModel = 0 nLoadModel = 1 LoadModel() ok private nLoadModel = 0 Class ControllerBase nRecordsPerPage = 5 nRecordsCount = 0 nPagesCount = 0 nActivePage = 0 # Dynamic creation of oView = new tablenameView and oModel = new tablename.Model classname = lower(classname(self)) if right(classname,10) = :controller tablename = left(classname,len(classname)-10) cCode = "oView = new " + tablename+"View" + nl cCode += "oModel = new " + tablename+"Model" + nl eval(cCode) oModel.connect() ok cSearchName = "searchname" cPart = "part" cPageError = "The page number is not correct" cLast = "last" cOperation = "operation" cRecID = "recid" aColumnsNames = ["id"] for t in oModel.aColumns aColumnsNames + t next cMainURL = website + "?" func Routing switch aPageVars[cOperation] on NULL showtable() on :add addrecord() on :save saverecord() on :delete deleterecord() on :edit editrecord() on :update updaterecord() off func ShowTable nRecordsCount = oModel.Count( aPageVars[cSearchName] ) nPagesCount = ceil(nRecordsCount / nRecordsPerPage) if aPageVars[cPart] = cLast aPageVars[cPart] = string(nPagesCount) ok nActivePage = number(aPageVars[cPart]) if nActivePage = 0 nActivePage = 1 ok if ( nActivePage > nPagesCount ) and nRecordsCount > 0 ErrorMsg(cPageError) return ok nStart = (nActivePage-1)*nRecordsPerPage if aPageVars[cSearchName] = NULL oModel.Read( nStart,nRecordsPerPage ) else oModel.Search( aPageVars[cSearchName],nStart,nRecordsPerPage ) ok oView.GridView(self) func AddRecord oModel.clear() oView.FormViewAdd(Self,:save,false) # false mean don't include record id func SaveRecord oModel.Insert() oView.SaveView(self) func EditRecord oModel.Find( aPageVars[cRecID] ) oView.FormViewEdit(Self,:update,true) # true mean include record id func UpdateRecord oModel.update( aPageVars[cRecID] ) oView.UpdateView(self) func DeleteRecord oModel.Delete( aPageVars[cRecID] ) oView.DeleteView() func braceend oModel.Disconnect() 

WebLib API

In this section we will see the web library functions, classes and methods.

Function

Parameters

Description

LoadVars

None

Save the request parameters and cookies to aPageVars List

WebPage

None

Create new object from the WebPage Class

BootStrapWebPage

None

Create new object from the BootStrapWebPage Class

HTMLSpecialChars

cString

Encode Special characters to HTML equivalent

Template

cFile,oObject

Execute Ring Code in cFile after accessing oObject using {}

Alert

cMessage

Generate HTML Web Page that display cMessage using JavaScript Alert()

HTML2PDF

cString

Generate and Display PDF File from HTML String (cString)

The Package System.Web contains the next classes

Class Name

Description

Application

Contains methods for Encoding, Decoding, Cookies & More.

Page

Contains methods to generate HTML pages.

ScriptFunctions

Contains methods to generate some JavaScript Functions.

StyleFunctions

Contains methods to generate CSS.

PageBuffer

Generate HTML Page in memory (don’t print the output).

HTML2PDF

Generate PDF File from HTML code.

BootStrapPage

Using BootStrap Library.

WebPage

Generate page using objects for each element.

HtmlPage

Like WebPage but doesn’t print the output to stdout.

BootStrapWebPage

Generate page using objects, using BootStrap Library.

ObjsBase

Parent Class for page objects.

NewObjectsFunctions

Methods to create new objects in the page or element.

H1

Wraps HTML H1.

H2

Wraps HTML H2.

H3

Wraps HTML H3.

H4

Wraps HTML H4.

H5

Wraps HTML H5.

H6

Wraps HTML H6.

P

Wraps HTML P.

Link

Wraps HTML link.

NewLine

Wraps HTML NewLine.

Div

Wraps HTML Div.

Form

Wraps HTML Form.

Input

Wraps HTML Input.

TextArea

Wraps HTML TextArea.

Select

Wraps HTML Select.

Option

Wraps HTML Option.

Image

Wraps HTML Image.

UL

Wraps HTML UL.

LI

Wraps HTML LI.

Table

Wraps HTML Table.

TR

Wraps HTML TR.

TD

Wraps HTML TD.

TH

Wraps HTML TH.

Audio

Wraps HTML Audio.

Video

Wraps HTML Video.

Nav

Wraps HTML Nav.

Span

Wraps HTML Span.

Button

Wraps HTML Button.

Application Class

Method

Parameters

Description

DecodeString

cString

Decode request parameters

Decode

cString

Decode multipart/form-data

GetFileName

aArray,cVar

Get File Name in aArray using cVar

SetCookie

name,value,expires,path,domain,secure

Set Cookie

Cookie

name,value

Set Cookie using name and value only

GetCookies

None

Get Cookies

URLEncode

cString

URL Encode

ScriptLibs

None

Add JavaScript Libraries like BootStrap

Print

None

Print Page Content

Style

cStyle

Add cStyle to page CSS content

StartHTML

None

Add HTTP Header to page content

Redirect

cLocation

Will redirect the webpage

NoJavaScript

None

Avoid JavaScript links

The method DecodeString is used to get HTTP request parameters.

The methods Decode and GetFileName are used for uploading files.

The methods SetCookie, Cookie & GetCookies are used for adding and reading cookies.

The methods StartHTML, ScriptsLibs, Style & Print are used for page structure and JS/CSS support.

The method URLEncode is used to encode a URL to be used in HTML pages.

Page Class

Method

Parameters

Description

text

x

add HTMLSpecialChars(x) to page content (accept strings and numbers)

html

cString

add html code to page content

h1

x

add x to page content between <h1> and </h1>

h2

x

add x to page content between <h2> and </h2>

h3

x

add x to page content between <h3> and </h3>

h4

x

add x to page content between <h4> and </h4>

h5

x

add x to page content between <h5> and </h5>

h6

x

add x to page content between <h6> and </h6>

p

aPara

HTML <p> </p>, uses aPara List as Hash to get attributes

NewLine

None

add <br /> to page content

AddAttributes

aPara

Convert aPara list as hash to HTML element attributes

Link

aPara

HTML <a href> and </a>, uses aPara List as Hash to get attributes

Image

aPara

HTML <img>, uses aPara List as Hash to get attributes

Button

aPara

HTML <input type=”button”>, uses aPara List as Hash to get attributes

ButtonLink

aPara

HTML <input type=”button”>, uses link attribute to navigate to link

Textbox

aPara

HTML <input type=”text”>, uses aPara List as Hash to get attributes

Editbox

aPara

HTML <textarea> and </textarea>, uses aPara to get attributes

Combobox

aPara

HTML <select>, uses items attribute as list for <option>

Listbox

aPara

HTML <select multiple=’multiple’>, uses items attribute for <option>

ulstart

aPara

HTML <ul>

ulend

aPara

HTML </ul>

listart

aPara

HTML <li>

liend

aPara

HTML </li>

List2UL

aList

Generate HTML <ul> including items from Ring List items

DivStart

aPara

HTML <div>, uses aPara List as Hash to get attributes

NavStart

aPara

HTML <nav>, uses aPara List as Hash to get attributes

SpanStart

aPara

HTML <span>, uses aPara List as Hash to get attributes

BoxStart

None

Generate Div with black background to be used as page header

DivEnd

None

HTML </div>

NavEnd

None

HTML </nav>

SpanEnd

None

HTML </span>

BoxEnd

None

HTML </div>, the same as divend()

FormStart

cAction

HTML <form>, with cAction as the action attribute or an empty value

FormPost

cAction

HTML <form method=”post”> , with cAction as the action attribute

FormEnd

None

HTML </form>

Submit

aPara

HTML <input type=”submit”>

Hidden

cName,cValue

HTML <input type=”hidden”>

FormUpload

x

HTML Form, method=”post” enctype=”multipart/form-data” and x = action

UploadFile

x

HTML <input type=”file”> and name = x

Video

aPara

HTML <video>

Audio

aPara

HTML <audio>

GetColor

aPara

Select Color

Radio

aPara

HTML <input type=”radio”>

Checkbox

aPara

HTML <input type=”checkbox”>

Spinner

aPara

HTML <input type=”number”>

Slider

aPara

HTML <input type=”range”>

TableStart

aPara

HTML <table>

TableEnd

None

HTML </table>

RowStart

aPara

HTML <tr>

RowEnd

None

HTML </tr>

CellStart

aPara

HTML <td>

CellEnd

None

HTML </td>

HeaderStart

aPara

HTML <th>

HeaderEnd

None

HTML </th>

theadStart

aPara

HTML <thead>

theadEnd

None

HTML </thead>

tbodyStart

aPara

HTML <tbody>

tbodyEnd

None

HTML </tbody>

tfootStart

aPara

HTML <tfoot>

tfootEnd

None

HTML </tfoot>

aPara in the page methods is a list contains attributes and values. Using aPara we can set values for the next attributes

classname id name align style dir value onclick oncontextmenu ondblclick onmousedown onmouseenter onmouseleave onmousemove onmouseover onmouseout onmouseup onkeydown onkeypress onkeyup onabort onbeforeunload onerror onhashchange onload onpageshow onpagehide onresize onscroll onunload onblur onchange onfocus onfocusin onfocusout oninput oninvalid onreset onsearch onselect onsubmit ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop oncopy oncut onpaste onafterprint onbeforeprint oncanplay oncanplaythrough ondurationchange onemptied onended onloadeddata onloadedmetadata onloadstart onpause onplay onplaying onprogress onratechange onseeked onseeking onstalled onsuspend ontimeupdate onvolumechange onwaiting animationend animationiteration animationstart transitionend onmessage onopen onmousewheel ononline onoffline onpostate onshow onstorage ontoggle onwheel ontouchcancel ontouchend ontouchmove ontouchstart color opacity background backgroundattachment backgroundcolor backgroundimage backgroundposition backgroundrepeat backgroundclip backgroundorigin backgroundsize border borderbottom borderbottomcolor borderbottomleftradius borderbottomrightradius borderbottomstyle borderbottomwidth bordercolor borderimage borderimageoutset borderimagerepeat borderimageslice borderimagesource borderimagewidth borderleft borderleftcolor borderleftstyle borderleftwidth borderradius borderright borderrightcolor borderrightstyle borderrightwidth borderstyle bordertop bordertopcolor bordertopleftradius bordertoprightradius bordertopstyle bordertopwidth borderwidth boxdecorationbreak boxshadow bottom clear clip display float height left margin marginbottom marginleft marginright margintop maxheight maxwidth minheight minwidth overflow overflowx overflowy padding paddingbottom paddingleft paddingright paddingtop position right top visibility width verticalalign zindex aligncontent alignitems alignself flex flexbasis flexdirection flexflow flexgrow flexshrink flexwrap justifycontent order hangingpunctuation hyphens letterspacing linebreak lineheight overflowwrap tabsize textalign textalignlast textcombineupright textindent textjustify texttransform whitespace wordbreak wordspacing wordwrap textdecoration textdecorationcolor textdecorationline textdecorationstyle textshadow textunderlineposition @fontface @fontfeaturevalues font fontfamily fontfeaturesettings fontkerning fontlanguageoverride fontsize fontsizeadjust fontstretch fontstyle fontsynthesis fontvariant fontvariantalternates fontvariantcaps fontvarianteastasian fontvariantligatures fontvariantnumeric fontvariantposition fontweight direction textorientation unicodebidi writingmode bordercollapse borderspacing captionside emptycells tablelayout counterincrement counterreset liststyle liststyleimage liststyleposition liststyletype @keyframes animation animationdelay animationdirection animationduration animationfillmode animationiterationcount animationname animationplaystate animationtimingfunction backfacevisibility perspective perspectiveorigin transform transformorigin transformstyle transition transitionproperty transitionduration transitiontimingfunction transitiondelay boxsizing content cursor imemode navdown navindex navleft navright navup outline outlinecolor outlineoffset outlinestyle outlinewidth resize textoverflow breakafter breakbefore breakinside columncount columnfill columngap columnrule columnrulecolor columnrulestyle columnrulewidth columnspan columnwidth columns widows orphans pagebreakafter pagebreakbefore pagebreakinside marks quotes filter imageorientation imagerendering imageresolution objectfit objectposition mask masktype mark markafter markbefore phonemes rest restafter restbefore voicebalance voiceduration voicepitch voicepitchrange voicerate voicestress voicevolume marqueedirection marqueeplaycount marqueespeed marqueestyle datatoggle dataride datatarget dataslideto dataslide datadismiss dataplacement datacontent datatrigger dataspy dataoffset dataoffsettop 

ScriptFunctions Class

This class contains methods for adding JavaScript code to the generated web page.

The class methods are merged to the Page class, so we can use the next methods with page objects directly.

Method

Parameters

Description

Script

cCode

Add cCode string between <script> and </script>

ScriptRedirection

cURL

set window.location to cURL

ScriptFunc

cFuncName,cCode

Define function cFuncName that contains cCode

ScriptFuncAlert

cFuncName,cMsg

Define function cFuncName that uses alert() to print cMsg

ScriptFuncAjax

cFuncName,cLink,cDiv

Define function cFuncName that load cLink in cDiv

ScriptFuncClean

cFuncName,cDiv

Define function cFuncName that clear the cDiv

ScriptFuncSelect

cF,aL,cD,cR,cGR,cFC,nTO,cL1,cL2

Used to Edit/Delete Grid Record

ScriptScrollFixed

cDiv,nSize

Set cDiv as Fixed Div with Size = nSize

StyleFunctions Class

This class contains methods for adding CSS to the generated web page.

Like ScriptFunctions Class, The StyleFunctions class methods are merged to the Page class, so we can use the next methods with page objects directly.

Method

Parameters

Description

StyleFloatLeft

None

Return float: left ;

StyleFloatRight

None

Return float: right ;

StyleSizeFull

None

Return width: 100% ; height: 100% ;

Stylecolor

x

Return ” color: ” + x + ” ; “

Stylebackcolor

x

Return ” background-color: ” + x + ” ;”

StyleTextCenter

None

Return “text-align: center ;”

StyleTextRight

None

Return “text-align: right ;”

StyleTextLeft

None

Return “text-align: left ;”

StyleSize

x,y

Return ” width: ” + x + ” ; height: ” + y + ” ;”

StyleWidth

x

Return ” width: ” + x + ” ;”

StyleHeight

x

Return ” height: ” + x + ” ;”

StyleTop

x

Return ” top: ” + x + ” ;”

StyleLeft

x

Return ” Left: ” + x + ” ;”

StylePos

x,y

Return ” top: ” + x + ” ;” + ” Left: ” + y + ” ;”

StyleHorizontalCenter

None

Return ” margin-right:auto ; margin-left:auto; “

StyleMarginTop

x

Return ” margin-top: ” + x + ” ;”

StyleMarginRight

x

Return ” margin-right: ” + x + ” ;”

StyleMarginLeft

x

Return ” margin-left: ” + x + ” ;”

StyleDivCenter

nWidth,nHeight

Create Div in the center of the page

StyleAbsolute

None

Return ” position:absolute ;”

StyleFixed

None

Return ” position:fixed ;”

StyleZIndex

x

Return ” z-index: ” + x + ” ;”

StyleFontSize

x

Return ” font-size: ” + x + ” ;”

StyleGradient

x

Generate Gradient (x values from 1 to 60)

StyleTable

None

Set table properties

StyleTableRows

id

Set different color to even and odd rows in the table

StyleTableNoBorder

None

Return ” border-style: none;”

WebPage Class

We use braces to access the active WebPage object attributes

Each one of these attribute will return a new object to access again using braces.

Attribute

Description

H1

Wraps HTML H1.

H2

Wraps HTML H2.

H3

Wraps HTML H3.

H4

Wraps HTML H4.

H5

Wraps HTML H5.

H6

Wraps HTML H6.

P

Wraps HTML P.

Link

Wraps HTML link.

NewLine

Wraps HTML NewLine.

Div

Wraps HTML Div.

Form

Wraps HTML Form.

Input

Wraps HTML Input.

TextArea

Wraps HTML TextArea.

Select

Wraps HTML Select.

Option

Wraps HTML Option.

Image

Wraps HTML Image.

UL

Wraps HTML UL.

LI

Wraps HTML LI.

Table

Wraps HTML Table.

TR

Wraps HTML TR.

TD

Wraps HTML TD.

TH

Wraps HTML TH.

Audio

Wraps HTML Audio.

Video

Wraps HTML Video.

Nav

Wraps HTML Nav.

Span

Wraps HTML Span.

Button

Wraps HTML Button.

THead

Wraps HTML THEAD.

TBody

Wraps HTML TBODY.

TFoot

Wraps HTML TFOOT.

HtmlPage Class

The same as the WebPage class with the next changes

  1. No output to the stdout

  2. Provide the Output Method to get the output

Syntax:

output() ---> The output as string