Please pardon my brashness as a newcomer here, but the RELATIVE_URLS + SITEURL behavior is broken, because it is being misused for several purposes. I see things like this scattered around templates:
{{ SITEURL }}/{{ article.url }}
What you get out with RELATIVE_URLS = False is correct (e.g. http://example.com/blog/posts/2015/05/funfunfun/), but if RELATIVE_URLS = True, although it's technically correct, the instantiated template really goes all the way up the tree and then back down, e.g. you get things like ../../../../blog/posts/2015/05/funfunfun.
There are several requirements for URLs in a static site, and they are sometimes different even in the same site. RELATIVE_URLS affects _all_ instances of SITEURL. What is really needed is a per-use way of stating whether you want a relative or absolute URL from a given reference:
For example, suppose I am on a page http://abcxyz.com/blog/posts/123.html and I want a link to http://abcxyz.com/blog/themes/foobar.css. I can state this link as
../themes/foobar.css (relative url)http://abcxyz.com/blog/themes/foobar.css (full absolute url, breaks if served via multiple aliases)/blog/themes/foobar.css (path portion of url)I would much rather see a function provided to the jinja2 template than the use of {{SITEURL}}/{{someurl}}, in other words something like these:
{{ relative_url( someurl ) }}
{{ absolute_url( someurl ) }}
{{ url_path( someurl ) }}
This allows the choice to be made on a case-by-case basis at each point of use.
I ended up using a workaround of this in my pelicanconf.py:
SITEURL = 'http://my.website.com'
SITEURL_ABS = SITEURL
and then using SITEURL_ABS in my theme when I need an absolute path, since it doesn't get touched by the URL relativizer the way SITEURL does.
Jinja functions might work for templates but that's not the whole story. There are also internal links in content. RELATIVE_URLS + SITEURL also affects those. How to handle them?
RELATIVE_URLS, right now, acts as a global switch. If you enable, you'll get relative urls everywhere except hardcoded urls (if you setup correctly).
Regarding your "workaround", I think that's a decent way of accomplishing what you want.
This is a problem for me too. I used the SITEURL_ABS solution, but it is a hack.
@avaris we could substitute new {absolute_ref} and {relative_ref} keywords to expand on existing behavior, and supply the new jinja functions.
might happen sometime in the future, but I think we have more urgent things in the queue
Same problem for me as well. My personal preference is using root-relative URLs wherever possible (and absolute otherwise, e.g. with feeds), but I suspect that another facet of the problem is that root-relative URLs don't reliably work for folks who don't use an HTTP server when developing locally.
+1 for interest, I think this issue urgently needs attention.
The situation is further confused for people like me who are sometimes looking to develop/preview locally (where the test server defaults to putting the entire site under "/" as the root URL) but for production want to deploy in such a way that the whole site will be hosted under "/foo". Shouldn't there be a separate concept of DOCUMENT_ROOT or something?
Regardless of whether different themes are using {{SITEURL}} everywhere they should, there's the separate matter of markdown links in content. The easiest thing to do to make links work everywhere as expected is to make the development setup more closely mirror the production one, so I think the test server also potentially needs to take into account SITEURL / RELATIVE_URLS / DOCUMENT_ROOT instead of always putting everything under "/".
I can volunteer time to make fixes and submit pull-requests.. but I think there needs to be some consensus about the approach first?
+1 needs fix
Since SITEURL gets tampered by Pelican during RELATIVE_URL, how about if we introduce ABSOLUTE_URL and just make a copy of SITEURL with it?
pelican already allows you to define custom variables (ALL_UPPERCASE) and use them in templates freely. So you can easily do:
SITEURL = 'whatever'
ABSOLUTE_URL = SITEURL
This is AWESOME! It works!
I did the following:
SITEURL = 'https://example.com/
ABSOLUTE_URL = SITEURL
and if pelicanconf.py has RELATIVE_URLS == True, then it becomes:
SITEURL = ..
ABSOLUTE_URL = 'https://example.com'
And if RELATIVE_URLS == False, then it becomes:
SITEURL = 'https://example.com'
ABSOLUTE_URL = 'https://example.com'
Perfect.
Given the workarounds listed here, as well as the already-existing ability to use distinct settings for local development and production (which are automatically generated by pelican-quickstart), I think this topic has been sufficiently addressed.