Write expression inside xml comment - xquery

I'd like to put xml comment in the output and put some expression inside the comment. How can I do that in xquery? If I have
<!-- {$var} -->
it is inserted literally, but I'd like to have a comment tag on the output with the value of $var

XQuery has a comment constructor, for example:
<test>
{
let $x := 'hello world!'
return comment {$x}
}
</test>
yields:
<?xml version="1.0" encoding="UTF-8"?>
<test><!--hello world!--></test>

Would something like this work?
for $x in /* return <x><![CDATA[<!--]]>{$x}<![CDATA[-->]]> </x>
input
<test>hello comment</test>
output
<!--hello comment-->

Related

Modifying and passing data through nested Handlebars partials

How is it possible to modify data from a partial when passing down to its sub-partial (in the context of assemble.io)?
usage is something like this:
<!-- index.hbs -->
{{> heroImage src="img.jpg"}}
<!-- heroImage.hbs -->
<div>{{> responsiveImage srcset=src+"480w"}}</div>
<!-- responsiveImage.hbs -->
<img srcset={{srcset}} />
I can only pass the src data but not using and modifying it, like src + "something" or src"something".
If you wish to perform a string concatenation from within a mustache you will need to use a helper method and invoke it as a sub expression.
Such a helper method could be as simple as the following:
Handlebars.registerHelper('concat', function () {
return Array.prototype.slice.call(arguments, 0, -1).join('');
});
And your heroImage.hbs partial would use this helper in the following way:
<div>{{> responsiveImage srcset=(concat src " 480w")}}</div>
I have also created an example fiddle.

What's the best/safest/most effective way of returning HTML from a Meteor helper?

I'm trying to return HTML from a helper function after certain logical conditions are met. However, using the Spacebars.SafeString() function doesn't seem to be working and I gather that using this method to return HTML is unsafe and is prone to code injection from external sources.
For example, returning this HTML:
<object data="/rating/what.svg" width="20" height="20" type="image/svg+xml"></object>
Set up like this:
Spacebars.SafeString("<object data=" + "/rating/what.svg" + "width='20' height='20' type=" + "image/svg+xml" + "></object>");
Can anyone guide me to the best way to return HTML from a helper and how to do such a task? Couldn't find a definitive answer anywhere else.
First of all, if your requirements allow it, don't return HTML at all, just use a template and populate it with a data context, for example:
in your template:
<template name="someHtml">
<object data="/rating/{{dynamicName}}.svg" width="20" height="20" type="image/svg+xml"></object>
</template>
in the corresponding helper:
Template.someHtml.helpers({
dynamicName: function() {
return 'what'; // obviously, you generate this with some code
}
})
But, if you truly must use html content to be printed, you can use one of the two most popular sanitization packages, either djedi:sanitize-html-client or vazco:universe-html-purifier
With the first:
cleanHtml = sanitizeHtml(dirtyHtml, {
allowedTags: [ 'b', 'i', 'em', 'strong', 'a' ],
allowedAttributes: {
'a': [ 'href' ]
}
});
and with the latter:
cleanHtml = UniHTML.purify(dirtyHtml, {
withoutTags: ['b', 'img'],
noFormatting: true
});
And then of course you include the return value of these in your template with either triple braces so that the HTML is not escaped.
You are correct in that Spacebars.SafeString() can return unsafe code. Your best bet is to strip out bad tags or injections that you do not want and either use Spacebars.SafeString() or triple brace syntax like below:
<div>
{{{htmlHelper}}}
</div>
htmlHelper: function() {
return "<img src=..."
}

ZF2 how to disable Zend\Feed\Writer\Feed extensions

Trying to create a simple rss feed in zend framework2 by using Zend\Feed\Writer\Feed:
$feed = new \Zend\Feed\Writer\Feed();
...
$out = $feed->export('rss');
echo $out;
And this will output:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
<channel>
<title>example</title>
<description>example</description>
<generator>Zend_Feed_Writer 2 (http://framework.zend.com)</generator>
<link>http://www.google.com</link>
<item>
<title>article1</title>
<pubDate>Fri, 11 Apr 2014 06:32:53 +0000</pubDate>
<slash:comments>0</slash:comments>
</item>
<item>
<title>article2</title>
<pubDate>Fri, 11 Apr 2014 06:32:53 +0000</pubDate>
<slash:comments>0</slash:comments>
</item>
</channel>
</rss>
My question is:
how to disable xmlns:slash extension <slash:comments>0</slash:comments>?
It's quite a mess in the Zend\Feed component with extensions. I have been messing around with it for a while.
What happens?
You construct a Zend\Feed\Writer\Feed. The Feed extends the Zend\Feed\Writer\AbstractFeed. In the __construct() of AbstractFeed happens this:
public function __construct()
{
Writer::registerCoreExtensions();
$this->_loadExtensions();
}
Writer is here the Zend\Feed\Writer\Writer. The registerCoreExtensions looks as follows:
public static function registerCoreExtensions()
{
static::registerExtension('DublinCore');
static::registerExtension('Content');
static::registerExtension('Atom');
static::registerExtension('Slash');
static::registerExtension('WellFormedWeb');
static::registerExtension('Threading');
static::registerExtension('ITunes');
}
Here, you see the different extens are added to the static Writer instance. From there on, the _loadExtensions() call fetches all extensions registered from the Writer and imports them into the Feed. The same happens by the way in the AbstractRenderer.
How to fix?
Because internally inside the Feed and Renderer the registerCoreExtensions() is called, you cannot overwrite the default list of extensions. Also, the Feed and the Renderer do not have getters/setters for the extension. The only way I came up with is to write your own Feed object and Renderer object.
For the Feed object you create a getter/setter to remove the extensions you want. You also override export where you copy the contents of the method, but overwrite the $renderClass variable name to the render class of your own.
For the Renderer class you create a getter/setter to remove the extensions you want as well. This way, you can tune the extensions you need. It's not that pretty, but hopefully it's something improved upon in ZF3 :)

Add an attribute to an element in an existing XML using Xquery

I need to add an attribute to an element of my response XML using XQuery.
Take the below XML as input,
<xyz:RootNode xmlns:abc="url1" xmlns:xyz="url2">
<abc:OtherNodes/>
<abc:messageHeader att1="val1" att2="val2">
<abc:childNodes/>
</abc:messageHeader>
<abc:OtherNodes/>
</xyz:RootNode>
Need an Xquery that add one more attribute newAtt with value newVal and give the result as,
<xyz:RootNode xmlns:abc="url1" xmlns:xyz="url2">
<abc:OtherNodes/>
<abc:messageHeader att1="val1" att2="val2" newAtt="newVal">
<abc:childNodes/>
</abc:messageHeader>
<abc:OtherNodes>
</xyz:RootNode>
Each time the number of attributes of message header may change. So the query should add a new attribute along with all the existing attributes and return the whole document.
Try the following:
xquery version "3.0";
module namespace foo="http://exist-db.org/apps/ns/foo";
declare function foo:process-node($node as node()?, $model as map()) {
if ($node) then
typeswitch($node)
case text() return $node
case element(messageHeader) return foo:messageHeader($node, $model)
default return element { $node/name() }
{ $node/#*, foo:recurse($node, $model) }
else ()
};
declare function foo:recurse($node as node()?, $model as map()) as item()* {
if ($node)
then
for $cnode in $node/node()
return foo:process-node($cnode, $model)
else ()
};
declare function foo:messageHeader($node as node(), $model as map()) {
element { $node/name() }
{ $node/#*,
attribute { 'newAtt' } { 'newVal' },
foo:recurse($node, $model)
}
};
You then call foo:process-node on the RootNode
You can always re-use the wheel that is there for such things, XSLT. Especially if you want to minimise risk in your code.
eXist supports XSL Transformations and here is an example of how to run an XSLT transformation that does the job that you want:
xquery version "3.0";
declare function local:add-attribute($input as node()?, $attributeName as xs:string, $attributeValue as xs:string?) {
let $xslt := <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template xmlns:abc="url1" match="abc:messageHeader">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:attribute name="{$attributeName}">{$attributeValue}</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
return transform:transform($input, $xslt, ())
};
let $input := <xyz:RootNode xmlns:abc="url1" xmlns:xyz="url2">
<abc:OtherNodes/>
<abc:messageHeader att1="val1" att2="val2">
<abc:childNodes/>
</abc:messageHeader>
<abc:OtherNodes/>
</xyz:RootNode>
return local:add-attribute($input, "hey", "bam")
You can also make use of the $parameters attribute if you want to bring your XSLT out into its own file. Will make things even more testable and modular.

How to create dynamic route with parameter in a JavaScript function?

One of my route is defined like this:
society_mybundle_searchpage:
pattern: /search/cp/{cp}
defaults: { _controller: SocietyMyBundle:Search:searchByCP }
So it needs one parameter: {cp}.
Now I'd like to create a form with an input widget. So my code is like that:
<form onsubmit="return search();" action="#">
{{ form_rest(form) }}
</form>
(Nothing specific, I let symfony do all the work for me). Note that this form calls a JS function: search(). So here's my code in twig:
<script type="text/javascript">
<!--
function verif_formulaire(){
/* some code to get the value of the cp */
...
/* then: */
ss="{{ path('society_mybundle_searchpage', {'cp': '+cp+'}) }}";
return true;
}
-->
</script>
The output is:
function verif_formulaire(){
ss="/symfony/web/app_dev.php/pizzas/search/cp/+tt+";
return true;
}
This is not the output I need. I want the output to be exactly like that this:
function verif_formulaire(){
ss="/symfony/web/app_dev.php/pizzas/search/cp/"+tt+"/";
return true;
}
How shall I proceed?
My solution was: implement a custom url_decode function in twig (very easy).
Then use the format() function.
Here's the result:
window.location ="{{ path('my_path', {'cp': "%s" }) | url_decode | format('"+monCP+"') | raw }}";
Explanation: path('my_path', {'cp': "AAAA" }) will generate an URL like '/mypath/cp/AAAA/' thus path('my_path', {'cp': "%s" }) will generate an URL like '/mypath/cp/%s/'
But the '%s' will be escaped. So I decode it through '| url_decode' :
path('my_path', {'cp': "%s" }) | url_decode
Will generate proper string '/mypath/cp/%s/'.
Then I use the format() function to pass a string.
Example: '"/mypath/cp/%s/" | format('OLIVIER')' will give '"/mypath/cp/OLIVIER/"'
So, here, I pass a specific string: '"+monCP+"' (watch carefully the quotes and double quotes).
So: '"/mypath/cp/%s/" | format('"+monCP+"')' will give '/mypath/cp/"+monCP+"/'
Last problem: this whole string is again escaped. This time, a classical "| raw" is enough.
Thus, to conclude, this:
var xx ="{{ path('my_path', {'cp': "%s" }) | url_decode | format('"+monCP+"') | raw }}";
Will result in full normal JavaScript code:
var xx ="/my-symfony-url/cp/"+monCP+"/";
This may look complex, but wow. No external JavaScript file needed. This is what I wanted. Just pure fast Symfony 2 php-generated cache. I propably could make this a Twig macro or something.
As I can see you need generate route in JS. So maybe you need a FOSJsRoutingBundle?

Resources