Let's move the XSL stylesheet _inline_.
See: https://stackoverflow.com/questions/7132106/using-inline-xslt-for-an-xml-file
For context:
This should fix a large amount of issues related to the XML sitemap being blank because the XSLT doesn't load. Additionally, this fixes a performance issue as we don't have to boot WordPress twice for an XML sitemap view.
I've tried the suggested situation and was not able to get something that works:
<xsl:if test="count(/sitemapindex/sitemap) < 1"> should be rewritten to get it working with the inline stylesheet.I've committed the branch:8521-load-xml-stylesheet-inline
This is the first example I've tried to get context on how an inline stylesheet should work.
<?xml version="1.0" encoding="utf-8"?>
<!--Reference the file name as the href value-->
<?xml-stylesheet type="text/xsl" href=""?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"
>
<!-- Output HTML doctype with text/html content-type and without XML declaration-->
<xsl:output method="xml" encoding="utf-8" version="" indent="yes" standalone="no" media-type="text/html" omit-xml-declaration="yes" doctype-system="about:legacy-compat" />
<!-- Read the children of the stylesheet itself -->
<xsl:template match="xsl:stylesheet">
<xsl:apply-templates/>
</xsl:template>
<!-- Output the HTML markup-->
<xsl:template match="/">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<div class="foo">
<span class="bar">
<span class="baz">1</span>
</span>
<!--Added comment to fill empty node-->
<span class="placeholder"><xsl:comment/></span>
</div>
<!-- Read matching templates -->
<xsl:apply-templates />
<!--Add comment to fill empty script tag-->
<script src="foo.js" type="application/x-javascript"><xsl:comment/></script>
</body>
</html>
</xsl:template>
<!-- Don't reprint text nodes within the xsl:stylesheet node -->
<xsl:template match="text()"/>
<!-- Read non-namespaced nodes within the xsl:stylesheet node -->
<xsl:template match="//node()[local-name() = name()]">
<xsl:if test="local-name() = 'foo'">
<xsl:variable name="foo" select="."/>
<input type="text" id="{$foo}" value="{$foo}"></input>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
<test>
<foo>A</foo>
<foo>B</foo>
<foo>C</foo>
</test>
</xsl:stylesheet>
It seems that the XML Sitemap ruleset prevents the root element (sitemapindex etc) from being embedded inside a xml:template element.
As this works for generic XML files, applying it to Sitemaps proofs rather difficult.
@jrfnl do you have any additional insights on possibilities to provide this functionality, or why it will not work?
do you have any additional insights on possibilities to provide this functionality, or why it will not work?
@moorscode Not off the top of my head. I'd need to do some research myself.
It seems that the XML Sitemap ruleset prevents the root element (sitemapindex etc) from being embedded inside a xml:template element.
Could you expand on this a bit ? What do you mean by _Sitemap ruleset_ ? Do you mean the DTD ?
Additionally, this fixes a performance issue as we don't have to boot WordPress twice for an XML sitemap view.
That is one thing which I've often wondered about too and which I think could be solved quite easily.
In the WPSEO XSL file, there are only five PHP calls.
Two of which are shortlinks to the Yoast site and three are URLs which need to take the site in which the file is being used into account.
All of this could be "hard-coded"/cached. I.e. on install, the file could be generated based on the current file as template and written to disk.
On upgrade of WPSEO, update of the home_url and possibly in a weekly cronjob or something, the file on disk could be regenerated to make sure it is in sync.
This action could also be added to the queue for when the sitemaps are completely regenerated on demand from the dashboard.
A note should be made in the docs that if someone uses constants in the wp-config file to define the PLUGIN_URL or INCLUDE_URL, that if those are updated, the user should regenerate the sitemaps.
Would that help ?
We currently load the XLS via a registered route - see https://github.com/Yoast/wordpress-seo/blob/trunk/inc/sitemaps/class-sitemaps-router.php#L34
This means that we are loading the entire WordPress environment to be able to render the stylesheet.
The proposed solution is to determine if we can directly load the file, instead of going through WordPress. As WordPress .htaccess configuration by default has the entries to not rewrite files or directories that exist to index.php.
Pieces of PHP that need to be determined if they can be generated without having the WordPress context:
<?php echo esc_url( home_url( 'sitemap_index.xml' ) ); ?> reference<?php echo esc_url( includes_url( 'js/jquery/jquery.js' ) ); ?> -<?php echo esc_url( plugins_url( 'js/dist/jquery.tablesorter.min.js', WPSEO_FILE ) ); ?><?php echo esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1y5' ) ) ?><?php echo esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1y6' ) ) ?>@moorscode
Re point 1: let's remove it. Too much of a cost for too little gain.
Re points 2 and 3 above: I'm very ok with removing the sorting script altogether. Too much of a cost for too little gain.
Point 4 then is an easy fix.
Basically this means this can become a static XSL file, as discussed with @moorscode yesterday.
Most helpful comment
For context:
This should fix a large amount of issues related to the XML sitemap being blank because the XSLT doesn't load. Additionally, this fixes a performance issue as we don't have to boot WordPress twice for an XML sitemap view.