We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 54163
    • 24 Posts
    I've been playing with SEOTab and trying to style the sitemap.xml to get a human readable file with the look of the rest of the site. The current result can be seen at https://fakenews.com/sitemap.xml . The key is the included sitemap.xsl. Part of the xsl is a html template. At the moment the xsl is a MODX resource with the pasted output from another completed page into the template part. To keep it in sync I would like to get the template/page from a snippet, but how?

    A few other options are to add conditional chunks with the surrounding xsl at the top and bottom of my normal template. Or add substitution filters to Apache/Nginx. Or add a MODX plugin. But doing it in a snippet would do best for my learning.

    With this tool I would have an alternative to loading data with json into a page. Instead, load a page around data.

    This question has been answered by multiple community members. See the first response.

    [ed. note: alipang last edited this post 5 years, 11 months ago.]
      Fake News is powered by MODX — https://fakenews.com/
    • discuss.answer
      • 3749
      • 24,544 Posts
      Try this:

      file_get_contents(’url_to_resource’)


      If that doesn't work, you could use cURL.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
      • discuss.answer
        • 54163
        • 24 Posts
        Thanks Bob! That was a quick fix. I digged a bit deeper and found how to stay away from the network layer. Let me share all the fun step-by-step. Some of them are probably totally unnecessary.

        1. Install the SEOTab Extra.
        2. The StercSeoSiteMap snippet currently only has placeholders for a regular sitemap, but we want to extend the xml a little. Patch core/components/stercseo/model/stercseo/stercseo.class.php and make the chunk call look like
          $output .= $this->getChunk(
          $rowTpl,
          array(
          'url' => $this->modx->makeUrl($resource->get('id'), '', '', 'full'),
          'lastmod' => date('c', $lastmod),
          'changefreq' => (!empty($properties['changefreq']) ? $properties['changefreq'] : $this->defaults['changefreq']),
          'priority' => (!empty($properties['priority']) ? $properties['priority'] : $this->defaults['priority']),
          'pagetitle' => $resource->get('pagetitle'),
          'id' => $resource->get('id'),
          'createdby' => $resource->get('createdby')
          )
          );
        3. Add content types
          • XSD text/xml .xsd
          • XSL text/xsl .xsl
        4. Add resource (85), aliased sitemap with type XML and content
          [[!StercSeoSiteMap? &outerTpl=`SitemapWrapper` &rowTpl=`SitemapRow`]]
        5. Add resource containers (87,88,89) below each other to mimic a namespace structure like "http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd". Alias them to the name of your schema extension. I made a resource (90), aliased fakesite with type XSD and content
          <?xml version="1.0"?>
          <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
          <xs:simpleType name="title">
          <xs:restriction base="xs:string" />
          </xs:simpleType>

          <xs:simpleType name="description">
          <xs:restriction base="xs:string" />
          </xs:simpleType>

          <xs:simpleType name="author">
          <xs:restriction base="xs:string" />
          </xs:simpleType>

          <xs:simpleType name="authorUrl">
          <xs:restriction base="xs:string" />
          </xs:simpleType>
          </xs:schema>

        6. Add chunk SitemapWrapper with content
          <?xml version="1.0" encoding="[[++modx_charset]]"?>
          <?xml-stylesheet type="text/xsl" href="[[~86? &scheme=`full`]]"?>

          <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:fakesite="[[~89? &scheme=`full`]]"
          xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
          http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd
          [[~89? &scheme=`full`]]
          [[~90? &scheme=`full`]]">
          [[+wrapper]]</urlset>
        7. Add chunk SitemapRow with content
          <url>
          <loc>[[+url]]</loc>
          <lastmod>[[+lastmod]]</lastmod>
          <changefreq>[[+changefreq]]</changefreq>
          <priority>[[+priority]]</priority>
          <fakesite:title>[[+pagetitle]]</fakesite:title>
          <fakesite:author>[[+createdby:userinfo=`fullname`]]</fakesite:author>
          </url>
        8. Begin the magic. Add resource (86), aliased sitemap, type XSL, this time containing
          <?xml version="1.0" encoding="UTF-8"?>
          <!-- xml entities are not as defined as html entities. Define a few missing -->
          <!DOCTYPE transform [
          <!ENTITY nbsp "& #x000A0;">
          <!ENTITY ndash "& #x02013;">
          <!ENTITY mdash "& #x02014;">
          <!ENTITY copy "& #x000A9;">
          <!ENTITY hellip "& #x2026;">
          ]>
          <xsl:stylesheet version="1.0"
          xmlns:html="http://www.w3.org/1999/xhtml"
          xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
          xmlns:fakesite="[[~89? &scheme=`full`]]"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:output method="html" doctype-system="about:legacy-compat"/>
          <xsl:template match="/">
          [[-
          Fetch the fully parsed content of a resource only having content <xsl:apply-templates></xsl:apply-templates>
          Alias it sitemap and let it's content type be HTML
          ]]
          [[!MakeXSLT? &resourceid=`91`]]
          </xsl:template>

          <xsl:template match="sitemap:urlset">
          <h3>XML Sitemap</h3>
          <table cellpadding="5">
          <tr style="border-bottom:1px black solid;">
          <th>Title</th>
          <th>Priority</th>
          <th>Change frequency</th>
          <th>Last modified (GMT)</th>
          </tr>
          <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyzåäö'"/>
          <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ'"/>
          <xsl:for-each select="./sitemap:url">
          <tr>
          <xsl:if test="position() mod 2 != 1">
          <xsl:attribute name="class">high</xsl:attribute>
          </xsl:if>
          <td>
          <xsl:variable name="itemURL">
          <xsl:value-of select="sitemap:loc"/>
          </xsl:variable>
          <xsl:variable name="itemTitle">
          <xsl:value-of select="fakesite:title"/>
          </xsl:variable>
          <a href="{$itemURL}">
          <xsl:value-of select="fakesite:title"/>
          </a>
          </td>
          <td>
          <xsl:value-of select="concat(sitemap:priority*100,'%')"/>
          </td>
          <td>
          <xsl:value-of select="concat(translate(substring(sitemap:changefreq, 1, 1),concat($lower, $upper),concat($upper, $lower)),substring(sitemap:changefreq, 2))"/>
          </td>
          <td>
          <xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))"/>
          </td>
          </tr>
          </xsl:for-each>
          </table>
          </xsl:template>

          <xsl:template match="sitemap:sitemapindex">
          <h3>XML Sitemap Index</h3>
          <table cellpadding="5">
          <tr style="border-bottom:1px black solid;">
          <th>URL of sub-sitemap</th>
          <th>Last modified (GMT)</th>
          </tr>
          <xsl:for-each select="./sitemap:sitemap">
          <tr>
          <xsl:if test="position() mod 2 != 1">
          <xsl:attribute name="class">high</xsl:attribute>
          </xsl:if>
          <td>
          <xsl:variable name="itemURL">
          <xsl:value-of select="sitemap:loc"/>
          </xsl:variable>
          <a href="{$itemURL}">
          <xsl:value-of select="sitemap:loc"/>
          </a>
          </td>
          <td>
          <xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))"/>
          </td>
          </tr>
          </xsl:for-each>
          </table>
          </xsl:template>
          </xsl:stylesheet>
        9. Add the document serving as our xsl template (91). Use your site's template. Let the only content be
          <xsl:apply-templates></xsl:apply-templates>
          Alias it sitemap (our third), and let the content type be HTML.
        10. Almost there. The final piece is what this post addressed. Add snippet MakeXSLT.
          <?php
          $currentResource = $modx->resource;
          $currentResourceIdentifier = $modx->resourceIdentifier;
          $currentElementCache = $modx->elementCache;

          $resource = $modx->getObject('modResource', $resourceid);
          $modx->getParser();
          $maxIterations = intval($modx->getOption('parser_max_iterations', null, 10));
          $modx->resource =& $resource;

          $modx->elementCache = array();
          $resourceOutput = $modx->resource->process();
          $modx->parser->processElementTags('', $resourceOutput, true, false, '[[', ']]', array(), $maxIterations);
          $modx->parser->processElementTags('', $resourceOutput, true, true, '[[', ']]', array(), $maxIterations);

          $modx->elementCache = $currentElementCache;
          $modx->resourceIdentifier = $currentResourceIdentifier;
          $modx->resource = $currentResource;

          // DOCTYPE must vanish
          $resourceOutput = str_replace("<!DOCTYPE html>", "", $resourceOutput);

          return $resourceOutput;
        [ed. note: alipang last edited this post 5 years, 11 months ago.]
          Fake News is powered by MODX — https://fakenews.com/
          • 3749
          • 24,544 Posts
          Thanks for posting that. smiley
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting