Este documento presenta el framework ItsNat y argumenta que es compatible con las características de Single Page Interface, servidor centrado, compatible con SEO y sin estado. Explica que ItsNat usa un modo de carga rápida y enlaces duales para ser compatible con SEO de forma que los robots puedan rastrear el sitio. También explica cómo ItsNat puede funcionar sin estado mediante el uso de eventos personalizados sin estado y la construcción dinámica del DOM en el cliente.
Hernandez_Hernandez_Practica web de la sesion 12.pptx
Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!
1. Jose María Arranz Santamaría
Sitios web SPI céntricos en el servidor SEO
compatibles sin estado ... ¡ALELUYA!
jmarranz@innowhere.com
@jmarranz
http://www.innowhere.com
18. Buscando el Santo Grial Web
Single Page SEO compatible server centric
stateless web framework...
o la búsqueda del
Santo Grial del Web
19. Buscando el Santo Grial Web
Single Page Interface
●
No recargas completas (cambios parciales)
=> mayor rendimiento
=> mejor experiencia de usuario
- no página en blanco transitoria
- no scroll al principio de la página
20. Buscando el Santo Grial Web
SEO compatible
●
Web crawlers capaces de recorrer nuestro sitio
web
–
Los robots ven nuestra web como paginada
(JavaScript es ignorado)
Aproximación “clásica” indeseable
=> hacer "dos webs” SPI y paginada
21. Buscando el Santo Grial Web
Server Centric
●
Lógica de vista y proceso de eventos
programado fundamentalmente en el servidor*
✔
✔
✔
Datos y “vista” en el mismo espacio de memoria
Lenguaje estático (Java, Scala...) o dinámico (Groovy...)
favorito
Herramientas favoritas (Eclipse, IntelliJ, NetBeans...)
➔
✔
Autocompletado, static analysis, navegación de código,
refactorización...
Código fuente puede crecer en libertad
*bueno sí, algún inconveniente tiene...
22. Buscando el Santo Grial Web
Stateless
●
El framework no hace uso de la sesión web
–
"share nothing" entre nodos
●
●
no necesaria sincronización de sesiones
ni afinidad de sesión (sticky sessions)
escalabilidad
horizontal lineal
23. Buscando el Santo Grial Web
¿Es ItsNat Single Page Interface SEO
Compatible Server Centric y Stateless?
24. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
¡¡¡ SÍ !!!
25. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
¡¡CÓDIGO!!
¡¡CÓDIGO!!
¡¡CÓDIGO!!
28. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
public class CoreExampleDocument implements EventListener {
...
public void load()
{
...
((EventTarget)clickElem1).addEventListener("click",
this,false);
public void setAsClickable(Element elem) {
}
elem.setAttribute("style","color:red;");
public void handleEvent(Event evt)
{
Text text = (Text)elem.getFirstChild();
EventTarget currTarget = evt.getCurrentTarget();
text.setData("Click Me!");
if (currTarget == clickElem1)
((EventTarget)elem).addEventListener(
{
"click",this,false);
removeClickable(clickElem1);
}
setAsClickable(clickElem2);
}
public void removeClickable(Element elem){
else
elem.removeAttribute("style");
{
Text text = (Text)elem.getFirstChild();
setAsClickable(clickElem1);
text.setData("Cannot be clicked");
removeClickable(clickElem2);
((EventTarget)elem).removeEventListener(
}
"click",this,false);
ItsNatEvent itsNatEvt = (ItsNatEvent)evt;
}
ItsNatServletRequest itsNatReq =
}
itsNatEvt.getItsNatServletRequest();
ItsNatDocument itsNatDoc = itsNatReq.getItsNatDocument();
HTMLDocument doc = (HTMLDocument)itsNatDoc.getDocument();
Element noteElem = doc.createElement("p");
noteElem.appendChild(doc.createTextNode("Clicked " +
((Element)currTarget).getAttribute("id")));
doc.getBody().appendChild(noteElem);
}
DOM
29. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
http://www.innowhere.com/itsnat/servlet?itsnat_doc_name=manual.core.example
30. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
✔ Single Page Interface
✔ Server Centric
¿SEO Compatible?
¿Stateless?
31. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
SEO Compatible
El oscuro secreto de ItsNat: Fast Load Mode
(EN CARGA)
public void setAsClickable(Element elem)
{
elem.setAttribute("style","color:red;");
Text text = (Text)elem.getFirstChild();
text.setData("Click Me!");
((EventTarget)elem).addEventListener("click",this,false);
}
<div style="color:red;" id="clickableId1">Click Me!</div>
<div style="color:red;" id="clickableId1">Click Me!</div>
(EVENTO AJAX)
¡¡SEO!!
itsNatDoc.setAttribute2("cn_2","style","color:red;");
itsNatDoc.setAttribute2("cn_2","style","color:red;");
itsNatDoc.setTextData2("cn_2",null,"Click Me!");
itsNatDoc.setTextData2("cn_2",null,"Click Me!");
itsNatDoc.addDOMEventListener("cn_2","click","el_10",null,false,3,-1,2);
itsNatDoc.addDOMEventListener("cn_2","click","el_10",null,false,3,-1,2);
32. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
SEO Compatible (cont.)
Dual links links con “doble vida”
“HTML de día, JavaScript de noche”
➔
Link normal con JavaScript desactivado (web crawlers)
➔
Disparador de eventos AJAX con JS activado
<a href="?st=overview" onclick="setState('overview'); return false;">Overview</a>
false;">Overview</a>
33. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
DEMO
¡¡¡OJO FAKE!!!
¡¡¡OJO FAKE!!!
http://www.innowhere.com/insites
34. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
¿¿STATELESS??
¡¡¡MENTIRA!!!
ESE EJEMPLO ES ESENCIALMENTE
STATEFUL
35. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
STATELESS
●
Soporte introducido en ItsNat v1.3
●
No aprovecha todo el potencial de ItsNat
●
Pero permite escalabilidad lineal horizontal
Sin degradación por
sincronización de sesiones
✔
Sin necesidad de afinidad de
sesión
✔
36. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
STATELESS (modo)
●
NO hay copia del árbol DOM del cliente en el
servidor
–
–
●
Sesión vacía
Estado visual únicamente en el cliente
Eventos AJAX => todos tipo “custom stateless”
–
Se construye bajo demanda el DOM a insertar
–
Necesario enviar info del estado visual
40. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
Template fragmento que se incluye en la inserción parcial
(manual.stless.example.fragment)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:itsnat="http://itsnat.org/itsnat">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Fragment</title>
</head>
<body>
<h4 style="color:green"><b>Fragment...</b></h4>
<h3>Inserted!</h3>
</body>
</html>
41. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
Clase procesadora de carga inicial
public class StlessExampleInitialDocument
{
protected ItsNatHTMLDocument itsNatDoc;
public StlessExampleInitialDocument(ItsNatHTMLDocument itsNatDoc)
{
this.itsNatDoc = itsNatDoc;
HTMLDocument doc = itsNatDoc.getHTMLDocument();
Text node = (Text)doc.createTextNode(
"This the initial stateless page (not kept in server)");
Element presentationElem = doc.getElementById("presentationId");
presentationElem.appendChild(node);
}
}
42. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
Clase procesadora de eventos stateless
public class StatelessExampleForProcessingEventDocument implements Serializable,EventListener
{
protected ItsNatHTMLDocument itsNatDoc;
protected Element counterElem;
public StatelessExampleForProcessingEventDocument(
ItsNatHTMLDocument itsNatDoc, ItsNatServletRequest request, ItsNatServletResponse response)
{
this.itsNatDoc = itsNatDoc;
if (!itsNatDoc.isCreatedByStatelessEvent())
throw new RuntimeException("Only to test stateless, must be loaded by a stateless event");
// Counter node with same value (state) than in client:
String currCountStr =
request.getServletRequest().getParameter("counter");
int counter = Integer.parseInt(currCountStr);
HTMLDocument doc = itsNatDoc.getHTMLDocument();
this.counterElem = doc.getElementById("counterId");
((Text)counterElem.getFirstChild()).setData(String.valueOf(counter));
itsNatDoc.addEventListener(this);
}
43. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
Clase procesadora de eventos stateless (parte 2)
public void handleEvent(Event evt)
{
ItsNatEventDOMStateless itsNatEvt = (ItsNatEventDOMStateless)evt;
Text counterText = (Text)counterElem.getFirstChild();
String currCountStr = counterText.getData();
int counter = Integer.parseInt(currCountStr);
counter++;
counterText.setData(String.valueOf(counter));
Document doc = itsNatDoc.getDocument();
Element elemParent = doc.getElementById("insertHereId");
ScriptUtil scriptGen = itsNatDoc.getScriptUtil();
String elemRef = scriptGen.getNodeReference(elemParent);
ClientDocument clientDoc = itsNatEvt.getClientDocument();
clientDoc.addCodeToSend(elemRef + ".innerHTML = '';");
clientDoc.addCodeToSend("alert('Currently inserted fragment removed before');");
ItsNatServlet servlet = itsNatDoc.getItsNatDocumentTemplate().getItsNatServlet();
ItsNatHTMLDocFragmentTemplate docFragTemplate =
(ItsNatHTMLDocFragmentTemplate)servlet.getItsNatDocFragmentTemplate("manual.stless.example.fragment");
DocumentFragment docFrag = docFragTemplate.loadDocumentFragmentBody(itsNatDoc);
elemParent.appendChild(docFrag); // docFrag is empty now
44. ¿Es ItsNat SPI SEO Compatible Server Centric Stateless?
Clase procesadora de eventos stateless (parte 3)
// Umm we have to celebrate/highlight this insertion
Element child1 = ItsNatTreeWalker.getFirstChildElement(elemParent);
Element child2 = ItsNatTreeWalker.getNextElement(child1);
Text textChild2 = (Text)child2.getFirstChild();
Element bold = doc.createElement("i");
bold.appendChild(textChild2); // is removed from child2
child2.appendChild(bold);
child2.setAttribute("style","color:red");
// <h3 style="color:red"><i>Inserted!</i></h3>
}
}