I'm having a problem with relative URLs. 
 
If the current page is:
 
content/mypage/n1/p1/n2/fred
 
And it contains a link to 
 
content/mypage/n1/p1/n2/jane
 
The relative URL rendered to HTML is:
 
../../../../../../jane
 
Which of course is wrong as the browser tries to jump to:
 
jane
 
instead of
 
content/mypage/n1/p1/n2/jane
 
 
I looked at the URL renderer and it was returning just 'jane' instead of
../jane
 
I'm not sure if this is the right approach but I changed
UrlRenderer.java (seemed like an 'out by 1' bug) so that it returns the
correct relative URL string. The git diff with a very recent
wicket-1.5.x branch HEAD is shown below.
 
../jane
 
Even though this now returns the correct relative URL this doesn't the
problem. Somehow later at render time the extra ../../../../ sequence
was prefixed to the already correct URL.
 
I think I know why - the URL is double processed by the UrlRenderer.
 
First it is converted from a Url object to a relative string via String
UrlRenderer.renderRelativeUrl(final Url url)  - returning ../jane as
above (after patch is applied).
 
Second, during rendering it is passed to
RelativePathPrefixHandler.onComponentTag which makes a relative path of
the path that is already relative, using String
UrlRenderer.renderContextRelativeUrl(String url) - of course this time
there is no common path segments so the sequence of ../ segments
prefixed to the given URL string takes it right back to the root.
 
Why would the relative path be processed again?
 
I can understand that UrlRenderer might need two relative Url creation
methods - one that works on a Url object and one that works on a String
object but I can't understand why both would be called as that breaks
things.
 
Path to 'fix' (maybe, if it is actually broken)
UrlRenderer.renderRelativeUrl(final Url url).
 
index d636450..ebe87f5 100644
---
a/wicket-request/src/main/java/org/apache/wicket/request/UrlRenderer.jav
a
+++
b/wicket-request/src/main/java/org/apache/wicket/request/UrlRenderer.jav
a
@@ -25,6 +25,8 @@ import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.string.PrependingStringBuffer;
 import org.apache.wicket.util.string.Strings;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * Takes care of rendering URLs.
  * <p>
@@ -211,30 +213,41 @@ public class UrlRenderer
                                }
                        }
 
-                       // we want the new URL to have at least one
segment (other than possible ../)
-                       if ((last != null) && (urlSegments.isEmpty() ||
(baseUrlSegments.size() == common)))
-                       {
-                               --common;
-                               urlSegments.add(0, last);
-                       }
-
-                       int baseUrlSize = baseUrlSegments.size();
-                       if (common + 1 == baseUrlSize &&
urlSegments.isEmpty())
+                       if ( common > 0 )
                        {
-                               newSegments.add(".");
+                               // URL has some elements common to
baseUrl so output a relative URL
+
+                               // we want the new URL to have at least
one segment (other than possible ../)
+                               if ((last != null) &&
(urlSegments.isEmpty() || (baseUrlSegments.size() == common)))
+                               {
+                                       --common;
+                                       urlSegments.add(0, last);
+                               }
+
+                               int baseUrlSize =
baseUrlSegments.size();
+                               if (common + 1 == baseUrlSize &&
urlSegments.isEmpty())
+                               {
+                                       newSegments.add(".");
+                               }
+                               else
+                               {
+
+                                       for (int i = common; i <
baseUrlSize; ++i)
+                                       {
+                                               newSegments.add("..");
+                                       }
+                               }
+                               newSegments.addAll(urlSegments);
+
+                               String renderedUrl = new
Url(newSegments, url.getQueryParameters()).toString();
+                               return Strings.isEmpty(renderedUrl) ?
"." : renderedUrl;
                        }
                        else
                        {
-
-                               for (int i = common + 1; i <
baseUrlSize; ++i)
-                               {
-                                       newSegments.add("..");
-                               }
+                               // Url has no common elements so convert
to an absolute URL
+                               return "/" + url.toString();
                        }
-                       newSegments.addAll(urlSegments);
-
-                       String renderedUrl = new Url(newSegments,
url.getQueryParameters()).toString();
-                       return Strings.isEmpty(renderedUrl) ? "." :
renderedUrl;
+                }

Reply via email to