Handling HTML Form Data

Create a basic form that uses HTTP POST to display user-submitted content on an HTML template.

This page and sample are part of an extended learning example of a simple blog application where users can upload posts. You should already be familiar with the Go programming language and basic web development. To start from the beginning, go to Building an App with Go.

Costs

There are no costs associated with running this tutorial. Running this sample app alone does not exceed your free quota.

Before you begin

If you started from Building an App with Go, skip this section; otherwise, complete the following steps:

  1. Complete the tasks in Before you begin in Setting Up Your Project and Application.

  2. In this example, you add code to the gophers-2 sample, which is the final product from Serving Static Files.

    Download the gophers-2 sample and its dependencies to your local machine:

    go get -u -d github.com/GoogleCloudPlatform/golang-samples/appengine/gophers/gophers-2/...
    
  3. Change to the gophers-2 directory:

    cd $GOPATH/src/github.com/GoogleCloudPlatform/golang-samples/appengine/gophers/gophers-2
    

Structuring your application

This sample project has the following structure:

  • go-app/: Project root directory.

    • app.yaml: Configuration settings for your App Engine application.
    • main.go: Your application code.
    • index.html: HTML template to display your homepage.
    • static/: Directory to store your static files.
      • style.css: Stylesheet that formats the look of your HTML file.
      • gcp-gopher.svg: Gopher image.

Creating a form on an HTML template

You should use a templating system when HTML embedded in code is difficult to maintain. A string or file containing portions enclosed in double braces, {{...}}, produces dynamic HTML. Dynamic HTML is content that changes as a result of your application’s operations.

  1. In index.html, under the title and picture, create a section to give submission feedback to the user and a form with a name and message input field:

    {{with .Notice}}<div id="notice">{{.}}</div>{{end}}
    
    <form action="/" method="post">
      <div>Name: <input name="name" value="{{.Name}}"></div>
      <div>Message: <input name="message"></div>
      <input type="submit">
    </form>

    When the user submits the form, the POST request updates the dynamic HTML to generate a notice for the user's submission.

  2. The code sample, gophers-2, is the result of the steps described in Serving Static Files, but in this page you are changing this to make index.html dynamic, not static. So delete the following lines from app.yaml:

    - url: /
      static_files: index.html
      upload: index.html
    

Integrating HTML templates

Using Go’s html/template package, parse through index.html and associate it as a template.

  1. Add packages html/template and fmt to your list of imports in main.go:

    "fmt"
    "html/template"

    In the fmt package, you use the Sprintf function to return a message with the user's name in it.

  2. Initialize your template variable in main.go:

    var (
    	indexTemplate = template.Must(template.ParseFiles("index.html"))
    )
    

    The template.Must() function wraps around another function that returns a pointer to a template and an error.

  3. Define your template parameters as a data structure with two fields, Notice and Name in main.go:

    type templateParams struct {
    	Notice string
    	Name   string
    }
    

Handling form data

When the page is first loaded, a GET request is sent. When the user submits content, the page reloads and sends a POST request. The POST request handles the form submission and updates the template variables, as shown in the code below.

In main.go, add the following lines to your indexHandler function:

params := templateParams{}

if r.Method == "GET" {
	indexTemplate.Execute(w, params)
	return
}

// It's a POST request, so handle the form submission.

name := r.FormValue("name")
params.Name = name // Preserve the name field.
if name == "" {
	name = "Anonymous Gopher"
}

if r.FormValue("message") == "" {
	w.WriteHeader(http.StatusBadRequest)

	params.Notice = "No message provided"
	indexTemplate.Execute(w, params)
	return
}

// TODO: save the message into a database.

params.Notice = fmt.Sprintf("Thank you for your submission, %s!", name)

By calling r.FormValue, you retrieve data from the form.

Passing data into your template

At the end of your indexHandler function, use the Execute function to display user-submitted content to your injection-safe index.html template:

indexTemplate.Execute(w, params)

Running your application locally

Run and test your application using the local development server (dev_appserver.py), which is included with the GCP SDK.

  1. From the project root directory where your application's app.yaml is located, start the local development server with the following command:

    dev_appserver.py app.yaml
    

    The local development server is now running and listening for requests on port 8080. Something go wrong?

  2. Visit http://localhost:8080/ in your web browser to view the app.

    Final

Running the local development server (dev_appserver.py)

To run the local development server, you can either run dev_appserver.py by specifying the full directory path or you can add dev_appserver.py to your PATH environment variable:

  • If you installed the original App Engine SDK, the tool is located at:

    [PATH_TO_APP_ENGINE_SDK]/dev_appserver.py
    
  • If you installed the Google Cloud SDK, the tool is located at:

    [PATH_TO_CLOUD_SDK]/google-cloud-sdk/bin/dev_appserver.py
    

    Tip: To add the Google Cloud SDK tools to your PATH environment variable and enable command-completion in your shell, you can run:

    [PATH_TO_CLOUD_SDK]/google-cloud-sdk/install.sh
    

For more information about running the local development server including how to change the port number, see the Local Development Server reference.

Making code changes

The local development server watches for changes in your project files, so it recompiles and re-launches your application after you make code changes.

  1. Try it now: Leave the local development server running and then try editing index.html to change "The Gopher Network" to something else.

  2. Reload http://localhost:8080/ to see the change.

Deploying your application

Deploy your application to App Engine using the following command from the project root directory where app.yaml is located:

gcloud app deploy

Viewing your application

To launch your browser and view your application at http://[YOUR_PROJECT_ID].appspot.com, run the following command:

gcloud app browse

What's next

You just built an application where the backend and the frontend interact over HTTP POST requests.

Next, learn how to save user-uploaded content in Cloud Datastore, a non-relational (NoSQL) database built for automatic scaling, high performance, and ease of application development.

Was this page helpful? Let us know how we did:

Send feedback about...

App Engine standard environment for Go