2. Our web application today
• Build a web application for searching
SML definitions from the SML Basis
Standard Library
✓ We will use Google custom search
for building this app
... because we know you like SML!
4. The Google Custom Search API
➡ Use the Google Custom Search API to search over a website
or a collection of websites and to embed the results in your
web application
5. 3 ways to use Google Custom search
• Google snippet
• Google Javascript API (client side)
• Google Python API (server side)
11. Step 4 - Paste the code snippet in your page
engine/templates/engine/index.html
...
<body>
<div id="cse-search-form" style="width: 100%;">Loading</div>
<script src="//www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1', {language : 'en', style : google.loader.themes.SHINY});
google.setOnLoadCallback(function() {
var customSearchControl = new google.search.CustomSearchControl('004982958264606934300:2o52rkqdfaw');
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
var options = new google.search.DrawOptions();
options.setSearchFormRoot('cse-search-form');
customSearchControl.draw('cse', options);
}, true);
</script>
<div id="cse" style="width:100%;"></div>
<body></html>
12. Step 4 - Paste the code snippet in your page
engine/templates/engine/index.html
...
Your Custom Search Identifier
<body>
(aka CX or CSEid)
<div id="cse-search-form" style="width: 100%;">Loading</div>
<script src="//www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1', {language : 'en', style : google.loader.themes.SHINY});
google.setOnLoadCallback(function() {
var customSearchControl = new google.search.CustomSearchControl('004982958264606934300:2o52rkqdfaw');
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
var options = new google.search.DrawOptions();
options.setSearchFormRoot('cse-search-form');
customSearchControl.draw('cse', options);
}, true);
</script>
<div id="cse" style="width:100%;"></div>
<body></html>
13. Step 4 - Paste the code snippet in your page
engine/templates/engine/index.html
...
Your Custom Search Identifier
<body>
(aka CX or CSEid)
<div id="cse-search-form" style="width: 100%;">Loading</div>
<script src="//www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1', {language : 'en', style : google.loader.themes.SHINY});
google.setOnLoadCallback(function() {
var customSearchControl = new google.search.CustomSearchControl('004982958264606934300:2o52rkqdfaw');
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
var options = new google.search.DrawOptions();
options.setSearchFormRoot('cse-search-form');
customSearchControl.draw('cse', options);
}, true);
</script>
The div element where to
<div id="cse" style="width:100%;"></div>
show the results
<body></html>
15. Advantages and Limitations
✓ Very easy to use
๏ The results are shown in a new tab/window
➡ We want the results to be embedded in the same page
16. Solution
➡ On the client side
1. query the Google search using the Google Javascript API
2. process the results using Javascript
3. show the results in the page
19. Search Request
search/static/js/script.js
function client()
{
$('#result').html('<script src="https://www.googleapis.com/customsearch/v1?
key=AIzaSyDBrtHVzXjrvKus_qGpPbTm9rJppIhjxvM&
cx=004982958264606934300:2o52rkqdfaw&
q='+$('#inp').val()+'&
callback=hndlr"></script>');
}
function hndlr(response)
{
....
}
20. Search Request
search/static/js/script.js
function client()
{
$('#result').html('<script src="https://www.googleapis.com/customsearch/v1?
key=AIzaSyDBrtHVzXjrvKus_qGpPbTm9rJppIhjxvM&
Your API key
cx=004982958264606934300:2o52rkqdfaw&
q='+$('#inp').val()+'&
callback=hndlr"></script>');
}
function hndlr(response)
{
....
}
21. Search Request
search/static/js/script.js
function client()
{
$('#result').html('<script src="https://www.googleapis.com/customsearch/v1?
key=AIzaSyDBrtHVzXjrvKus_qGpPbTm9rJppIhjxvM&
Your API key
cx=004982958264606934300:2o52rkqdfaw&
q='+$('#inp').val()+'&
Your custom search engine id
callback=hndlr"></script>');
}
function hndlr(response)
{
....
}
22. Search Request
search/static/js/script.js
function client()
{
$('#result').html('<script src="https://www.googleapis.com/customsearch/v1?
key=AIzaSyDBrtHVzXjrvKus_qGpPbTm9rJppIhjxvM&
Your API key
cx=004982958264606934300:2o52rkqdfaw&
q='+$('#inp').val()+'&
Your search query Your custom search engine id
callback=hndlr"></script>');
}
function hndlr(response)
{
....
}
23. Search Request
search/static/js/script.js
function client()
{
$('#result').html('<script src="https://www.googleapis.com/customsearch/v1?
key=AIzaSyDBrtHVzXjrvKus_qGpPbTm9rJppIhjxvM&
Your API key
cx=004982958264606934300:2o52rkqdfaw&
q='+$('#inp').val()+'&
Your search query Your custom search engine id
callback=hndlr"></script>');
}
function hndlr(response)
{ Your callback method
....
}
24. The callback method
➡ The call method (called hndlr in the example) defines
what to do with the search results
25. Example
search/static/js/script.js
function hndlr(response)
{
page = “”
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var link = item.link;
page += "<br/><div><a onclick="go('"+link+"');" href='#'>"
+item.htmlTitle
+"</a><br/>"
+item.htmlSnippet+
+ "<br/><a onclick="go('"+link+"');" href='#'>"
+link+"</a></div><br/>";
}
$('#result').html(page);
$('#result').show();
}
26. Example
search/static/js/script.js
function hndlr(response)
For each search result ...
{
page = “”
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var link = item.link;
page += "<br/><div><a onclick="go('"+link+"');" href='#'>"
+item.htmlTitle
+"</a><br/>"
+item.htmlSnippet+
+ "<br/><a onclick="go('"+link+"');" href='#'>"
+link+"</a></div><br/>";
}
$('#result').html(page);
$('#result').show();
}
27. Example
search/static/js/script.js
function hndlr(response)
For each search result ...
{
page = “”
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var link = item.link;
page += "<br/><div><a onclick="go('"+link+"');" href='#'>"
+item.htmlTitle
+"</a><br/>"
+item.htmlSnippet+
+ "<br/><a onclick="go('"+link+"');" href='#'>"
+link+"</a></div><br/>";
}
$('#result').html(page); ... display the search result but change the target url
$('#result').show(); address so that the link opens in the current page
rather than opening a new one
}
29. Problem
๏ Nothing happens when you click on the link
➡ No bug shown except ...
30. Problem
๏ Nothing happens when you click on the link
➡ No bug shown except ...
This is a Cross Domain error
31. Cross Domain restriction (aka Same Origin Policy)
”The policy permits scripts running on pages
originating from the same site to access each other's
methods and properties with no specific restrictions,
but prevents access to most methods and
properties across pages on different sites.” Wikipedia
32. Solution - use an iframe
• An <iframe> can contains another HTML document possibly
coming from another domain
➡ Like a webpage inside a webpage
✓ An iFrame is acting like a fence between the two documents
<html>
...
<iframe>
<html>
</html>
</iframe>
...
</html>
33. Solution - use an iframe
• An <iframe> can contains another HTML document possibly
coming from another domain
➡ Like a webpage inside a webpage
✓ An iFrame is acting like a fence between the two documents
<html>
... Javascript code from the inner document cannot
<iframe> access the resources from the main document
<html>
</html>
</iframe>
...
</html>
34. Solution - use an iframe
• An <iframe> can contains another HTML document possibly
coming from another domain
➡ Like a webpage inside a webpage
✓ An iFrame is acting like a fence between the two documents
<html>
... Javascript code from the inner document cannot
<iframe> access the resources from the main document
<html>
</html>
</iframe>
... and vice versa
</html>
35. Solution to our problem search/static/js/script.js
function hndlr(response)
{
page = “”
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var link = item.link;
page += "<br/><div><a onclick="go('"+link+"');" href='#'>"
+item.htmlTitle
+"</a><br/>"
+item.htmlSnippet+
+ "<br/><a onclick="go('"+link+"');" href='#'>"
+link+"</a></div><br/>";
}
$('#result').html(page);
$('#result').show();
}
37. Advantages and Limitations
✓ Using an iframe is secure
๏ We cannot modify the page contained in the iframe
➡ We want the define new CSS and Javascript controls for the
result document
38. Solution
➡ On the server side
1. query the Google search using the Python Google API
2. process the results using Python
3. return the results to the client
40. The Python Google API
• Download the last release from
http://code.google.com/p/google-api-python-client/downloads/list
• Install
$ tar xvzf google-api-python-client-1.0beta6.tar.gz
$ cd google-api-python-client-1.0
$ python setup.py install
41. Example
search2/views.py
from apiclient.discovery import build
from BeautifulSoup import BeautifulSoup
import urllib2
import re
@csrf_exempt
def find(request):
try:
service = build("customsearch","v1",
developerKey="AIzaSyDBrtHVzXjrvKus_qGpPbTm9rJppIhjxvM")
res = service.cse().list(q=request.POST['key'],
cx='004982958264606934300:2o52rkqdfaw').execute()
page = urllib2.urlopen(res['items'][0]['link'])
soup = BeautifulSoup(page).body
except:
return HttpResponse("error")
else:
return HttpResponse(soup)