I'm looking at the PHP code for the interspire shopping cart and they make extensive use of template variables such as %%GLOBAL_variables%% and %%variable%%.
I haven't seen those before and I'm trying to understand how they are defined and used. Does anyone know what template engine is involved and any documentation on it?
thanks
I've used %% as "delimiters" for my own homegrown templating engine. There is nothing special about it, they are just characters that will prevent any unwanted replacements since it is very unlikely they will occur naturally. Some engines use {keyword}, like Smarty.
As an example, you can do a quick search/replace with an associative array of data.
$data_replace = array('%%GLOBAL_variable%%'=>'some data',
'%%variable1%%'=>'different data',
'%%variable2%%'=>'limited time only!');
//Perform the search and replace
$output = str_replace(array_keys($data_replace), $data_replace, $template_text);
As a guess it looks like a home grown solution.
That said, it would be pretty easy to re-create something like this by doing something like:
Load the template file into a
string.
Grab all occurances of '%%xxx%%'.
(I'm guessing the '%%' are just
handly delimiters.)
Convert the first '%%' to '$_' if
the occurance begins with '%%GLOBAL'
or '$' otherwise.
Once all that's done evaluate the resultant string. (eval)
Additionally, it would be possible to include variables within the scope of the evaluation using extract.
Irrespective, I'd have thought you should be able to confirm this by having a hunt around in the code.
Related
Its my first time working with Smarty Template Engine and I am having troubles translating the following PHP json_decode statement into a Smarty friendly code. The output is an array since I use the TRUE in the json_decode.
$itemArray = json_decode($dni-content-slider-id-prefix-saved-content-picker-item- . $promos, true)
I've tried
{ assign var $itemArray = value=$dni-content-slider-id-prefix-saved-content-picker-item-|cat:$promos|json_decode}
But it doesnt really work. any suggestions?
Pretty much everything in that line of Smarty is wrong; let's go through in order:
{ assign
Don't put a space between the { and the Smarty tag; if Smarty 3's "auto-literal" feature is switched on, it will assume that's a literal { not a Smarty tag.
var $itemArray =
You seem to be mixing two different functions here. The Smarty {assign} function takes the form {assign var=some_name value=$some_value}. Note that the var parameter is the name of the variable to assign, so does not need a $.
Smarty 3 also has a PHP-style "short-form assign", which looks like {$some_name=$some_value} (complete with $, but no assign keyword).
value=$dni-content-slider-id-prefix-saved-content-picker-item-|cat:$promos
This will take the content of the variable $dni-content-slider-id-prefix-saved-content-picker-item- treat it as a string, and add the content of the variable $promos (also treated as a string) to the end of it. Looking again, I see that that is also what your PHP code does, but it seems a very odd thing to do, since the first variable would have to be something like "{'foo':'bar'," and the second something like "'baz':'quux'}". Why would you ever have variables like that?
Based on the PHP code being the same, I'm going to assume this paragraph was wrong on my part What I suspect you want is a variable variable name (a different variable when the code runs); there are ways to do that, but this isn't one of them. It's also generally a really bad idea; if you want lots of similar variables which you can select from at run-time, put them in an associative array, and index something like $dni-content-slider-id-prefix-saved-content-picker-items[$promos].
|json_decode}
Finally, the part actually related to your question. You point out that in PHP, you pass the optional true parameter to the json_decode function, but in this Smarty code, you are not doing so. This can be easily done by adding :true on the end, as in {assign var=itemArray value=$jsonString|json_decode:true}.
I have search strings, similar to the one bellow:
energy food "olympics 2010" Terrorism OR "government" OR cups NOT transport
and I need to parse it with PHP5 to detect if the content belongs to any of the following clusters:
AllWords array
AnyWords array
NotWords array
These are the rules i have set:
If it has OR before or after the word or quoted words if belongs to
AnyWord.
If it has a NOT before word or quoted words it belongs to NotWords
If it has 0 or more more spaces before the word or quoted phrase it
belongs to AllWords.
So the end result should be something similar to:
AllWords: (energy, food, "olympics 2010")
AnyWords: (terrorism, "government", cups)
NotWords: (Transport)
What would be a good way to do this?
If you want to do this with Regex, be aware that your parsing will break on stupid user input (the user, not the input =) ).
I'd try the following Regexes.
NotWords:
(?<=NOT\s)\b((?!NOT|OR)\w+|"[^"]+")\b
AllWords:
(?<!OR\s)\b((?!NOT|OR)\w+|"[^"]+")\b(?!\s+OR)
AnyWords:
Well.. the rest. =) They are not that easy to spot, since I do not know how to put "OR behind it or OR in front of it" into regex. Maybe you could join the results from the three regexes
(?<=OR\s)\b((?!NOT|OR)\w+|"[^"]+")\b(?!\s+OR)
(?<=OR\s)\b((?!NOT|OR)\w+|"[^"]+")\b(?=\s+OR)
(?<!OR\s)\b((?!NOT|OR)\w+|"[^"]+")\b(?=\s+OR)
Problems: These require exactly one space between modifier words and expressions. PHP only supports lookbehinds for fixes length expressions, so I see no way around that, sorry. You could just use \b(\w+|"[^"]+")\b to split the input, and parse the resulting array manually.
This is an excellent example of how an test-first driven approach can help you arrive at a solution. It might not be the very best one, but having tests written allow you to refactor with confidence and instantly see if you break any of the existing tests. Anyway, you could set up a few tests like:
public function setUp () {
$this->searchParser = new App_Search_Parser();
}
public function testSingleWordParsesToAllWords () {
$this->searchParser->parse('Transport');
$this->assertEquals(
$this->searchParser->getAllWords(),
array('Transport')
);
$this->assertEquals($this->searchParser->getNotWords(), array());
$this->assertEquals($this->searchParser->getAnyWords());
}
public function testParseOfCombinedSearchString () {
$query = 'energy food "olympics 2010" Terrorism ' .
'OR "government" OR cups NOT transport';
$this->searchParser->parse($query);
$this->assertEquals(
$this->searchParser->getAllWords(),
array('energy', 'food', 'olympics 2010')
);
$this->assertEquals(
$this->searchParser->getNotWords(),
array('Transport')
);
$this->assertEquals(
$this->searchParser->getAnyWords(),
array( 'terrorism', 'government', 'cups')
);
}
Other good tests would include:
testParseTwoWords
testParseTwoWordsWithOr
testParseSimpleWithNot
testParseInvalid
Here you have to decide what invalid input looks like and how you interpret it, i.e:
'NOT Transport': Search for anything that doesn't contain Transport or inform the user that he has to include at least one search term too?
'OR energy': Is it ok to begin with a combinator?
'food OR NOT energy': Does this mean "search for food or anything that doesn't contain energy", or does it mean "search for food and not energy", or doesn't it mean anything? (i.e. throw exception, return false or whatnot)
testParseEmpty
Then, write the tests one by one, and write a simple solution that passes the test. Then refactor and make it right, and run again to see that you still pass the test.
Once a test passes and the code is refactored, then write the next test and repeat the procedure. Add more tests as you find special cases and refactor the code so that it passes all tests. If you break a test, back-up and re-write the code (not the test!) such that it passes.
As for how you can solve this problem, look into preg_match, strtok or rely simply loop through the string adding up tokens as you go.
I would like to know if I can use a gt function on a variable with php?
eg. : echo _($var);
Feel free to. But you need to make sure the possible contents of the variable makes it into .po/.mo files. (one of the ways to do assure it is to create a dummy file never processed except for by xgettext, containing _("translate me"); expressions).
I don't think gettext will recognize a variable since it scans the source code. If you want to include variables in a string, it's better to use
sprintf()
For example
echo sprintf(_("There are %d results!"), $numResults);
In gettext, the translator will see
There are %d results!
so therefore it can easily be translated as long as he/she knows that %d is a variable. When the script gets executed, gettext will first replace the translation, and then sprintf will insert the variable $numResults. Good luck! I just got done internationalizing my site.
I want to use PHP to replace javascript functions in HTML documents. For example:
original:
function my_function(hey) {
do stuff
}
new:
function new_function(hi) {
do different stuff
}
I was thinking of using regular expressions with the ereg_replace function, but I'm not sure if this is the best approach. The code in each function is pretty long... plus regex looks very daunting to me at the moment. Any suggestions?
This is the kind of thing that perl is built for. Spend a day learning how to slurp in files and take a good look at the many regex tools out there, and you'll have yourself a script that you can modify to use in the future, if need be, but is otherwise throwaway, which is good, since you probably wrote it crappily, being your first one and all.
Looks like you trying to do something pointless. Put a new function and call it. Just do no use the old one, once you anyway want to replace the entire body with it's name.
I'm creating a very simple PHP templating system for a custom CMS/news system. Each article has the intro and the full content (if applicable). I want to have a conditional of the form:
{continue}click to continue{/continue}
So if it's possible to continue, the text "click to continue" will display, otherwise, don't display this whole string. So far, it works like this: if we can continue, remove the {continue} tags; otherwise, remove the whole thing.
I'm currently using preg_match_all to match the string in the second case. What is the best function for removing the matched text? A simple str_replace, or something else?
Or is there a better way to implement this overall?
Why not use preg_replace_callback?
Specifically:
preg_replace_callback('!\{continue\}(.*)\{/continue\}!Us', 'replace_continue', $html);
function replace_continue($matches) {
if (/* can continue */) {
return $matches[1];
} else {
return '';
}
}
I find preg_replace_callback to be incredibly useful.
Sorry I know people have been ridiculing this kind of answer, but just use Smarty. Its simple, stable, clever, free, small and cheap. Spend an hour learning how to use it and you will never look back.
Go to www.smarty.net
For PHP templating systems the proper way is to parse the template (using state machine or at least preg_split), generate PHP code from it, and then use that PHP code only. Then you'll be able to use normal if for conditional expressions.
Regular expressions aren't good idea for implementing templates. It will be PITA to handle nesting and enforce proper syntax beyond basic cases. Performance will be very poor (you have to be careful not to create backtracking expression and even then you'll end up scanning and copying KBs of templates several times).