App Engine is currently running a simple survey on the administration console. For those of you who haven’t seen it yet, here’s what it looks like:
The question is located on the top of the admin page:
Tips, tricks, and thoughts about Google, AdWords, Google Cloud Platform, and all its subsidiaries. Not affiliated with or sponsored by Google.
App Engine is currently running a simple survey on the administration console. For those of you who haven’t seen it yet, here’s what it looks like:
The question is located on the top of the admin page:
A quick note: Go allows the aliasing of imports. For instance, the below line of code imports the appengine/datastore package under the name aedatastore :
import aedatastore "appengine/datastore"
Then the application can call datastore services under the alias name:
aedatastore.Get(c, key, &entity)
This aliasing is particularly useful when package names collide. Assume that an application needs to import the Go image and appengine/image packages. Since both packages are named image, the Go compiler will issue an image redeclared as package name error if both are imported. To avoid this, alias one of the imports:
import "image"
import aeimage "appengine/image"
While configuring a new Google Apps account for a customer, I encountered the error below:
Here’s how to fix this. First, go to the Users tab, then click Services :
Type in Webmaster Tools in the search box directly under the Services tab:
Click the On button next to the Webmaster Tools label:
Remember to save your changes:
Retrieving the originating IP address of the request is simple in most languages.
Here’s how to retrieve the IP address in Java ( req represents a javax.servlet.http.HttpServletRequestreference ):
String ip = req.getRemoteAddr();
Here’s the same line in Go ( r represents http.Request ):
ip := r.RemoteAddr
In PHP, the originating IP can be retrieved from the predefined variable SERVER :
$_SERVER['REMOTE_ADDR']
Here’s how to retrieve the value of a form element named comment ( r represents http.Request ):
comment := r.FormValue("comment")
Suppose the form value is an integer. Here’s how to extract the value from the request and convert it from a string to an integer (if an error occurs when converting, the value -1 is stored):
index, err := strconv.Atoi(r.FormValue("index"))
if err != nil {
index = -1
}
If needed, the submitted form value can be written to logging by calling:
c := appengine.NewContext(r)
c.Infof("Submitted Value: %v", index)
The Go language contains an extremely powerful templating engine which simplifies the creation of web pages. Here’s a quick overview of how it works.
First of all, create a set of template HTML files. Wherever dynamic content should be added, add a {{.name-of-property}}
annotation. Here’s an example:
<div class="row">
<div class="span12">{{.propertyone}}</div>
<div class="span8">{{.propertytwo}}</div>
</div>
In the above example, propertyone and propertytwo represent keys which will be replaced by values later on.
Next, make these template files available to the Go application. This line of code pulls in an entire folder of template files (assuming that templates is a root level directory):
var templates, templates_err = template.ParseGlob("templates/*")
Alternately, a set of templates can be called in by name:
var templates = template.Must(template.ParseFiles("templates/one.html", "templates/two.html", "templates/three.html"))
Using template.Must ensures that all the templates files are loaded in – if it is unable to find a named template file, template.Must sets off a panic.
Next, create a map of strings to display on the page. We associate the keys (which were set within the HTML of the template file) with values that will replace the annotations:
//This map holds the data to display on the page.
display_data := make(map[string]string)
display_data["propertyone"] = string_one
display_data["propertytwo"] = string_two
display_data["propertythree"] = string_three
Finally, execute the template. W represents a http.ResponseWriter reference to write the completed template to, one.html represents the name of the template to use, and display_data is the map that defines the values to use when replacing the annotations:
//Put the data into the template and send to the user.
templates.ExecuteTemplate(w, "one.html", display_data)
Remember to import the html/template package before using this code.
A quick note about MIME types: JSON responses have a MIME type of application/json while Javascript files use application/javascript . JSONP is a JSON object within a Javascript function call, so it shares the same MIME type as Javascript ( application/javascript ).
With that said, there are some browsers (largely older browsers) and applications that don’t understand the application/json MIME type. They may require JSON responses to have a content type of application/javascript , application/x-javascript , or text/html . If you encounter issues with handling JSON, it’s a good idea to try changing the MIME type – it may solve the problem.
As a reminder, here’s how to set the content type of a response in Java (other languages have similar functions):
resp.setContentType(mime_type);
The resp object represents a javax.servlet.http.HttpServletResponse reference.
A quick note about some Google UI changes: Google is in the middle of removing the top black navigation bar.
Previously, Google had a top nav bar linking to various Google services:
Now that navigation bar is gone:
Google is popping up a little note to explain the changes:
In short, the grid icon drops down a list of various Google services to choose from:
Here’s an overview of how to send HTTP status codes in Go. W represents a http.ResponseWriterreference, and r is a http.Request reference.
The following line tells the browser to redirect to the URL given (a 301 is a Moved Permanently redirect):
http.Redirect(w, r, "http://learntogoogleit.com/", 301)
Here is a standard Not Found error:
http.Error(w, http.StatusText(404), 404)
An Internal Server Error is indicated using a 500 status code:
http.Error(w, http.StatusText(500), 500)
The above examples use StatusText to retrieve standard error text, but you can set your own text if needed:
http.Error(w, "Too Many Requests", 429)
Here’s a code snippet demonstrating how to wrap JSON text within a JSONP response.
The text of the JSON object is in the string json. The variable resp represents a HttpServletResponseobject. Callback represents contents of the HTTP parameter callback , which should be set with the name of the Javascript function to call. Before calling this code, it’s a good idea to validate that parameter.
String callback = req.getParameter("callback");
String json_text = callback + "(" + json + ");";
resp.getWriter().println(json_text);
Here’s an example of a simple JSONP response:
findIP({"ip": "8.8.8.8"});
This response will call the JS function findIP (the callback parameter contents), with an object containing the property ip (the JSON data).