Announcement Announcement Module
Collapse
No announcement yet.
Custom URLs Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Custom URLs

    Hi,

    I'd like my page URLs to look nicer than ${url.context}/${page.id} (eg /myapp/mypage). Case in point: my application is relevant to several types of people, say cats and mice. I'd like the generic pages to look like /myapp/everyone/pageid, the "cat" pages like /myapp/cats/pageid, and the "mice" pages like /myapp/mice/pageid.

    This is purely cosmetic, but it's nagging (also, I'd like to be able to tell Spring Security to restrict access to /cats/* to cats etc. Now I have to use coding conventions and tell my developers to create cat pages with ids like cat_pageid).

    Any idea? I surmise it'd mean writing a custom page mapper that would ignore the first token in the url.

  • #2
    You're always free to write custom ViewResolver and View implementations if you really need to wrangle the URLs to look like anything you want. You can even use REST annotations on top of controllers to completely control the ModelView creation process. Surf provides a LinkBuilder pattern so that you can use a common API to build links that respect your desired page URLs.

    That said, Surf 1.0.0.M3 (which is coming out tonight) features a URI template facility for resolution of pages and components. You can tell Surf about additional URLs and how to parse out tokens from those URLs that may identify the page as well as the context of the page.

    For example, you might want to have many URLs that point to the same page and which take in context in multiple ways. Even though they take in the context in many different ways, you'd like that context to be available to your pages in a consistent fashion.

    You could define four URLs:

    /site/{site}/{pageid}/{productId}?color={?color}&size={?size}
    /{pageid}/{productId}?color={?color}&size={?size}&site={site }
    /{pageid}/{productId}/{color}?size={?size}&site={site}
    /{pageid}/{productId}/{color}/{size}?site={site}

    These would all point to the same page and populate the request context with the same context. Multiple entry points to the same place.

    You could use the existing PageViewResolver for this (as it supports it). If you find that limiting, you can use the URI templates piece within your own view resolvers. If so, I'd like to know how it's limiting. That feedback would let us improve Surf for your specific scenario.

    Thanks!

    Michael

    Comment


    • #3
      I use URL short cuts which makes it easier to work with and post.

      Comment


      • #4
        URI Templates?

        Hi there!

        How can i use these URI Template feature or URL short cuts?? Cant find any documentation about this...


        thx and regards!

        Comment


        • #5
          Hi,
          I think the best way now is to implement your own controller.
          See UZIs post and this link.

          The 'LinkBuilder' sounds good. But I found no documentation about it.

          Comment


          • #6
            The URI templates mentioned earlier can do exactly what you want. In the Alfresco Share application we do pretty much exactly the same:

            Code:
            <alfresco-config>
               <config evaluator="string-compare" condition="UriTemplate">
                  <!-- list of URI based page Id templates used by Share -->
                  <!-- when pages are requested from the framework, matches are attempted
                       against each uri-template, and the token values returned if matched -->
                  <uri-templates>
                     <uri-template id="sitedashboardpage">/site/{site}/dashboard</uri-template>
                     <uri-template id="sitepage">/site/{site}/{pageid}</uri-template>
                     <uri-template id="userdashboardpage">/user/{userid}/dashboard</uri-template>
                     <uri-template id="userpage">/user/{userid}/{pageid}</uri-template>
                     <uri-template id="userprofilepage">/user/{userid}/profile</uri-template>
                     <uri-template id="userdefaultpage">/user/{pageid}</uri-template>
                     <uri-template id="consoletoolpage">/console/{pageid}/{toolid}</uri-template>
                     <uri-template id="consolepage">/console/{pageid}</uri-template>
                  </uri-templates>
               </config>
            </alfresco-config>
            You can add a similar override config block to your surf.xml config.

            So what does it mean? Basically it allows you to specify which part of the URL is used to represent the pageid for the lookup of the page Surf object - rather than the whole uri. It also allows you to "mark" or "template" parts of the url so they it will get automatically tokenized by surf and the values placed in the page.url.templateArgs map - which you can access from WebScript javascript. We do this a lot in Alfresco Share!

            For your example I think you want something like this:

            Code:
            <uri-template id="catpages">/cats/{pageid}</uri-template>
            <uri-template id="micepages">/mice/{pageid}</uri-template>
            The "id" of the template is simply a unique id - it is only used if you want to push them down to client-side javascript i.e so you could generate well known urls on the client. The {pageid} token is a well known token name that is known to Surf to mean "this bit of the url is the page id" - any other tokens you specify will simply get the name/value pairs added to the page.url.templateArgs map I mentioned ealier.

            Hope this helps!

            Kev

            Comment


            • #7
              Thanks for your detailed information.
              This is pretty cool. I will try it the next days.

              Comment


              • #8
                I am unable to create unique url's to my defined pages like the default "products" page and I question if the syntax is the problem, the syntax above is like

                <uri-templates>
                <uri-template id="products">/try/products</uri-template>

                </uri-templates>

                However I have seen other examples showing

                <uri-mappings>

                <uri-mapping>
                <uri-template>/try/products/</uri-template>
                <url-entry>/products</url-entry>
                </uri-mapping>

                </uri-mappings>

                These settings are in the surf.xml

                In the end neither work, the most basic question is, which syntax is correct?

                Desired would be any addition information on creating alternative urls like I'm attempting above

                /try/products works the same as /products

                I completely see how this can be done at the webscript level but those are internal urls, I need to manapulate the url's the brower sees which is at the page level.... right?

                Thanks

                Comment


                • #9
                  Hi,

                  You have spotted some old config that should be removed - infact I have removed it on the trunk codeline and it will be cleaner in RC1 release.

                  The config you want is the first type:
                  <uri-templates>
                  <uri-template id="products">/try/products</uri-template>
                  </uri-templates>

                  so:
                  /try/products works the same as /products

                  You define this:
                  Code:
                  <uri-templates>
                     <uri-template id="products">/try/{pageid}</uri-template>
                  </uri-templates>
                  Remember if you want to -rewrite- urls then edit the urlrewrite.xml - the uri-templates config is there to allow you to specify what *part* of the URL specifies the page ID to lookup - and as a helper to get parts of the url placed into a name/value templateArgs map for you.

                  Kev

                  Comment


                  • #10
                    Hi Kevin,

                    So let's see if I've understood it...

                    I've got a website with the blogs page in it (/blogs). I want it to be accessible through different urls (/blog/{year}, /blog/{author}, ...)

                    So what I did is the next in the surf.xml file:

                    Code:
                    <config evaluator="string-compare" condition="UriTemplate">
                          <uri-mappings>
                          	<uri-mapping>
                              	<uri-template>/blogs/{year}</uri-template>
                    		<url-entry>/blogs?year={year}</url-entry>
                    	</uri-mapping>
                    	<uri-mapping>
                            	<uri-template>/blogs/author/{author}</uri-template>
                    		<url-entry>/blogs?author={author}</url-entry>
                    	</uri-mapping>
                          </uri-mappings>
                       </config>
                    After trying it and seeing what you posted it seems it's wrong and that I've got to specify those mapping/rewrites in the urlrewrite.xml. Is that right?

                    Could you give me a hint on how to do it?

                    Thanks in advanced,
                    Adei

                    Comment


                    • #11
                      Yes that is a case for urlrewrite rather than urltemplate config:

                      http://www.tuckey.org/urlrewrite/manual/3.0/guide.html

                      I think your example would be this:

                      Code:
                      	<rule>
                      		<from>/blogs/(.*)</from>
                      		<to>/blogs?year=$1</to>
                      	</rule>
                      	<rule>
                      		<from>/blogs/author/(.*)</from>
                      		<to>/blogs?author=$1</to>
                      	</rule>
                      Thanks,

                      Kev

                      Comment


                      • #12
                        Hi again,

                        I did what you said, but it keeps saying

                        javax.servlet.ServletException: Could not resolve view with name 'blogs/2010' in servlet with name 'Spring MVC Dispatcher Servlet'
                        Any ideas?

                        Comment


                        • #13
                          I can see that the rule is there. If I go to http:localhost:8180/rewrite-status it's in there and everytime I change it it changes, so the rule is deployed

                          Comment


                          • #14
                            I assume you are using something based on the sample app, in which case the rule is probably going to look like this:

                            Code:
                            	<rule>
                            		<from>/blogs/author/(.*)</from>
                            		<to>/service/blogs?author=$1</to>
                            	</rule>
                            	<rule>
                            		<from>/blogs/(.*)</from>
                            		<to>/service/blogs?year=$1</to>
                            	</rule>

                            Comment


                            • #15
                              Hi Kevin,

                              Sorry, yes, I managed to solved it yesterday but forgot updating the post.

                              Thanks for the help

                              Comment

                              Working...
                              X