From 99d6de546c74f0eed230ea8253dda6b85109d2e7 Mon Sep 17 00:00:00 2001
From: Markus Koivisto <markus@vaadin.com>
Date: Fri, 22 Jan 2016 14:55:18 +0200
Subject: Add documentation to master branch

Change-Id: I2504bb10f1ae73ec0cbc08b7ba5a88925caa1674
---
 documentation/advanced/advanced-urifu.asciidoc | 191 +++++++++++++++++++++++++
 1 file changed, 191 insertions(+)
 create mode 100644 documentation/advanced/advanced-urifu.asciidoc

(limited to 'documentation/advanced/advanced-urifu.asciidoc')

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">>.
+
+
+
+
-- 
cgit v1.2.3

