Your SlideShare is downloading. ×
PrettyFaces: SEO, Dynamic, Parameters, Bookmarks, Navigation for JSF / JSF2 (UrlRewrite)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

PrettyFaces: SEO, Dynamic, Parameters, Bookmarks, Navigation for JSF / JSF2 (UrlRewrite)

10,140
views

Published on

PrettyFaces: SEO, Dynamic Parameters, Bookmarks, and Navigation for JSF / JSF2 - As presented at JSFSummit2009 in Orlando Florida. …

PrettyFaces: SEO, Dynamic Parameters, Bookmarks, and Navigation for JSF / JSF2 - As presented at JSFSummit2009 in Orlando Florida.

Why should we use PrettyFaces?

Published in: Technology, Design

1 Comment
3 Likes
Statistics
Notes
No Downloads
Views
Total Views
10,140
On Slideshare
0
From Embeds
0
Number of Embeds
38
Actions
Shares
0
Downloads
130
Comments
1
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Thank everyone for attending Tell them who you are Tell them where you are from and some of your hobbies
  • Went to Northfield Mount Hermon, and Penn State I want to start my own company Went through a few ideas with friends, landed on scrumshark I'm talking about this because... scrumshark started prettyfaces
  • Client Facing Applications You've got a stunning user interface, but your URLs are ugly... put in the extra effort
  • Transcript

    • 1. PrettyFaces Client-facing JSF – Lincoln Baxter, III
    • 2. SiteMap
    • 7. PrettyFaces is: Url Rewriting http://example.com/faces/store .jsf http://example.com/ store
    • 8. PrettyFaces is: Url Parameterization http://example.com/store/item/ Z34SD498
    • 9. PrettyFaces is: Declarative Data Loading <action> #{storeBean.loadItem} </action>
    • 10. PrettyFaces is: Simplified Navigation “ viewStore ” -> http://example.com/store
    • 11. SiteMap
    • 16. The PrettyFaces Story Lincoln Baxter, III PrettyFaces/PrettyTime Founder of O cpSoft
    • 17. The PrettyFaces Story Lincoln Baxter, III Founder of O cpSoft @lincolnthree http://ocpsoft.com http://scrumshark.com http://ocpsoft.com/prettyfaces http://ocpsoft.com/prettytime
    • 18. The Problem
      • JSF1.x
        • Good separation between M & V of MVC
        • 19. Had usability issues, pitfalls
        • 20. Navigation was a pain...
        • 21. No bookmarks? Not entirely true.
        • 22. What about Pretty URLs / SEO?
    • 23. The Result
      • Took a while
        • Tried a few other tools
        • 24. Applied the 80/20 rule
        • 25. Destroyed Thanksgiving 2008
    • 26. The Result
      • Came out with a Gem: PrettyFaces
        • URLs were clean, search optimized
        • 27. Faces-config practically gone
        • 28. Data loading easy & declarative
      Easy, Bookmarkable JSF
    • 29. :) Life is good
    • 30. Why do we need Pretty URLs?
      • Build Trust
      • 31. Enhance User Experience
      • 32. Self-Promote
    • 33. SiteMap
    • 38. Rethinking Navigation The Basics Keep it simple...
    • 39. SiteMap
    • 47. Keep URLs Clean Build trust by reducing clutter Before: http://example.com/news.xhtml?p=my-new-post After: http://example.com/news/my-new-post/
    • 48. Keep URLs Clean Real Life: Should have been: http://www.llbean.com/webapp/wcs/stores/servlet/CategoryDisplay?categoryId=28&storeId=1&catalogId=1&langId=-1&nav=hp-gndp http://llbean.com/kids http://www.llbean.com/webapp/wcs/stores/servlet/CategoryDisplay? categoryId=28 & storeId=1 & catalogId=1 & langId=-1 & nav=hp-gndp Vulnerable!
    • 49. Keep URLs Clean Why don't more people buy used cars?
    • 50. Keep URLs Clean They don't trust the last owner. They're afraid of getting a bad deal.
    • 51. Keep URLs Clean http:// www.linkedin.com/in/lincolnthree http://ocpsoft.com/prettyfaces http://sourceforge.net/projects/resteasy/ http://www.youtube.com/watch?v=ZOU8GIRUd_g
    • 53. Keep URLs Clean
      • Clean, readable URLs:
        • Build trust
        • 54. Are self-promoting, benefit SEO
        • 55. Reduce vulnerability
        • 56. Root the user
    • 57. SiteMap
    • 65. Parameterization (p14n) / root / the / user
        • Be consistent... always
        • 66. Be general, progress to specific
        • 67. Keep the query string optional
    • 68. Parameterization (p14n)
      • P14N is:
        • a “Scope”
        • 69. where I am & what I'm looking at
        • 70. user accessible
    • 71. Parameterization (p14n) Examples:
      • No!
      http://scrumshark.com/project/PrettyFaces http://scrumshark.com/project/PrettyFaces /s7 http://scrumshark.com/project/PrettyFaces /iterations http://scrumshark.com/project/PrettyFaces /iterations/Sprint1 http://scrumshark.com/PrettyFaces/Sprint1/iterations/project
    • 72. Problem solved <pretty-config> ... <url-mapping id=”viewProject”> <pattern> / project / #{currentProjectBean.project} </pattern> <view-id>/faces/project/view.xhtml</view-id> </url-mapping> … </pretty-config> PrettyFaces
    • 73. SiteMap
    • 81. Validation
      • P14n is a “Scope”
      • 82. End-users have DIRECT ACCESS
      • 83. Validate everything
    • 84. Validation @FacesValidator(“ projectName ”) public class ProjectNameValidator { public void validate(...) } <url-mapping id=”viewProject”> <pattern value=”/project/#{currentProjectBean.project}”> <validate param=&quot;0&quot; validatorIds=” projectName ... ” /> </pattern> <view-id>/faces/project/view.xhtml</view-id> </url-mapping> pretty-config.xml
    • 85. Validation Yes – pretty:id or empty PrettyFaces Validation Send 404 Is onError handler defined? Handler returned Successfully? Inject values & continue or redirect to “pretty:id” Throw Exception
    • 86. SiteMap
    • 94. Data Loading A few ways to do it:
        • Always Load (On construction)
        • 95. Lazy Loading (On access)
        • 96. Declarative Loading (On event)
    • 97. Data Loading
      • Declarative Loading
        • JSF1.x traditionally sticky with this
        • 98. Enables deterministic behavior
        • 99. JSF2 helps a lot
          • More on that later
    • 100. Nothing fancy <pretty-config> ... <url-mapping id=”viewProject”> <pattern> /project/#{currentProjectBean.project} </pattern> <view-id>/faces/project/view.xhtml</view-id> <action> #{currentProjectBean.load} </action> </url-mapping> … </pretty-config> PrettyFaces
    • 101. Action Methods RESTORE_VIEW APPLY_REQUEST_VALUES PROCESS_VALIDATION … ANY_PHASE CurrentProjectBean + load() PrettyFaces Action Invocation <action>#{currentProjectBean.load}</action> Trigger Navigation Continue Lifecycle
    • 102. Alternatives More Configuration +3 +8 +1+n +4 Lines: = ~4 :) PrettyFaces = ~17! 2.0 view params Url Rewrite Filter 2.0 event listeners 1.x: requires seam or other pretty-config.xml
    • 103. The Basics
      • Keep URLs clean – Build trust, self promote
      • 104. Logical Parameter Order – Root the User
      • 105. Validate everything
      • 106. Load data declaratively
    • 107. SiteMap
    • 115. Rethinking Navigation Rethinking Navigation so many channels, so little time...
    • 116. SiteMap
    • 124. History: the old <h:commandLink action=”viewProject” /> <navigation-rule> <from-view-id> * </from-view-id> <navigation-case> <from-action> * </from-action> <from-outcome>viewProject</from-outcome> <to-view-id>/faces/project/view.xhtml</to-view-id> </navigation-case> </navigation-rule>
    • 125. History: the new <h:link outcome=”/view”> <f:param name=”project” value=”prettyfaces”/> </h:link> <f:metadata> <f:viewParam name=”project” value=”...” /> </f:metadata>
    • 126. History: Navigation Cases
      • Complex logic can be pulled into XML
      • 127. Conditional evaluation and outcomes
      • 128. Selectively pass page-params
        • … sounds like code?
    • 129. How often do we need them? pretty:hospital “ The baby's coming!” “ It might be a late night, Should we get some coffee?” No... “ What if we don't remember This? Let's get a video Camera!” NO! “ Should I pick up my mother?” DRIVE!!
    • 130. SiteMap
    • 138. pretty:mappingId private String actionMethod() { if(user.isMember) { return “ pretty:viewProject ”; } return “ pretty:joinProject ”; } < p:link mappingId=” hospital ”> <f:param value=”delivery”/> < /p:link >
    • 139. That Same Configuration The mapping ID <pretty-config> ... <url-mapping id=” viewProject ”> <pattern> /project/ #{currentProjectBean.project} </pattern> <view-id>/faces/project/view.xhtml</view-id> <action> #{currentProjectBean.load} </action> </url-mapping> … </pretty-config> PrettyFaces
    • 140. P14N is a “Scope” “ P14N is a Scope” private String createProject() { if(dao.createProject(project)) { currentProjectBean.setProject( “scrumshark” ); return “pretty:viewProject”; } FacesUtils.addError(“Something went wrong! Try again.”); return null; } project.getName()
    • 141. SiteMap
    • 149. But what about coupling?
      • PrettyFaces - Coupling pretty:ids to action methods
      • 150. JSF2 - Coupling view locations to action methods
      (what happens when you need to refactor?) Take your pick...
    • 151. But what about coupling? JSF2 /WebContent /faces /project view.xhtml Action Methods <h:link> <h:commandLink> faces-config.xml
    • 152. But what about coupling? PrettyFaces /WebContent /faces /project view.xhtml Action Methods <p:link> <h:commandLink> faces-config.xml pretty:viewProject
    • 153. But what about coupling?
      • PrettyFaces – pretty:ids abstract resource locations, lowers maintenance cost.
      • 154. “You GET what you ask for”
    • 155. SiteMap
    • 163. “You GET what you ask for” GET /project/scrumshark Create Project Action #{bean.create} GET /newproject Invoke Navigation “pretty:viewProject” <action> Load Project Data Render Response ?
    • 164. “You GET what you ask for” Option to handle behavior up front, instead of “behind” a submit. GET /project/scrumshark <action> Load Project Data ?
    • 165. Can I still use JSF navigation?
        Yes – PrettyFaces extends, does not interfere with, JSF navigation.
    • 166. In summary
      • PrettyFaces offers:
        • Declarative navigation via GET
        • 167. Encapsulation, de-coupling from view-location
        • 168. Extension to existing JSF navigation
    • 169. SiteMap
    • 177. Search Engine Optimization
    • 178. SiteMap
    • 185. Keywords
      • PUT KEYWORDS IN THE URL
      #1 Self-promoting Links
    • 186. Keywords examples Poor: http://example.com/shop.jsf?catId=23&itemId=Z34FK94SE Partly there: http://example.com/shop.jsf?cat=books&item=how-to-start-a-web-store Perfect: http://example.com/shop/books?item=how-to-start-a-web-store Self-promoting Links
    • 187. Keywords examples <url-mapping id=&quot;viewItem&quot;> <pattern> /shop/#{catBean.item} </pattern> <query-param name=” item ”> {itemBean.itemName} </query-param> <view-id>/faces/shop.jsf</view-id> <action> #{itemBean.load} </action> </url-mapping>
    • 188. Why do we need Pretty URLs?
      • Build Trust, Transparency
      • 189. Enhance User Experience
      • 190. Self-Promote, SEO
    • 191. SiteMap
    • 198. SEO is all you need False
    • 199. Install Google Analytics http://ocpsoft.com July 2008: 0 Nov 2009: 13,287 views 68% from search
    • 200. Three Fundamentals
      • Actually provide information
      • 201. Get people to say they believe you
      • 202. Get search engines to believe you both
    • 203. That means...
      • Content:
      Choose your keywords, make sure they are appropriate for your content.
    • 204. That means...
      • Credibility:
      Get other people to link back to your site, or create those links yourself.
    • 205. That means...
      • Context:
      • 206. Make sure your external links appear on pages relevant to your content.
    • 207. SiteMap
    • 214. Plan for Change .jsf .jsp .php .do .cgi .asp
    • 215. Clean up your URLs Technology changes... be agnostic. /
    • 216. SiteMap
    • 223. Examples what a “view”
    • 224. Setup Add Pretty Filter in web.xml <filter> <filter-name>Pretty Filter</filter-name> <filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class> </filter> <filter-mapping> <filter-name>Pretty Filter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>
    • 225. Map your first pages Create /WEB-INF/pretty-config.xml <pretty-config xmlns=&quot;http://ocpsoft.com/prettyfaces-xsd&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://ocpsoft.com/prettyfaces-xsd http://ocpsoft.com/xml/ns/prettyfaces/pretty-1.0.xsd&quot; > <url-mapping id=&quot;home&quot;> <pattern> /home </pattern> <view-id> /faces/home.jsf </view-id> </url-mapping> <url-mapping id=&quot;viewComment&quot;> <pattern value=”/story/#{myBean.currentStoryId}/#{myBean.commentId}” /> <view-id>/faces/story/comment.jsf</view-id> </url-mapping> </pretty-config>
    • 226. Add some actions Take action ;) <pretty-config xmlns=&quot;http://ocpsoft.com/prettyfaces-xsd&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://ocpsoft.com/prettyfaces-xsd http://ocpsoft.com/xml/ns/prettyfaces/pretty-1.0.xsd&quot; > <url-mapping id=&quot;home&quot;> <pattern> /home </pattern> <view-id> /faces/home.jsf </view-id> <action> #{homeBean.loadUserLayout} </action> </url-mapping> <url-mapping id=&quot;viewComment&quot;> <pattern value=”/story/#{myBean.currentStoryId}/#{myBean.commentId}” /> <view-id>/faces/story/comment.jsf</view-id> <action> #{myBean.load} </action> </url-mapping> </pretty-config>
    • 227. Validate (2.0.x series only) <pretty-config xmlns=&quot;http://ocpsoft.com/prettyfaces-xsd&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://ocpsoft.com/prettyfaces-xsd http://ocpsoft.com/xml/ns/prettyfaces/pretty-1.0.xsd&quot; > <url-mapping id=&quot;home&quot;> <pattern> /home </pattern> <view-id> /faces/home.jsf </view-id> <action> #{homeBean.loadUserLayout} </action> </url-mapping> <url-mapping id=&quot;viewComment&quot;> <pattern value=”/story/#{myBean.currentStoryId}/#{myBean.commentId}”> <validate param=”0” validatorIds=”integerValidator” /> <validate param=”1” validatorIds=”integerValidator” /> </pattern> <view-id>/faces/story/comment.jsf</view-id> <action>#{myBean.load}</action> </url-mapping> </pretty-config>
    • 228. Navigate viewComment.xhtml <%@ taglib prefix=&quot;pretty&quot; uri=&quot;http://ocpsoft.com/prettyfaces&quot; %>   <pretty:link mappingId=&quot;comment&quot;> <f:param value=&quot;23&quot; /> <f:param value=&quot;5&quot; /> Go to Comment. (This is Link Text) </pretty:link>   <pretty:link mappingId=&quot;comment&quot;> <f:param value=&quot;#{myBean.storyId}&quot; /> <f:param value=&quot;#{myBean.nextCommentId}&quot; /> View next comment. (This is Link Text) </pretty:link>
    • 229. The SiteMap If this presentation were a website... <pretty-config xmlns=&quot;http://ocpsoft.com/prettyfaces-xsd&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://ocpsoft.com/prettyfaces-xsd http://ocpsoft.com/xml/ns/prettyfaces/pretty-1.0.xsd&quot; > <url-mapping id=&quot;home&quot;> <pattern> /prettyfaces </pattern> <view-id> /faces/home.jsf </view-id> </url-mapping> <url-mapping id=&quot;levelOne&quot;> <pattern> /prettyfaces/#{presBean.levelOne} </pattern> <view-id> /faces/present.jsf </view-id> </url-mapping> <url-mapping id=&quot;levelTwo&quot;> <pattern> /prettyfaces/#{presBean.levelOne}/#{presBean.levelTwo} </pattern> <view-id> /faces/present.jsf </view-id> </url-mapping> </pretty-config>
    • 230. Questions? Lincoln Baxter, III Founder of O cpSoft @lincolnthree http://ocpsoft.com http://scrumshark.com http://ocpsoft.com/prettyfaces http://ocpsoft.com/prettytime