Is it possible to call a method from a DotLiquid template? - dotliquid

Clearly, you can call properties, but calling a method doesn't do anything, even on a class that extends from Drop.
I'm trying to do something like this in my XmlDocumentDrop class.
public string XPath
{
return xmlDoc.DocumentElement.SelectSingleNode(xpath).InnerText;
}
Then in my DotLiquid template.
{{ xmlDoc.XPath("//firstName") }}
This returns nothing.
I have tried to use the "CatchAll" method, but I'm trying to pass XPath, and it seems to strip out all non-word characters. So, trying to do this:
{{ xmlDoc.//firstName }}
Just sends "firstName" to BeforeMethod.
I'm trying to template an XML document, using XPath to access data from the template. Short of creating properties for every XPath I might need (not ideal, as the idea is to let users template an XML doc without having to involve a developer), what are my options?
I could do a filter, so something like this:
{{ xmlDoc|xpath:"//firstName" }}
But a filter only takes a string, which means I'm passing in the raw XML as a string, then re-parsing this XML every time it's called, which isn't great.
Options?
Edit:
I tried a custom tag too, but in the end, I'm still passing the XML as a string and re-parsing all the XML every time. What I really need is a reference to the XML document in my template, and the ability to call a single method, passing in a string of XPath.

You can pass XMLDoc as not a string. Simply create a Filter that accepts object like this:
public static Xpath(object document, string xpath)
{
var xmlDoc = document as XmlDocumentDrop;
return xmlDoc.DocumentElement.SelectSingleNode(xpath).InnerText;
}
That way you don't need to re-parse anything.

Related

Modify all text output by TYPO3

I would like to create a "cleanup" extension that replaces various characters (quotes by guillemets) in all kinds of textfields in TYPO3.
I thought about extending <f:format.html> or parseFunc, but I don't know where to "plug in" so I get to replace output content easily before it's cached.
Any ideas, can you give me an example?
If you don't mind regexing, try this:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['cleanUpQuotes'][] = \NAMESPACE\Your\Extension::class;
Insert it into ext_localconf.php and this part is done.
The next step is the class itself:
public function cleanUpQuotes(TypoScriptFrontendController $parentObject)
{
$parentObject->content = DO_YOUR_THING_HERE
}
There also is another possibility which could replace any strings in the whole page - as it operates on the rendered page (and not only on single fields).
You even can use regular expressions.
Look at my answer -> here

Get the properties of reference pages - Kentico

I have a page where I need to display testimonials, In that page document type I have a field to assign testimonials by using page selection, so It will save the GUID of selected testimonial in the database,
I have used following code to display the description of Testimonial, But is there any other way to get the document fileds by passing the GUID,
One option I can use is write a custom macro.
{% Documents["/Page-Resource/Testimonial/Testimonial"].getValue("Description") #%}
Note: I have used the text/xml type transformation
Well it's not that easy but there is one way and that is to use loops:
r = ""; foreach (i in CMSContext.Current.Documents) {if(i.NodeGUID == "a88f82be-bb76-4b82-8faf-5253209f0f75"){r = i}}; r.Description
Notes:
Use NodeGUID or DocumentGUID based on what you store in your custom field.
Replace the hardcoded guid with something like CMSContext.Current.CurrentDocument.YourDescriptionFieldWithGuid
See the documentation if you have any doubts about K# syntax

Zend Validate: How to validate each separate value in comma separated values in textarea for zend_validate_DbRecordExist?

I have text box in which your adds values in comma separated values. Once the form is post I want to check each of CSV value against database table that if each one of them exist already. If so then I want to throw error message otherwise that is fine.
How can I implement this?
What you need is a custom validator. you can either do it extending Zend_Validate_Abstract or you can simply use a callback validator.
To do so, you need to add this to your element:
$elem = new Zend_Form_Element_Text('elem_name');
$elem->setLabel('Label Name:')
->setRequired(true)
->addValidator('callback', true, array('callback' => array($this, 'functionName')));
$this->addElement($elem);
And in the same class (usually your form is in a class that extends Zend_Form), you add this method:
public function functionName($csvString) {
// stuff here using explode(',', $csvString)
// foreach() to iterate over the result and match against the db each $value
}
See explode() for more information.
However, if your form element is going to be called more than once, and in different forms, then I don't recommend you to use a callback, but you'd better write your own validator, the theory remains the same though. Take a look here for more information about how to write validators.
I really doubt that this can be achieved directly just using Zend_Validate_Db_RecordExists. I think the best solution would be to create a custom validator for this purpose. Something that would take your value then explode it based on a , $valueArray = explode(',', $value); and then for each $valueArray check if the element exists in the db. This shouldn't be too hard. If you dont have idea about custom validators this might be helpful.

Need to find the tags under a tag in an XML using jQuery

I have this xml as part of the responseXml of an Ajax call:
<banner-ad>
<title><span style="color:#ffff00;"><strong>Title</strong></span></title>
</banner-ad>
When I used this jQuery(responseXml).find("title").text(); the result is "Title".
I also tried jQuery(responseXml).find("title:first-child") but the result is [object Object].
I want to get the result:
<span style="color:#ffff00;"><strong>Title</strong></span>
Please let me know how to do this in jQuery.
Thanks in advance for any help.
Regards,
Racs
Your problem is that you cannot simply append nodes from one document (the XML response) to another (your HTML page). The issue is two-fold:
You can use jQuery to append nodes from the XML document to the HTML page. This works; the nodes appear in the HTML DOM, but they stay XML nodes and therefore the browser ignores the style attribute, for example. Consequently the text will not be yellow (#ffff00).
As far as I can see, jQuery offers no built-in way to get the XML string (i.e. a serialized node) from an XML node. jQuery can handle XML documents quite well, but there is no equivalent to what .html() does in HTML documents.
So to make this work we need to extract the XML string from the XML document. Some browsers support the .xml property on XML nodes (namely, IE), the others come with an XMLSerializer object:
// find the proper XML node
var $title = $(doc).find("title");
// either use .xml or, when unavailable, an XMLSerializer
var html = $title[0].xml || (new XMLSerializer()).serializeToString($title[0]);
// result:
// '<title><span style="color:#ffff00;"><strong>Title</strong></span></title>'
Then we have to feed this HTML string to jQuery so new, real HTML elements can be created from it:
$("#target").append(html);
There is a fiddle to show this in action: http://jsfiddle.net/Tomalak/QWHj8/. This example also gets rid of the superfluous <title> element.
Anyway. If you have a chance to influence the XML itself, it would make sense to change it:
<banner-ad>
<title><span style="color:#ffff00;"><strong>Title</strong></span></title>
</banner-ad>
Just XML-encode the payload of <title> and you can do this in jQuery:
$("#target").append( $(doc).find("title").text() );
This would probably work:
$(responseXml).find("title").html();

How can I use the sfValidatorEmail validator in Symfony to validate a single email field

I have a form with 2 elements that will be submitted and then update part of a user profile.
I don't want to use the entire generated form and have to remove all the fields except for the two I need. I just want to be able to create a quite simple form to do my update.
Is there a way to utilize Symfony's sfValidatorEmail inside the action on the returned value of an email field?
Since the regex is already written in the validator, I would like to reuse it, but I don't know how to use it in the action after the non-symfony form has been submitted.
Two approaches here - you could construct a simple form anyway extending from sfForm/sfFormSymfony (doesn't have to be ORM-based) that just contains the 2 fields you want. That way you can use the existing validation framework, and then use $myForm->getValues() after everything has been validated to get your values for your profile update.
Alternatively, as you've mentioned, you can use the sfValidatorEmail class in your action like so:
$dirtyValue = "broken.email.address"
$v = new sfValidatorEmail();
try
{
$v->clean($dirtyValue);
}
catch (sfValidatorError $e)
{
// Validation failed
}
The latter approach quickly leads to messy code if you have many values that need cleaning, and it's worth putting the logic back into a form to handle this in the usual manner.
If you're submitting a form with 2 elements, it should be a form on the edit and update end, period. Symfony forms are lightweight, there's no performance reason to not use them. Instead, make a custom form for this purpose:
class ProfileUpdateForm extends ProfileForm
{
public function configure()
{
$this->useFields(array('email', 'other_field'));
}
}