Movable Type: HASH output issue - movabletype

I am trying to combine and sort by date two different feed list of entries with hash but not seems to be working.
<mt:entries blog_id="1">
<$mt:entrydate format="%Y:%m:%d:%H:%M:%S" setvar="DateStart"$>
<mt:setvarBlock name="item{title}"><mt:entryTitle></mt:setvarBlock>
<mt:setvarBlock name="item{url}"><mt:entryPermalink></mt:setvarBlock>
<mt:setvarBlock name="items" key="$DateStart"><mt:var name="item"></mt:setvarBlock>
</mt:entries>
<mt:entries blog_id="2">
<$mt:entrydate format="%Y:%m:%d:%H:%M:%S" setvar="DateStart"$>
<mt:setvarBlock name="item{title}"><mt:entryTitle></mt:setvarBlock>
<mt:setvarBlock name="item{url}"><mt:entryPermalink></mt:setvarBlock>
<mt:setvarBlock name="items" key="$DateStart"><mt:var name="item"></mt:setvarBlock>
</mt:entries>
<mt:loop name="items" sort_by="key numeric reverse">
<$mt:Var name="__value__"$><br />
</mt:loop>
OUTPUT:
HASH(0x7fb66e8284a8)
HASH(0x7fb66e8284a8)
HASH(0x7fb66e8284a8)
What Am I doing wrong?

This works for me:
<mt:entries blog_id="9">
<$mt:entrydate format="%Y%m%d%H%M%S" setvar="DateStart"$>
<mt:SetHashVar name="myhash">
<mt:SetHashVar name="$DateStart">
<mt:entryTitle setvar="title">
<mt:entryPermalink setvar="url">
</mt:SetHashVar>
</mt:SetHashVar>
</mt:entries>
<mt:entries blog_id="8">
<$mt:entrydate format="%Y%m%d%H%M%S" setvar="DateStart"$>
<mt:SetHashVar name="myhash">
<mt:SetHashVar name="$DateStart">
<mt:entryTitle setvar="title">
<mt:entryPermalink setvar="url">
</mt:SetHashVar>
</mt:SetHashVar>
</mt:entries>
<mt:loop name="myhash" sort_by="key numeric reverse">
Key: <$mt:Var name="__key__"$> — Values: <br>
<mt:loop name="__value__">
— Key: <$mt:Var name="__key__"$> — Value: <$mt:Var name="__value__"$><br>
</mt:loop>
<br>
</mt:loop>
It removes your "item" key which looks unnecessary to me.
P.S. I've also changed the date key to be a real number (since you want to sort by a numeric value).

Related

How do I address an item in a sequence when using tokenize()

I have an HTML that contains a style attribute with a list of values separated by semicolons:
<td style="border-width:1pt;border-color:#FFFFFF;border-style:solid">
I want to split this list:
<xsl:variable name="astyle"><xsl:value-of select="tokenize(#style, ';')"/></xsl:variable>
This gives me a sequence. Now I want to select the first item in the sequence.
<xsl:value-of select="$astyle[1]"/>
result:
"border-width:1pt border-color:#FFFFFF border-style:solid"
so that's the entire sequence instead of the first item in the sequence.
I can't find any documentation on this.
Edit: it seems my assumption is incorrect. Tokenize() contains a sequence of 1 item. I was expecting 3 items.
How can I split a string into items that can be addressed individually?
I want to do something like
<xsl:value-of select="$astyle[1]"/>
and get:
border-width:1pt
Use <xsl:variable select="tokenize(...)" name="astyle"/>, then the value of the variable is a sequence and $astyle[1] works.

Replace alphabets with spaces

I want to print item.rate but only with having integer values in it.Currently it is printing the rate and also the currency in character.I want to hide the chars.
<td> ${item.rate} </td>
You should be able to use Freemarker's replace function. See https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builtin_replace for reference.
I'd recommend using a regular expression to find everything that's not a number. That should look something like:
${item.rate}?replace('\D', '', 'r')
Reference for Freemarker's regular expression syntax is here: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

Checking for readonly in Geb

