A Golang Wiki Page Tutorial Web Application
This Application takes a Go leaner through the process of building a web application using package net/http and html/template from Go standard library.
This is a stepping coding instructor to a tutorial article by golang.org. Each tagged commit is a separate teaching towards a very simple web app.
- Creating a data structure with load and save methods
- Using the
net/httppackage to build web applications - Using the
html/templatepackage to process HTML templates - Using the
regexppackage to validate user input - Using closures
- A good place to learn about setting up git is here.
- You can find documentation and download git here.
- Get Go.
- Learn how to set up Go development.
- Understanding of basic web technologies (HTTP, HTML)
- Basic UNIX/DOS command-line knowledge
You can check out any point of the tutorial using:
$ git checkout step-?
To see the changes made between any two lessons use the git diff command:
$ git diff step-?..step-?
- Create a gowiki.go file.
- Add the
Page struct. - Add the
saveandloadPagefunction. - Write the
mainfunction to test what we've written.
- Modify the
loadPageto let it return an error ifReadFileencounters one.
You can compile and run the program like this:
$ go build gowiki.go
$ ./gowiki
This is a sample page.
- Use
net/httppackage to serve our wiki pages. - Add the
viewHandlerto handle URLs. - create some page data like test.txt
Let's compile, run our code and visit http://localhost:8080/view/test to see what we have by far.
- Add the
editHandler.
Now we have an editing page http://localhost:8080/edit/test.
As you might have noticed, we comment out the registration of saveHandler in main. We will come back on that later.
- Use
html/templateto keep the HTML in a separate file. - Keep hard-coded HTMLs in separate files.
In this step, we will not be adding any new functionality to our application. Instead, we are going to take a step back, refactor our codebase and fix a potential issue.
- Move all templating code to its own function.
- Handle non-existent pages in
viewHandler.
Recompile the code, run and visit http://localhost:8080/view/APageThatDoesntExist
- Implement the
saveHandlerand uncommenting the related line inmain.
- Handle errors in
renderTemplate. - Handle errors in
saveTemplate.
- Refactor to call
ParseFilesonce at program initialization, parsing all templates into a single*Template. - Create the global variable named
templates, and initialize it withParseFiles. - Modify the
renderTemplatefunction to call thetemplates.ExecuteTemplatemethod with the name of the appropriate template.
- Use
regexppackage and create the global variablevalidPathto store our validation expression. - Add the function
getTitlethat uses thevalidPathexpression to validate path and extract the page title. - Put a call to
getTitlein each of the handlers.
- Re-write the function definition of each of the handlers to accept a title string.
- Define the wrapper function that takes a function of the above type, and returns a function of type
http.HandlerFunc. - Wrap the handler functions with
makeHandlerinmain. - Remove the calls to
getTitlefrom the handler functions, making them much simpler.
Now we have finished our little wiki page application. Recompile the code, and run the app:
$ go build gowiki.go
$ ./gowiki
Visiting http://localhost:8080/view/ANewPage should present you with the page edit form. You should then be able to enter some text, click 'Save', and be redirected to the newly created page.
In the article there are some simple tasks left for readers:
- Store templates in
tmpl/and page data indata/. - Add a handler to make the web root redirect to
/view/FrontPage. - Spruce up the page templates by making them valid HTML and adding some CSS rules.
- Implement inter-page linking by converting instances of
[PageName]to<a href="/view/PageName">PageName</a>. (hint: you could useregexp.ReplaceAllFuncto do this)
And we will continue Go with these extra tasks.
- Store templates in
tmpl/and page data indata/. - Change file directory in
save(),loadPage()andtemplates.