Just turned SEF on and inner page images where gone

Did you had this experience? Couple of days ago I just turned on SEF and the inner pages began to act weird - images disappeared, modules misbehaved, scripts weren't loaded...

My first reaction was that I have set something wrong... or the SEF component I used have a flaw. After few days of digging I found that the issue has a much simpler cause.

Joomla 1.5 introduced a new system plugin, which was unnoticed by many of us, the system SEF plugin, which by default is unpublished.

So the fix might be as simple as turn that plugin on! To not be that simple, I discovered, that with older Joomla 1.5 releases the plugin was added as a Content plugin, not as system plugin, and enabling it does not solves the issue. For these older Joomla versions, which - for some reason - can't be upgraded (not be surprised, I needed to fix the problem in a badly cross-hacked Joomla 1.5.14 install Evil) you need to change this, and make from that plugin a system plugin, using this SQL query:

UPDATE `jos_plugins` SET `ordering` = `ordering` + 1 WHERE `folder` LIKE "system";
UPDATE `jos_plugins` SET `name` = "System - SEF", `folder` = "system", `ordering` = 1 WHERE element LIKE "sef";

But from where all this problem is coming from?

To understand the issue you should know, that all Joomla websites have a <base> tag that is dynamically created for each page and every page. The path and file name in the <base /> tag is equal to the current page's location, which is the proper coding according to W3C. And Joomla makes everything, that your internal references, to images, inner page links, loaded CSS files, scripts etc. to be W3C compliant, using relative links. So, for example a link in the page http://example.com/path1/somedoc.html to an internal page should look like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head>
<base href=http://example.com/path1/ />
...
</head>
<body>
....
<a href="/seo_page.html">anchor</a>
</body>
</html> 

So far so good - but this is an ideal stage. The core Joomla engine - as was launched in the 1.5 version - could not handle this correctly. The page's <base> tag is generated as in the above example, BUT the internal links where created relatively to the Joomla's site root, so in fact the above example looked like:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head>
<base href=http://example.com/path1/ />
...
</head>
<body>
....
<a href="/path1/seo_page.html">anchor</a>
</body>
</html> 

obviously resulting in a link pointing to http://example.com/path1/path1/seo_page.html instead of the correct http://example.com/path1/seo_page.html. And this problem is solved by the new SEF plugin.