using namespace xmltooling;
using namespace std;
+namespace {
+ static const pair<string,string> emptyPair;
+}
+
void TemplateEngine::setTagPrefix(const char* tagPrefix)
{
keytag = string("<") + tagPrefix + " ";
ifnottag = string("<") + tagPrefix + "ifnot ";
ifendtag = string("</") + tagPrefix + "if>";
ifnotendtag = string("</") + tagPrefix + "ifnot>";
+ fortag = string("<") + tagPrefix + "for ";
+ forendtag = string("</") + tagPrefix + "for>";
}
string TemplateEngine::unsafe_chars = "#%&():[]\\`{}";
const char*& lastpos,
ostream& os,
const TemplateParameters& parameters,
+ const std::pair<std::string,std::string>& loopentry,
const XMLToolingException* e
) const
{
string key = buf.substr(lastpos-line, thispos-lastpos);
trimspace(key);
- const char* p = parameters.getParameter(key.c_str());
- if (!p && e)
- p = e->getProperty(key.c_str());
- if (p)
- html_encode(os,p);
+ if (key == "$name" && !loopentry.first.empty())
+ html_encode(os,loopentry.first.c_str());
+ else if (key == "$value" && !loopentry.second.empty())
+ html_encode(os,loopentry.second.c_str());
+ else {
+ const char* p = parameters.getParameter(key.c_str());
+ if (!p && e)
+ p = e->getProperty(key.c_str());
+ if (p)
+ html_encode(os,p);
+ }
lastpos = thispos + 2; // strlen("/>")
}
}
if (visible)
cond = parameters.getParameter(key.c_str()) || (e && e->getProperty(key.c_str()));
lastpos = thispos + 1; // strlen(">")
- process(cond, buf, lastpos, os, parameters, e);
+ process(cond, buf, lastpos, os, parameters, loopentry, e);
}
}
#ifdef HAVE_STRCASECMP
if (visible)
cond = !(parameters.getParameter(key.c_str()) || (e && e->getProperty(key.c_str())));
lastpos = thispos + 1; // strlen(">")
- process(cond, buf, lastpos, os, parameters, e);
+ process(cond, buf, lastpos, os, parameters, loopentry, e);
}
}
#ifdef HAVE_STRCASECMP
lastpos = thispos + ifnotendtag.length();
return;
}
+
+#ifdef HAVE_STRCASECMP
+ else if (!strncasecmp(thispos, fortag.c_str(), fortag.length()))
+#else
+ else if (!_strnicmp(thispos, fortag.c_str(), fortag.length()))
+#endif
+ {
+ // Save this position off.
+ lastpos = thispos + iftag.length();
+ string key;
+ bool cond = visible;
+
+ // search for the end of this tag
+ if ((thispos = strchr(lastpos, '>')) != NULL) {
+ key = buf.substr(lastpos-line, thispos-lastpos);
+ trimspace(key);
+ lastpos = thispos + 1; // strlen(">")
+ }
+
+ const multimap<string,string>* forParams = parameters.getLoopCollection(key.c_str());
+ if (!forParams || forParams->size() == 0) {
+ process(false, buf, lastpos, os, parameters, emptyPair, e);
+ }
+ else {
+ const char* savlastpos = lastpos;
+ for (multimap<string,string>::const_iterator i=forParams->begin(); i!=forParams->end(); ++i) {
+ lastpos = savlastpos;
+ process(cond, buf, lastpos, os, parameters, *i, e);
+ }
+ }
+ }
+
+#ifdef HAVE_STRCASECMP
+ else if (!strncasecmp(thispos, forendtag.c_str(), forendtag.length()))
+#else
+ else if (!_strnicmp(thispos, forendtag.c_str(), forendtag.length()))
+#endif
+ {
+ // Save this position off and pop the stack.
+ lastpos = thispos + forendtag.length();
+ return;
+ }
+
else {
// Skip it.
if (visible)
buf += line + '\n';
const char* pos=buf.c_str();
- process(true, buf, pos, os, parameters, e);
+ process(true, buf, pos, os, parameters, emptyPair, e);
}