Create layout to output XML instead of XHTML

Topics: General, XSLT
Jan 17, 2011 at 10:58 AM

Is it possible to create a layout that does not include the head and body tags?

I would like to create a layout that I can use for a dynamic page, which I am going to use as input HTML for the FormSubmitHandler XSLT function, but it seems that the Layout editor in Composite C1 won't allow me to exclude the head and body tags.

I need the source code for the page to be something like this:

<html>

<form>

<input type="text" name="name"/>

</form>

</html>

The content inside the html tags could be entered under the "Content" pane on the page.

Any ideas on how I do this?

Jan 17, 2011 at 11:17 AM

I found out that the FormSubmitHandler does not take a page URL as input for the form. It has to be a file on the server.

Jan 17, 2011 at 11:23 AM

 

Your approach is a bit wrong I guess, although I can not clearly understand why you need this.

In general layouts should have head and body tag as well as html tag. Contents will have same tags as well.

This doesn't mean that there will be any duplication but this gives you the opportunity to have something appeared within head tag of the layout without modifying it. 

Jan 17, 2011 at 11:47 AM

Yeah, I also have a feeling that what the way I am trying to do it isn't the right way :-)

So now I am trying a new approach.

And that leads me to a new question: I would like to use the Composite.Mail.SendMail function to send an e-mail, but only if a form is submitted. Is it possible, in an XSLT function, to check if the current request is a post request, and then, if so, use Composite.Mail.SendMail to send an e-mail?

Jan 17, 2011 at 12:00 PM

This may help:

http://docs.composite.net/C1/Releasehistory/NewFeatures.aspx?ID=1936

Jan 17, 2011 at 2:02 PM

Marvelous! :-)

That's exactly what I needed!

That leaves me with only one question: How do I set the HTML of the e-mail that is sent?

Let's say I have a variable "orders" that contain the HTML fragments. If I set up the function like this:

<f:function name="Composite.Mail.SendMail">
<f:param name="From" value="example@example.com" />
<f:param name="To" value="example@example.com" />
<f:param name="Subject" value="Test" />
<f:param name="Body" select="{$orders}" />
<f:param name="IsHtml" value="True" />
</f:function>

... the e-mail just contains the text and no HTML formatting.

If i set up the function like this:

<f:function name="Composite.Mail.SendMail">
<f:param name="From" value="example@example.com" />
<f:param name="To" value="example@example.com" />
<f:param name="Subject" value="Test" />
<f:param name="Body" />
<xsl:copy-of select="{$orders}" />
</f:param> 
<f:param name="IsHtml" value="True" />
</f:function>

... thew XSLT function outputs "[ ERROR ]" and the following errors are logged:

---------------------

System.InvalidProgramException: Wrong xml format   at Composite.Functions.FunctionTreeBuilder.BuildParameterFunctionRuntimeNode(XElement element)   at Composite.Functions.FunctionTreeBuilder.BuildFunctionRuntimeNode(XElement element)   at Composite.Functions.FunctionTreeBuilder.Build(XElement element)   at Composite.StandardPlugins.Functions.XslExtensionsProviders.StandardExtension.CallFunction(XPathNodeIterator nodeIterator)

---------------------

System.Xml.Xsl.XslTransformException: An error occurred during a call to extension function 'CallFunction'. See InnerException for a complete description of the error. ---> System.InvalidProgramException: Wrong xml format   at Composite.Functions.FunctionTreeBuilder.BuildParameterFunctionRuntimeNode(XElement element)   at Composite.Functions.FunctionTreeBuilder.BuildFunctionRuntimeNode(XElement element)   at Composite.Functions.FunctionTreeBuilder.Build(XElement element)   at Composite.StandardPlugins.Functions.XslExtensionsProviders.StandardExtension.CallFunction(XPathNodeIterator nodeIterator)   --- End of inner exception stack trace ---   at System.Xml.Xsl.Runtime.XmlExtensionFunction.Invoke(Object extObj, Object[] args)   at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args)   at <xsl:template match="/">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)   at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)   at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)   at System.Xml.Xsl.XmlILCommand.Execute(XmlReader contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)   at System.Xml.Xsl.XslCompiledTransform.Transform(XmlReader input, XsltArgumentList arguments, XmlWriter results)   at Composite.StandardPlugins.Functions.FunctionProviders.XsltBasedFunctionProvider.XsltBasedFunctionProvider.XsltXmlFunction.Execute(ParameterList parameters, FunctionContextContainer context)   at Composite.Functions.Foundation.PluginFacades.FunctionWrapper.Execute(ParameterList parameters, FunctionContextContainer context)

