summaryrefslogtreecommitdiffstats
path: root/documentation/advanced/advanced-urifu.asciidoc
diff options
context:
space:
mode:
authorelmot <elmot@vaadin.com>2015-09-25 16:40:44 +0300
committerelmot <elmot@vaadin.com>2015-09-25 16:40:44 +0300
commita1b265c318dbda4a213cec930785b81e4c0f7d2b (patch)
treeb149daf5a4f50b4f6446c906047cf86495fe0433 /documentation/advanced/advanced-urifu.asciidoc
parentb9743a48a1bd0394f19c54ee938c6395a80f3cd8 (diff)
downloadvaadin-framework-a1b265c318dbda4a213cec930785b81e4c0f7d2b.tar.gz
vaadin-framework-a1b265c318dbda4a213cec930785b81e4c0f7d2b.zip
Framework documentation IN
Change-Id: I767477c1fc3745f9e1f58075fe30c9ac8da63581
Diffstat (limited to 'documentation/advanced/advanced-urifu.asciidoc')
-rw-r--r--documentation/advanced/advanced-urifu.asciidoc191
1 files changed, 191 insertions, 0 deletions
diff --git a/documentation/advanced/advanced-urifu.asciidoc b/documentation/advanced/advanced-urifu.asciidoc
new file mode 100644
index 0000000000..709d6c4bd3
--- /dev/null
+++ b/documentation/advanced/advanced-urifu.asciidoc
@@ -0,0 +1,191 @@
+---
+title: Managing URI Fragments
+order: 11
+layout: page
+---
+
+[[advanced.urifu]]
+= Managing URI Fragments
+
+A major issue in AJAX applications is that as they run in a single web page,
+bookmarking the application URL (or more generally the __URI__) can only
+bookmark the application, not an application state. This is a problem for many
+applications, such as product catalogs and discussion forums, in which it would
+be good to provide links to specific products or messages. Consequently, as
+browsers remember the browsing history by URI, the history and the
+[guibutton]#Back# button do not normally work. The solution is to use the
+__fragment identifier__ part of the URI, which is separated from the primary
+part (address + path + optional query parameters) of the URI with the hash (#)
+character. For example:
+
+
+----
+http://example.com/path#myfragment
+----
+
+The exact syntax of the fragment identifier part is defined in RFC 3986
+(Internet standard STD 66) that defines the URI syntax. A fragment may only
+contain the regular URI __path characters__ (see the standard) and additionally
+the slash and the question mark.
+
+Vaadin offers two ways to enable the use of URI fragments: the high-level
+[classname]#Navigator# utility described in
+<<dummy/../../../framework/advanced/advanced-navigator#advanced.navigator,"Navigating
+in an Application">> and the low-level API described here.
+
+[[advanced.urifu.setting]]
+== Setting the URI Fragment
+
+You can set the current fragment identifier with the
+[methodname]#setUriFragment()# method in the [classname]#Page# object.
+
+
+[source, java]
+----
+Page.getCurrent().setUriFragment("mars");
+----
+
+Setting the URI fragment causes an [interfacename]#UriFragmentChangeEvent#,
+which is processed in the same server request. As with UI rendering, the URI
+fragment is changed in the browser after the currently processed server request
+returns the response.
+
+Prefixing the fragment identifier with an exclamation mark enables the web
+crawler support described in <<advanced.urifu.crawling>>.
+
+
+[[advanced.urifu.reading]]
+== Reading the URI Fragment
+
+The current URI fragment can be acquired with the [methodname]#getUriFragment()#
+method from the current [classname]#Page# object. The fragment is known when the
+[methodname]#init()# method of the UI is called.
+
+
+[source, java]
+----
+// Read initial URI fragment to create UI content
+String fragment = getPage().getUriFragment();
+enter(fragment);
+----
+See the http://demo.vaadin.com/book-examples-vaadin7/book#advanced.urifragment.basic[on-line example, window="_blank"].
+
+To enable reusing the same code when the URI fragment is changed, as described
+next, it is usually best to build the relevant part of the UI in a separate
+method. In the above example, we called an [methodname]#enter()# method, in a
+way that is similar to handling view changes with [classname]#Navigator#.
+
+
+[[advanced.urifu.listening]]
+== Listening for URI Fragment Changes
+
+After the UI has been initialized, changes in the URI fragment can be handled
+with a [interfacename]#UriFragmentChangeListener#. The listeners are called when
+the URI fragment changes, but not when the UI is initialized, where the current
+fragment is available from the page object as described earlier.
+
+For example, we could define the listener as follows in the [methodname]#init()#
+method of a UI class:
+
+
+[source, java]
+----
+public class MyUI extends UI {
+ @Override
+ protected void init(VaadinRequest request) {
+ getPage().addUriFragmentChangedListener(
+ new UriFragmentChangedListener() {
+ public void uriFragmentChanged(
+ UriFragmentChangedEvent source) {
+ enter(source.getUriFragment());
+ }
+ });
+
+ // Read the initial URI fragment
+ enter(getPage().getUriFragment());
+ }
+
+ void enter(String fragment) {
+ ... initialize the UI ...
+ }
+}
+----
+See the http://demo.vaadin.com/book-examples-vaadin7/book#advanced.urifragment.basic[on-line example, window="_blank"].
+
+<<figure.advanced.urifu>> shows an application that allows specifying the menu
+selection with a URI fragment and correspondingly sets the fragment when the
+user selects a menu item.
+
+[[figure.advanced.urifu]]
+.Application State Management with URI Fragment Utility
+image::img/urifu-1.png[]
+
+
+[[advanced.urifu.crawling]]
+== Supporting Web Crawling
+
+Stateful AJAX applications can not normally be crawled by a search engine, as
+they run in a single page and a crawler can not navigate the states even if URI
+fragments are enabled. The Google search engine and crawler
+link:http://googlewebmastercentral.blogspot.fi/2009/10/proposal-for-making-ajax-crawlable.html[support
+a convention] where the fragment identifiers are prefixed with exclamation mark,
+such as [literal]#++#!myfragment++#. The servlet needs to have a separate
+searchable content page accessible with the same URL, but with a
+[literal]#++_escaped_fragment_++# parameter. For example, for
+[literal]#++/myapp/myui#!myfragment++# it would be
+[literal]#++/myapp/myui?_escaped_fragment_=myfragment++#.
+
+You can provide the crawl content by overriding the [methodname]#service()#
+method in a custom servlet class. For regular requests, you should call the
+super implementation in the [classname]#VaadinServlet# class.
+
+
+[source, java]
+----
+public class MyCustomServlet extends VaadinServlet
+ @Override
+ protected void service(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+ String fragment = request
+ .getParameter("_escaped_fragment_");
+ if (fragment != null) {
+ response.setContentType("text/html");
+ Writer writer = response.getWriter();
+ writer.append("<html><body>"+
+ "<p>Here is some crawlable "+
+ "content about " + fragment + "</p>");
+
+ // A list of all crawlable pages
+ String items[] = {"mercury", "venus",
+ "earth", "mars"};
+ writer.append("<p>Index of all content:</p><ul>");
+ for (String item: items) {
+ String url = request.getContextPath() +
+ request.getServletPath() +
+ request.getPathInfo() + "#!" + item;
+ writer.append("<li><a href='" + url + "'>" +
+ item + "</a></li>");
+ }
+ writer.append("</ul></body>");
+ } else
+ super.service(request, response);
+ }
+}
+----
+See the http://demo.vaadin.com/book-examples-vaadin7/book#advanced.urifragment.basic[on-line example, window="_blank"].
+
+The crawlable content does not need to be human readable. It can provide an
+index of links to other application states, as we did in the example above. The
+links should use the " [literal]#++#!++#" notation, but can not be relative to
+avoid having the [literal]#++_escaped_fragment_++# parameter.
+
+You need to use the custom servlet class in the [filename]#web.xml# deployment
+descriptor instead of the normal [classname]#VaadinServlet# class, as described
+in
+<<dummy/../../../framework/application/application-environment#application.environment.web-xml,"Using
+a web.xml Deployment Descriptor">>.
+
+
+
+