I'm trying to write a test in Geb that has a bunch of different text fields. The scenario is essentially that there are five or six html inputs and the user should only be allowed to type in one of them at a time. That is, if the first textbox has a value, the rest of the boxes should be immutable.
Instead of the element having an input type="disabled", they have an attribute (I'm assuming it's an attribute?) of readonly.
Here is a generic example:
<input aria-labelledby="Date Input Value 1" id="Date Input 1" name="Date Input 1" class="input-small DateOrEmpty dateInput" value="" style="display: inline-block;" readonly="">
I've tried
${"input", id: "Date Input 1"}.#readonly
as well as
${"input", id: "Date Input 1"}.has("readonly")
and I haven't had much luck..
Instead of having to deal with the fact that even an empty readonly attribute will cause the element to be read only but $("input[id='Date Input 1']").#readonly evaluates to a falsey value (as #readonly returns the value of the attribute which is an empty string in your case) why not turn the navigator into an instance of FormElement module and use the isReadOnly() property method it provides?
$("input[id='Date Input 1']").module(FormElement).readOnly
EDIT
As pointed out by kriegaex, $("input[id='Date Input 1']").#readonly actually evaluates to a truthy value (because WebDriver always returns a string which contains true when obtaining the value of readonly attribute as long as the attribute is defined on the element and regardless of the actual value of that attribute).
The above means that:
$("input[id='Date Input 1']").module(FormElement).readOnly
and:
$("input[id='Date Input 1']").#readonly
are equivalent in that they evaluate to a truthy value.
You have several problems here:
You use HTML IDs with inline spaces. This are actually not legal names and make it more difficult to write simple CSS selectors like #my-id for them.
Geb syntax for selectors uses parentheses, not curly braces. Curly braces are used for closures, which are a completely different kind of beast.
Please note that according to HTML specification the readonly attribute is boolean and always true if it exists at all, i.e. usually you do not write readonly="something" but just readonly. Even if you write readonly="false" it will evaluate to true because its value is ignored, only its existence is checked.
So if you have this HTML code:
<input id="Date Input 1" readonly>
<input id="Date Input 2">
<input id="date-input-3" readonly="false">
<input id="date-input-4">
<input id="date-input-5" readonly="">
You can write these selectors in your Geb test (please note how not using spaces in IDs makes the selectors simpler):
$("input[id='Date Input 1']").#readonly
!$("input[id='Date Input 2']").#readonly
$("input#date-input-3").#readonly
!$("input#date-input-4").#readonly
$("input#date-input-5").#readonly

Sharepoint XSLT Dynamic filtering

