I am playing a little bit with Google App Engine (GAE) and as first thing I tried to integrate OpenUI5 in a demo app.
My app is just showing a list of projects and let the user to create a new project.
Here a screen:
Detailed info for Google App Engine SDK installation can be found in the official documentation:
Download the Google App Engine SDK - Google App Engine — Google Developers
I also used PyDev eclipse plugin as IDE.
For OpenUI5 SDK, you can download it from here (I used version 1.22.4):
On App Engine side, my application is built on three main python modules:
models/project.py --> it is the model; it creates one Datastore entity - Projects - with two characteristics: project_id and project_description and it implements three functions:
from google.appengine.ext import db
class Projects(db.Model):
project_id = db.StringProperty(required=True, )
project_description = db.StringProperty(required=True)
def get_projects():
list_of_projects = []
q = db.GqlQuery("SELECT * FROM Projects")
for p in q.run():
current_project = { 'project_id' : p.project_id, 'project_description' : p.project_description}
list_of_projects.append(current_project)
return list_of_projects
def get_project(project_id=None):
if not project_id:
return None
key = db.Key.from_path('Projects', project_id)
project = db.get(key)
if not project:
return None
return project
def put_project(project_id, project_description):
query = Projects.all(keys_only=True).filter('project_id', project_id)
entity = query.get()
if entity:
raise Exception('unique_property must have a unique value!')
project = Projects(project_id=project_id, project_description=project_description)
project.put()
main.py --> Is the main request handler for the GAE application (MainPage class is the handler)
import datetime
import jinja2
import os
import webapp2
from google.appengine.api import users
template_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.getcwd()))
class MainPage(webapp2.RequestHandler):
def get(self):
current_time = datetime.datetime.now()
current_user = users.get_current_user()
login_url = users.create_login_url(self.request.path)
logout_url = users.create_logout_url(self.request.path)
template = template_env.get_template('templates/index.html')
context = {
'current_time' : current_time,
'current_user' : current_user,
'login_url' : login_url,
'logout_url' : logout_url,
}
self.response.out.write(template.render(context))
application = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
projects_handler.py --> is the handler for a POST request to create a new project and a GET request to get all projects in a JSON format (I haven't found a good solution to espose the data via odata in python, some comments here would be really appreciated)
import webapp2
import json
from models import projects
class PostProject(webapp2.RequestHandler):
def post(self):
try:
project_id = self.request.get('project_id')
project_description = self.request.get('project_description')
projects.put_project(project_id, project_description)
except:
self.response.set_status(500)
return
self.response.set_status(200)
class GetProjects(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'application/json'
obj = projects.get_projects()
self.response.out.write(json.dumps(obj))
application = webapp2.WSGIApplication([('/post_project', PostProject)],
debug=True)
application_get_projects = webapp2.WSGIApplication([('/get_projects', GetProjects)],
debug=True)
app.yaml is the GAE configuration file in python, I defined 4 static handlers for directories and three script handlers for the http requests (one for main page GET, one for GET the list of projects as Json file, one for POST a new project):
application: com-oloconsulting-damien
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /css
static_dir: css
- url: /js
static_dir: js
- url: /openui5
static_dir: openui5-runtime-1.22.4
- url: /ui
static_dir: ui
- url: /post_project
script: projects_handler.application
- url: /get_projects
script: projects_handler.application_get_projects
- url: .*
script: main.application
libraries:
- name: webapp2
version: "2.5.1"
- name: jinja2
version: latest
- name: markupsafe
version: latest
Basically the app is working in this way: first page is managed by main.py, POST and GET requests on Projects model are managed by module projects_handler.py.
From OpenUI5 side, I created two views and put them in the same page:
ProjectList view (it implements a table for the list of projects):
sap.ui.jsview('ui.ProjectList', {
getControllerName : function() {
return 'ui.ProjectList';
},
createContent : function(oController) {
var oTable = new sap.ui.table.Table({editable:false});
var oControl = new sap.ui.commons.TextView({text: '{project_id}'});
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: oBundle.getText('ProjectId')}),
template: oControl, sortProperty: 'project_id',
filterProperty: 'project_id', width: '50px'}));
var oControl = new sap.ui.commons.TextView({text: '{project_description}'});
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: oBundle.getText('ProjectDescription')}),
template: oControl, sortProperty: 'project_description',
filterProperty: 'project_description', width: '200px'}));
var aData = oController.getProjects();
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({modelData: aData});
oTable.setModel(oModel);
oTable.bindRows('/modelData');
oTable.sort(oTable.getColumns()[0]);
return oTable;
}
});
The controller is implementing only one function to get the list of the projects (it is called in the view to fill the model data: var aData = oController.getProjects();)
getProjects: function() {
var aUrl = '/get_projects';
var aData = [];
jQuery.ajax({
url: aUrl,
async: false,
type: 'GET',
success: function(data, textStatus, jqXHR) {
//alert('success to post');
aData = data;
},
error: function(jqXHR, textStatus, errorThrown) {
alert('fail to post');
}
});
return aData;
}
ProjectCreation view (it defines a form with a couple of textFields and a button):
sap.ui.jsview('ui.ProjectCreation', {
getControllerName : function() {
return 'ui.ProjectCreation';
},
createContent : function(oController) {
var oLayout = new sap.ui.layout.form.GridLayout('ProjectCreationFormLayout');
var oForm = new sap.ui.layout.form.Form('ProjectCreationForm',{
title: new sap.ui.core.Title({
text: oBundle.getText('CreateProject')
}),
width: '50%',
layout: oLayout,
formContainers: [
new sap.ui.layout.form.FormContainer('ProjectCreationFC', {
formElements: [
new sap.ui.layout.form.FormElement({
fields: [
new sap.ui.commons.Label('lblProjectId', {
text: oBundle.getText('ProjectId')
}),
new sap.ui.commons.TextField('txtProjectId')
]
}),
new sap.ui.layout.form.FormElement({
fields: [
new sap.ui.commons.Label('lblProjectDescription', {
text: oBundle.getText('ProjectDescription')
}),
new sap.ui.commons.TextField('txtProjectDescription')
]
}),
new sap.ui.layout.form.FormElement({
fields: [
new sap.ui.commons.Button('ProjectCreationButton', {
text: 'Insert',
tooltip: oBundle.getText('CreateProject'),
press: function(oEvent){
oController.onCreateButtonPress(oEvent,oController);
}
})
]
})
]
})
]
});
return oForm;
}
});
The controller is implementing the function for inserting a new project:
onCreateButtonPress: function(oEvent, oController) {
var oProjectId = sap.ui.getCore().byId('txtProjectId');
var oProjectDescription = sap.ui.getCore().byId('txtProjectDescription');
var aUrl = '/post_project';
var formData = {
project_id: oProjectId.getValue(),
project_description: oProjectDescription.getValue()
};
jQuery.ajax({
url: aUrl,
type: 'POST',
data: formData,
success: function(data, textStatus, jqXHR) {
alert(oBundle.getText('ProjectCreationOk'));
location.reload();
},
error: function(jqXHR, textStatus, errorThrown) {
alert(oBundle.getText('ProjectCreationError'));
}
});
}
You can test the application at this link:
http://com-oloconsulting-damien.appspot.com/
here it is a snapshot of the GAE datastore after a couple of projects creation:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
11 | |
10 | |
7 | |
6 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 |