---------------------

 

 

 

Coordinator
Jan 17, 2011 at 9:11 PM

Looks like it's just a small typo - you are closing the Body param inline, and closing it again further down. Remove the '/' char in the open tag.

<f:param name="Body" />
   <xsl:copy-of select="{$orders}" />
</f:param> 

 

Jan 18, 2011 at 6:23 AM

Unfortunately that is not the problem. Apparently I only made that typo in the post :-)

Could the problem be that I do the function call inside a variable? So in effect, I am doing xsl:copy-of inside a function call inside xsl-variable?

The code is now as below, but I get the same error:

<xsl:variable name="SendMailFunctionMarkup">
<f:function name="Composite.Mail.SendMail">
<f:param name="From" value="mail@example.com" />
<f:param name="To" value="mail@example.com" />
<f:param name="Subject" value="Test" />
<f:param name="Body">
<xsl:copy-of select="$orders" />
</f:param>
<f:param name="IsHtml" value="True" />
</f:function>
</xsl:variable>

 

Coordinator
Jan 18, 2011 at 8:49 AM

Looks like our documentation could be better here - sorry about that. I was able to repro the error you get when the mail body contain multiple 'root nodes'.

You didn't post the part the build up the mail body, but I suspect that you do not have a single root element on it - which make the function throw the 'wrong xml format' exception.

The sample below work - if I remove the <div id="fragment" /> (so I have multiple root html elements) I get the same error.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:c1="http://c1.composite.net/StandardFunctions" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:f="http://www.composite.net/ns/function/1.0" 
                xmlns="http://www.w3.org/1999/xhtml" 
                exclude-result-prefixes="xsl f c1">
	<xsl:template match="/">
		<html>
			<head />
			<body>
			 <!-- building up the HTML for mail s a variable -->
				<xsl:variable name="MailBody">
				        <div id="fragment">
        			     <h1>Hello there!</h1>
        			     <p>This is a <b>test</b>! You can build this markup using XSLT!</p>
    			     </div>
			 </xsl:variable>
			 <!-- building up the function call -->
				<xsl:variable name="SendMailFunctionMarkup">
      <f:function name="Composite.Mail.SendMail">
        <f:param name="From" value="example@example.com" />
        <f:param name="To" value="example@example.com" />
        <f:param name="Subject" value="Test" />
        <f:param name="Body">
          <xsl:copy-of select="$MailBody" />
        </f:param>
        <f:param name="IsHtml" value="True" />
      </f:function>
    </xsl:variable>
    <!-- execute the sending (require smtp setup in web.config to work) --> Mail was send (true/false):
				<xsl:value-of select="c1:CallFunction($SendMailFunctionMarkup)" />
			</body>
		</html>
	</xsl:template>
</xsl:stylesheet>
We will look into giving a more helpful exception - thanks for bringing this to our attention!

Coordinator
Jan 18, 2011 at 11:40 AM

Checked in a more verbose exception info so a similar situation will yield "Wrong xml format in parameter 'Body' - contains multiple elements" instead of just "Wrong xml format". Available when we sync / release.

Feb 21, 2011 at 12:10 PM

I never got to thank you, so here it comes:

THANK YOU so much for helping with this problem :-)

It fixed the issue and helped me finish the function.