You could just make an XSLT Macro to create the XML, and have a page with just the Macro in. I've used a similar technique to produce google sitemaps. You can use the sitemap XSLT template as a basis if you want. There's a library method you can call to chnage the content type from text/html to XSLT as well, which you can call like this:
Thanks for the reply. Jan, I had a look at the link you sent. The code with it was a little light on. I need a little more to get me going. Tim's suggestion sounded good and I wanted to explore it. I have made the decision to use Umbraco and I need some secure pages, so I will need to generate the structure somehow and use in pages that are outside the CMS, as Umbraco does not support SSL, which is a shame.
All I need is a little code to get me going as I'm under pressure to get this website done.
Can either of you elborate on the solutions that you have provided please?
If you create a new XSLT File in the developer section, you'll get the option to select a template, one of them is sitemap, that should give you an idea of how to write out the site structure. If you want a more complex example, this is a Macro that generates a google sitemap for a site, sets the content type to XML, and excludes certain DocTypes from the map. There's a bunch of properties I check in the script that won't be relevant to you, but it should give you an idea of how to do it:
<!-- ==================================================== This XSLT creates an XML sitemap used for search engines. Following these guidelines http://www.sitemaps.org ==================================================== -->
<!-- ==================================================== We setup two parameters.
maxLevelForSitemap allows you to configure how deep the sitemap should go.
url is the root url - eg: http://localhost ==================================================== --> <xsl:variable name="maxLevelForSitemap" select="8"/> <xsl:variable name="url" select="concat('http://',umbraco.library:RequestServerVariables('HTTP_HOST'))" />
<xsl:template match="/"> <!-- change the mimetype for the current page to xml --> <xsl:value-of select="umbraco.library:ChangeContentType('text/xml')"/> <xsl:text disable-output-escaping="yes"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>]]></xsl:text> <xsl:text disable-output-escaping="yes"><![CDATA[<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">]]></xsl:text> <!-- ==================================================== This <URL> node is for the homepage/root page ==================================================== --> <url> <loc> <xsl:value-of select="concat($url,'/')"/> </loc> <lastmod> <xsl:value-of select="concat($currentPage/ancestor-or-self::node [@level=1]/@updateDate,'+00:00')" /> </lastmod> <priority> <xsl:choose> <xsl:when test="string($currentPage/ancestor-or-self::node [@level=1]/googlePriority) > '0'"> <xsl:value-of select="$currentPage/ancestor-or-self::node [@level=1]/googlePriority"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="0.5"/> </xsl:otherwise> </xsl:choose> </priority> </url>
<!-- ==================================================== RUN template drawNodes passing the parent variable as the ROOT node. ==================================================== --> <xsl:call-template name="drawNodes"> <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@level=1]"/> </xsl:call-template> <xsl:text disable-output-escaping="yes"><![CDATA[</urlset>]]></xsl:text> </xsl:template>
<!-- ==================================================== If the parent variable is NOT protected ==================================================== --> <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0"> <!-- ==================================================== For each CHILD node of the parent variable node WHERE umbracoNaviHide is NOT true AND the node's level is less than and equal to the maxLevelForSitemap variable. ==================================================== --> <xsl:for-each select="$parent/* [@isDoc and string(./umbracoNaviHide) != '1' and string(hideFromSitemap) != '1' and @level <= $maxLevelForSitemap and contains($ignoreDocTypes, concat('#', Exslt.ExsltStrings:uppercase(name()), '#')) = 0]"> <!-- Do not show the node if it is a page section, as a page section has no physical page --> <xsl:if test="name() != 'PageSection'"> <url> <loc> <xsl:choose> <xsl:when test="name() = 'Home'"> <xsl:attribute name="href"> <xsl:text>/</xsl:text> </xsl:attribute> </xsl:when> <xsl:otherwise> <xsl:value-of select="$url"/> <xsl:value-of select="umbraco.library:NiceUrl(@id)"/> </xsl:otherwise> </xsl:choose> </loc> <lastmod> <xsl:value-of select="concat(@updateDate,'+00:00')" /> </lastmod> <priority> <xsl:choose> <xsl:when test="string(googlePriority) > '0'"> <xsl:value-of select="googlePriority"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="0.5"/> </xsl:otherwise> </xsl:choose> </priority> </url> </xsl:if>
<!-- ==================================================== IF the number of child nodes from the current node in the for-each loop WHERE umbracoNaviHide is NOT true AND the node's levels are less than and equal to the maxLevelForSitemap variable is GREATER than 0. ==================================================== --> <xsl:if test="count(current()/* [@isDoc and string(./umbracoNaviHide) != '1' and @level <= $maxLevelForSitemap and contains($ignoreDocTypes, Exslt.ExsltStrings:uppercase(name())) = 0]) > 0"> <!-- ==================================================== As we have further child nodes recall the same template we are in with the parent variable set to as the current node in the for-each loop. ==================================================== --> <xsl:call-template name="drawNodes"> <xsl:with-param name="parent" select="current()"/> </xsl:call-template> </xsl:if> </xsl:for-each> </xsl:if> </xsl:template>
</xsl:stylesheet>
Not sure what you mean when you say Umbraco doesn't support SSL. I've had areas of Umbraco sites run over SSL before. Is there something specifc that you're trying to do?
1) Create the navigation XSLT macro that should generate the XML for you based on the predefined Sitemap XSLT snippet.
2) Modify the snippet so it outputs proper xml elements. For instance turn the <div id="sitemap"></div> into <root></root> and the ul to for instance <menu></menu> and the li to <page></page> or whatever you think is the proper structure for your sitemap. Place the <xsl:value-ofselect="umbraco.library:ChangeContentType('text/xml')"/> somewhere in the template(preferably in the start)
to make sure the document gets the correct mime-type once you insert the macro into the template you'll be using to
create the XML document.
3) Create a template called something like "XMLnavigation" in the template section. Add the XML prolog to the template and place the macro right after it.
4) Now you should be able to access the XML by going to www.yoursite.com/yourxmltemplate.aspx which is the url you need to import in your project outside of Umbraco.
I hope this makes sense to you.
I think that it really should be able to use SSL with Umbraco, but I must admit that I don't know how to do it currently.
I also still have a suspicion that the above could be created more elegantly using /base. But since you're in a hurry I think you should give the above a try.
Wow. Thanks for the response everybody. I will try this code (from Tim's post tomorrow), thank you. Tim as far as the SSL goes. I was told that the lastest version of Umbraco didn't support HTTPS urls.
So my proposal was to have a secure folder with a few custom navigation links pointing to that secure folder and that folder would be requiring SSL. Is there another approach that you can recommend? Part of that was to generate and xml navigation structure for these pages to read from, as the Umbraco macro's didn't work in those pages when I tried it.
I've not tried it on the latest version of Umbraco (the last site I did that had SSL was using 4.5.2.
All I did was set up some rewrites using the UrlRewriting config so that everything under certain URLS had to be under SSL, if it wasn't it 301 redirected to the SSL URL. I then had a nother rule that said anything else that was over SSL that wasn't in those folders should be 301'd to the non-SSL page.
So for example, everything under /users could only be accessed via https, and everything else could only be accessed via http. Other than that, nothing was different.
Are you trying to have a members area? If so, you might want to look into the protecting pages with the membership API.
Hi Tim , I'm trying to understand your solution. So you were able to create pages in Umbraco, and the assign them a https URL using the default URL rewrite capability? 0r Dod you write your own for this ?
Thanks ind advance.
Kind regards,
Sean
Did you manage to get it solved? And if so would you care describe the steps you took so others can benefit if they come accross this post in the future? :-)
Hi Jan, I have not solved it as yet. It has partially answered my question. I'm having to generate the structure on page load from c# , then read and embellish it. The last part is the 301 redirects which I'm doing inside each secure template.
It's going to be a thesis, when I solve it I will post the solution. Give me few weeks.
Sean
Generating the navigation structure to xml file
Hi There,
I'm wondering how I generate the navigation structure of all the nodes to xml. If anyone has a code snippet please?
Thanks in advance.
Sean
Hi Sean
I've made some suggestions in the old post in case you missed them: http://our.umbraco.org/forum/developers/extending-umbraco/17709-Secure-pages-In-umbraco?p=1#comment66926
But it's probably also possible to generate it using some C#...I just don't know how. But probably some of the other great people in here does :-)
/Jan
Hi Sean,
Are you wanting physical XML file, or just have it on a URL for web services etc to get to?
Hi Tim , it would be nice to have a webservice URL to access . Have you done this before? Kind regards, Sean
You could just make an XSLT Macro to create the XML, and have a page with just the Macro in. I've used a similar technique to produce google sitemaps. You can use the sitemap XSLT template as a basis if you want. There's a library method you can call to chnage the content type from text/html to XSLT as well, which you can call like this:
<xsl:value-of select="umbraco.library:ChangeContentType('text/xml')"/>
Hope that helps!
:)
Tim's suggestion is the best route!
Which is similiar to the one I suggested in the post I'm reffering too above ;-)
But would'nt /Base actually be better performance-wise?
/Jan
Hi all,
Thanks for the reply. Jan, I had a look at the link you sent. The code with it was a little light on. I need a little more to get me going. Tim's suggestion sounded good and I wanted to explore it. I have made the decision to use Umbraco and I need some secure pages, so I will need to generate the structure somehow and use in pages that are outside the CMS, as Umbraco does not support SSL, which is a shame.
All I need is a little code to get me going as I'm under pressure to get this website done.
Can either of you elborate on the solutions that you have provided please?
Sean
Hiya,
If you create a new XSLT File in the developer section, you'll get the option to select a template, one of them is sitemap, that should give you an idea of how to write out the site structure. If you want a more complex example, this is a Macro that generates a google sitemap for a site, sets the content type to XML, and excludes certain DocTypes from the map. There's a bunch of properties I check in the script that won't be relevant to you, but it should give you an idea of how to do it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:umbraco.contour="urn:umbraco.contour" xmlns:Designit.VideoEmbed="urn:Designit.VideoEmbed"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets umbraco.contour Designit.VideoEmbed ">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:variable name="ignoreDocTypes" select="Exslt.ExsltStrings:uppercase('#contentCreditlineArticle#DateFolder#contentEvent#contentCaseStudy#contentIndustryMinuteArticle#contentNewsArticle#contentIndustryNewsArticle#contentResearchAndInsightArticle#contentTestimonial#contentVacancy#')"/>
<!--
====================================================
This XSLT creates an XML sitemap used for search
engines. Following these guidelines
http://www.sitemaps.org
====================================================
-->
<!--
====================================================
We setup two parameters.
maxLevelForSitemap allows you to configure how deep
the sitemap should go.
url is the root url - eg: http://localhost
====================================================
-->
<xsl:variable name="maxLevelForSitemap" select="8"/>
<xsl:variable name="url" select="concat('http://',umbraco.library:RequestServerVariables('HTTP_HOST'))" />
<xsl:template match="/">
<!-- change the mimetype for the current page to xml -->
<xsl:value-of select="umbraco.library:ChangeContentType('text/xml')"/>
<xsl:text disable-output-escaping="yes"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>]]></xsl:text>
<xsl:text disable-output-escaping="yes"><![CDATA[<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">]]></xsl:text>
<!--
====================================================
This <URL> node is for the homepage/root page
====================================================
-->
<url>
<loc>
<xsl:value-of select="concat($url,'/')"/>
</loc>
<lastmod>
<xsl:value-of select="concat($currentPage/ancestor-or-self::node [@level=1]/@updateDate,'+00:00')" />
</lastmod>
<priority>
<xsl:choose>
<xsl:when test="string($currentPage/ancestor-or-self::node [@level=1]/googlePriority) > '0'">
<xsl:value-of select="$currentPage/ancestor-or-self::node [@level=1]/googlePriority"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0.5"/>
</xsl:otherwise>
</xsl:choose>
</priority>
</url>
<!--
====================================================
RUN template drawNodes passing the parent variable
as the ROOT node.
====================================================
-->
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@level=1]"/>
</xsl:call-template>
<xsl:text disable-output-escaping="yes"><![CDATA[</urlset>]]></xsl:text>
</xsl:template>
<xsl:template name="drawNodes">
<xsl:param name="parent"/>
<!--
====================================================
If the parent variable is NOT protected
====================================================
-->
<xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0">
<!--
====================================================
For each CHILD node of the parent variable node
WHERE umbracoNaviHide is NOT true AND the node's
level is less than and equal to the
maxLevelForSitemap variable.
====================================================
-->
<xsl:for-each select="$parent/* [@isDoc and string(./umbracoNaviHide) != '1' and string(hideFromSitemap) != '1' and @level <= $maxLevelForSitemap and contains($ignoreDocTypes, concat('#', Exslt.ExsltStrings:uppercase(name()), '#')) = 0]">
<!-- Do not show the node if it is a page section, as a page section has no physical page -->
<xsl:if test="name() != 'PageSection'">
<url>
<loc>
<xsl:choose>
<xsl:when test="name() = 'Home'">
<xsl:attribute name="href">
<xsl:text>/</xsl:text>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$url"/>
<xsl:value-of select="umbraco.library:NiceUrl(@id)"/>
</xsl:otherwise>
</xsl:choose>
</loc>
<lastmod>
<xsl:value-of select="concat(@updateDate,'+00:00')" />
</lastmod>
<priority>
<xsl:choose>
<xsl:when test="string(googlePriority) > '0'">
<xsl:value-of select="googlePriority"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0.5"/>
</xsl:otherwise>
</xsl:choose>
</priority>
</url>
</xsl:if>
<!--
====================================================
IF the number of child nodes from the current node
in the for-each loop WHERE umbracoNaviHide is NOT true
AND the node's levels are less than and equal to the
maxLevelForSitemap variable is GREATER than 0.
====================================================
-->
<xsl:if test="count(current()/* [@isDoc and string(./umbracoNaviHide) != '1' and @level <= $maxLevelForSitemap and contains($ignoreDocTypes, Exslt.ExsltStrings:uppercase(name())) = 0]) > 0">
<!--
====================================================
As we have further child nodes recall the same
template we are in with the parent variable set to
as the current node in the for-each loop.
====================================================
-->
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="current()"/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Not sure what you mean when you say Umbraco doesn't support SSL. I've had areas of Umbraco sites run over SSL before. Is there something specifc that you're trying to do?
Hi Sean
Have you created the XSLT file Tim suggested?
Otherwise
1) Create the navigation XSLT macro that should generate the XML for you based on the predefined Sitemap XSLT snippet.
2) Modify the snippet so it outputs proper xml elements. For instance turn the <div id="sitemap"></div> into <root></root> and the ul to for instance <menu></menu> and the li to <page></page> or whatever you think is the proper structure for your sitemap. Place the <xsl:value-of select="umbraco.library:ChangeContentType('text/xml')"/> somewhere in the template(preferably in the start)
to make sure the document gets the correct mime-type once you insert the macro into the template you'll be using to
create the XML document.
3) Create a template called something like "XMLnavigation" in the template section. Add the XML prolog to the template
and place the macro right after it.
4) Now you should be able to access the XML by going to www.yoursite.com/yourxmltemplate.aspx which is the url you need
to import in your project outside of Umbraco.
I hope this makes sense to you.
I think that it really should be able to use SSL with Umbraco, but I must admit that I don't know how to do it currently.
I also still have a suspicion that the above could be created more elegantly using /base. But since you're in a hurry I
think you should give the above a try.
Hope this helps.
/Jan
Haha, too slow. You rock Tim :)
/Jan
Wow. Thanks for the response everybody. I will try this code (from Tim's post tomorrow), thank you. Tim as far as the SSL goes. I was told that the lastest version of Umbraco didn't support HTTPS urls.
So my proposal was to have a secure folder with a few custom navigation links pointing to that secure folder and that folder would be requiring SSL. Is there another approach that you can recommend? Part of that was to generate and xml navigation structure for these pages to read from, as the Umbraco macro's didn't work in those pages when I tried it.
What's your approach on using SSL & Umbraco Tim?
Sean
I've not tried it on the latest version of Umbraco (the last site I did that had SSL was using 4.5.2.
All I did was set up some rewrites using the UrlRewriting config so that everything under certain URLS had to be under SSL, if it wasn't it 301 redirected to the SSL URL. I then had a nother rule that said anything else that was over SSL that wasn't in those folders should be 301'd to the non-SSL page.
So for example, everything under /users could only be accessed via https, and everything else could only be accessed via http. Other than that, nothing was different.
Are you trying to have a members area? If so, you might want to look into the protecting pages with the membership API.
Hi Tim , I'm trying to understand your solution. So you were able to create pages in Umbraco, and the assign them a https URL using the default URL rewrite capability? 0r Dod you write your own for this ? Thanks ind advance. Kind regards, Sean
Thanks for all the answers guys. I appreciate the help
Hi Sean
Did you manage to get it solved? And if so would you care describe the steps you took so others can benefit if they come accross this post in the future? :-)
/Jan
Hi Jan, I have not solved it as yet. It has partially answered my question. I'm having to generate the structure on page load from c# , then read and embellish it. The last part is the 301 redirects which I'm doing inside each secure template. It's going to be a thesis, when I solve it I will post the solution. Give me few weeks. Sean
is working on a reply...