I'm trying to create a dynamic row filter based on a variable. I have the following code:
<xsl:variable name="filter" select="contain(#Title, 'title1') or contain(#Title, 'title2')"/>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[string($filter)]" />
This unfortunately doesn't seem to work and I end up with all rows. I'm guessing the filter doesn't actually get applied, since I can copy and paste the output of the $filter variable, copy and paste it in the Row[] and it works as expected.
Anyone tried to do this before?
In case you're wondering the filter variable is actually created using a template that splits a string like:
title1 - title2 - title3
and returns a string like:
contain(#Title, 'title1') or contain(#Title, 'title2') or contain(#Title, 'title3')
Any help would be greatly appreciated!
You can't do what you seem to be attempting here. An XPath expression is atomical, you can't save parts of it and re-use them (apart from that it is contains(), not contain()).
You need something like this:
<xsl:variable name="Rows" select="
/dsQueryResponse/Rows/Row[
contains(#Title, 'title1') or contains(#Title, 'title2')
]
" />
Your "filter" does not work because if $filter is a string, then it is a string, nothing else. It does not get a magical meaning just because it looks like XPath. ;-)
This
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[string($filter)]" />
evaluates to a non-empty string as the predicate. And any non-empty string evaluates to true, which makes the expression return every node there is.
If you want a dynamic filter based on an input string, then do this:
<xsl:variable name="filter" select="'|title1|title2|title3|'" />
<xsl:variable name="Rows" select="
/dsQueryResponse/Rows/Row[
contains(
$filter,
concat('|', #Title, '|')
)
]
" />
The use of delimiters also prevents "title11" from showing up if you look for "title1".
Make sure your filter always starts and ends with a delimiter, and use a delimiter that is reasonably unlikely to ever occur as a natural part of #Title. (For example, you could use 
. If your title cannot be multi-line this is pretty safe.)

How can I repeatedly match from A until B in VIM?

I need to get all text between <Annotation> and </Annotation>, where a word MATCH occurs. How can I do it in VIM?
<Annotation about="MATCH UNTIL </Annotation> " timestamp="0x000463e92263dd4a" href=" 5raS5maS90ZWh0YXZha29rb2VsbWEvbGFza2FyaS8QyrqPk5L9mAI">
<Label name="las" />
<Label name="_cse_6sbbohxmd_c" />
<AdditionalData attribute="original_url" value="MATCH UNTIL </Annotation> " />
</Annotation>
<Annotation about="NO MATCH" href=" Cjl3aWtpLmhlbHNpbmtpLmZpL2Rpc3BsYXkvbWF0aHN0YXRLdXJzc2l0L0thaWtraStrdXJzc2l0LyoQh_HGoJH9mAI">
<Label name="_cse_6sbbohxmd_c" />
<Label name="courses" />
<Label name="kurssit" />
<AdditionalData attribute="original_url" value="NO MATCH" />
</Annotation>
<Annotation about="MATCH UNTIL </ANNOTATION> " score="1" timestamp="0x000463e90f8eed5c" href="CiZtYXRoc3RhdC5oZWx zaW5raS5maS90ZWh0YXZha29rb2VsbWEvKhDc2rv8kP2YAg">
<Label name="_cse_6sbbohxmd_c" />
<Label name="exercises_without_solutions" />
<Label name="tehtäväkokoelma" />
<AdditionalData attribute="original_url" value="MATCH UNTIL </ANNOTATION>" />
</Annotation>
First, a disclaimer: Any attempt to slice and dice XML with regular expressions is fragile; a real XML parser would do better.
The pattern:
\(<Annotation\(\s*\w\+="[^"]\{-}"\s\{-}\)*>\)\#<=\(\(<\/Annotation\)\#!\_.\)\{-}"MATCH\_.\{-}\(<\/Annotation>\)\#=
Let's break it down...
Group 1 is <Annotation\(\s*\w\+="[^"]\{-}"\s\{-}\)*>. It matches the start-tag of the Attribute element. Group 2, which is embedded in Group 1, matches an attribute and may be repeated 0 or more times.
Group 2 is \s*\w\+="[^"]\{-}"\s\{-}. Most of these pieces are commonly used; the most unusual is \{-}, which means non-greedy repetition (*? in Perl-compatible regular expressions). The non-greedy whitespace match at the end is important for performance; without it, Vim will try every possible way to split the whitespace between attributes between the \s* at the end of Group 2 and the \s* at the beginning of the next occurrence of Group 2.
Group 1 is followed by \#<=. This is a zero-width positive look-behind. It prevents the start-tag from being included in the matched text (e.g., for s///).
Group 3 is \(<\/Annotation\)\#!\_.. It includes Group 4, which matches the beginning of the Attribute end-tag. The \#! is a zero-width negative look-ahead and \_. matches any character (including newlines). Together, this groups matches at any character except where the Attribute end-tag starts. Group 3 is followed by a non-greedy repetition marker \{-} so that it matches the smallest block of text before MATCH. If you were to use \_. instead of Group 3, the matched text could include the end-tag of an Annotation element that did not include MATCH and continue through into the next Annotation element with MATCH. (Try it.)
The next bit is straightforward: Find MATCH and a minimal number of other characters before the end-tag.
Group 5 is easy: It's the end tag. \#= is a zero-width positive look-ahead, which is included here for the same reason as the \#<= for the start-tag. We have to repeat <\/Attribute rather than use \4 because groups with zero-width modifiers aren't captured.
Does it have to be done within vim? Could you cheat, and open a second window where you pipe something into more/less that tells you what line number to go to within vim?
-- edit --
I have never done a multi-line match/search in vi[m]. However, to cheat in another window:
perl -n -e 'if ( /<tag/ .. /<\/tag/)' -e '{ print "$.:$_"; }' file.xml | less
will show the elements/blocks for "tag" (or other longer matching names), with line numbers, in less, and you can then search for the other text within each block.
Close enough?
-- edit --
within "less", type
/MATCH
to search for occurrences of MATCH. On the left margin will be the line number where that instance (within the targeted element/tags) is.
within vi[m], type
:n
where "n" is the desired line number.
Of course, if what you really wanted to do was some kind of search/yank/replace, it's more complicated. At that point, awk / perl / ruby (or something similar which meets your tastes ... or xsl?) is really the tool you should be using for the transformation.

Resources