It's up to you how you output the default text and what you case is..
You can do like in your example or you can wrap the text Listen inside a <xsl:text> element like this: <xsl:text>Listen</xsl:text> or use <xsl:value-of select="'Listen'" /> ... noticed you'll need the to apostrophes like this 'Listen' inside the two quotes. Or you can use HTML elements like <p>Listen</p>.
If you use the value mulitple times, you would probably define a variable in the beginning:
Furthermore you could also check that the teaser text property doesn't contains just whitespace with normalize-space($mediaNode/teaser) in the test attribute.
But if you have a multilingual website, you would more likely use dictionary items, where DefaultText is the alias of your dictionary item:
I don't think it would have something to say besides perhaps some formatting in the HTML source code..
one thing you should be aware of in xslt is self closing tags in the some browsers, if e.g. an varible is empty and is wrapped inside some tags, which then would be empty and the browser might then mess up the markup, because the tags are closed other places in the code, which not was the intention.
I'll add a couple of scenarios here, because I think it heavily depends on where you're doing this:
If I can get around using the choose construct, I will. It's not always possible, but when it's very much like an if/else and you're just doing something in the "else" part if the first one is "empty", I can usually do with this pattern:
A very common scenario in Umbraco is using a property (e.g. pageTitle) but falling back to @nodeName if the property is empty. Because they're both nodes and not strings, we can use this one-liner:
Another scenario is adding an attribute (e.g., a class) to a node, where the class (or classes) depend on something else - first, let's take the "maybe add a class" example:
About the whitespace question: It's all about the XML parsing step before the XSLT stylesheet is read by the processor.
An XSLT file is an XML file, and there's a simple rule about whitespace in XML, that there's something called significant whitespace and insignificant whitespace.
Take these simple examples:
<p>
Some text
</p>
The whitespace in the above (between <p> and Some, and between text and </p>) is parsed as insignificant - so effectively, it's read by the XML parser as equal to the following:
<p>Some text</p>
This is because the p element only contains text.
Now look at this one:
<p>
Some <em>formatted</em> text
</p>
Because the p element has both text and element content, it's said to have "mixed content" and therefore, the same whitespace chunks as in the first example above are now considered significant whitespace and thus will be part of the document tree the parser hands off.
So when you're doing this:
<xsl:otherwise>
text here
</xsl:otherwise>
It's interpreted exactly the same as:
<xsl:otherwise>text here</xsl:otherwise>
Phew, lenghty explanation - but I hope it helps a little :-)
So when you ask for individual items in a nodeset, you ask for them by position (1-based) - not by offset (0-based), which I know is pretty much how all other languages does it :-)
The pageTitle / @nodeName select works like this:
When pageTitle exists and isn't empty, you'll get this:
select="(@nodeName[false()] | pageTitle)[1]"
which will be a nodeset with only the pageTitle node in it - selecting the first item in that set, of course gives us the pageTitle.
When pageTitle is empty (or doesn't even exist), we get this:
select="(@nodeName[true()] | pageTitle)[1]"
which can be either a nodeset with both the @nodeName attribute and the pageTitle element, OR, a nodeset with only the @nodeName attribute. In either case, taking the first node from that set gives us @nodeName.
Best Practice, Select Default Text
I often find myself checking for a value to be set, and if it's not, use some default, like this:
It seems like this is not really a best practice. Should I be using something else in place of "Listen" like:
..or something like that, and why?
Hi Jacob
It's up to you how you output the default text and what you case is..
You can do like in your example or you can wrap the text Listen inside a <xsl:text> element like this: <xsl:text>Listen</xsl:text> or use <xsl:value-of select="'Listen'" /> ... noticed you'll need the to apostrophes like this 'Listen' inside the two quotes. Or you can use HTML elements like <p>Listen</p>.
If you use the value mulitple times, you would probably define a variable in the beginning:
Furthermore you could also check that the teaser text property doesn't contains just whitespace with normalize-space($mediaNode/teaser) in the test attribute.
But if you have a multilingual website, you would more likely use dictionary items, where DefaultText is the alias of your dictionary item:
/Bjarne
Thanks, so I guess using value-of is ok, and normalize-space seems like a good check.
I thought I've seen certain contexts where formatting in an xslt carries through to the page.
In other words, if I'm using tabs or spaces to format my xslt file, like this:
Notice that I have a cr/lf after opening otherwise and after Listen. Or sometimes in XSLT's I might have it tabbed in a larger context, like this:
I thought sometimes this can get you into trouble. But I can't remember where. I'll just use value-of.
I don't think it would have something to say besides perhaps some formatting in the HTML source code..
one thing you should be aware of in xslt is self closing tags in the some browsers, if e.g. an varible is empty and is wrapped inside some tags, which then would be empty and the browser might then mess up the markup, because the tags are closed other places in the code, which not was the intention.
Hi Jacob,
I'll add a couple of scenarios here, because I think it heavily depends on where you're doing this:
If I can get around using the choose construct, I will. It's not always possible, but when it's very much like an if/else and you're just doing something in the "else" part if the first one is "empty", I can usually do with this pattern:
A very common scenario in Umbraco is using a property (e.g. pageTitle) but falling back to @nodeName if the property is empty. Because they're both nodes and not strings, we can use this one-liner:
Another scenario is adding an attribute (e.g., a class) to a node, where the class (or classes) depend on something else - first, let's take the "maybe add a class" example:
Second, here's a version where you have a default class, but may need to change it in some cases:
/Chriztian
About the whitespace question: It's all about the XML parsing step before the XSLT stylesheet is read by the processor.
An XSLT file is an XML file, and there's a simple rule about whitespace in XML, that there's something called significant whitespace and insignificant whitespace.
Take these simple examples:
The whitespace in the above (between
<p>
and Some, and between text and</p>
) is parsed as insignificant - so effectively, it's read by the XML parser as equal to the following:This is because the p element only contains text.
Now look at this one:
Because the p element has both text and element content, it's said to have "mixed content" and therefore, the same whitespace chunks as in the first example above are now considered significant whitespace and thus will be part of the document tree the parser hands off.
So when you're doing this:
It's interpreted exactly the same as:
Phew, lenghty explanation - but I hope it helps a little :-)
/Chriztian
Thanks Bjarne, I think I remember losing several hours on the self-closing tags issue once a while back.
Chriztian, this is really clever, I will use this:
...and the pageTitle vs. nodeName scenario I have ALL OVER THE PLACE in a choose. Geez this is awesome:
I had to look at this for a second, but I think I understand. When pageTitle does exist we have:
But how come @nodeName[0] is false? I was dealing with this earlier today when I used
I found that in order to access my expected two items, they were actually located like this:
I tried like this first:
and found nothing in [0]; I don't get that. Is this related? Does accessing an item with [0] always mean false?
And thanks for the whitespace explanation. I think I understand now.
Hi Jacob,
About [1] vs. [0]:
When you write this:
It's actually just shorthand for this:
So when you ask for individual items in a nodeset, you ask for them by position (1-based) - not by offset (0-based), which I know is pretty much how all other languages does it :-)
The pageTitle / @nodeName select works like this:
When pageTitle exists and isn't empty, you'll get this:
which will be a nodeset with only the pageTitle node in it - selecting the first item in that set, of course gives us the pageTitle.
When pageTitle is empty (or doesn't even exist), we get this:
which can be either a nodeset with both the @nodeName attribute and the pageTitle element, OR, a nodeset with only the @nodeName attribute. In either case, taking the first node from that set gives us @nodeName.
/Chriztian
Thanks again Chriztian for breaking this down. I love to learn like this.
is working on a reply...