18 #include "clearsilver_p.h" 26 #include <QtCore/QLoggingCategory> 28 Q_LOGGING_CATEGORY(CUTELYST_CLEARSILVER,
"cutelyst.clearsilver", QtWarningMsg)
33 , d_ptr(new ClearSilverPrivate)
38 ClearSilver::~ClearSilver()
46 return d->includePaths;
52 d->includePaths = paths;
65 d->extension = extension;
82 NEOERR* cutelyst_render(
void *user,
char *data)
84 QByteArray *body =
static_cast<QByteArray*
>(user);
97 const QVariantHash &stash = c->
stash();
98 QString templateFile = stash.value(QStringLiteral(
"template")).toString();
99 if (templateFile.isEmpty()) {
100 if (c->action() && !c->action()->
reverse().isEmpty()) {
101 templateFile = c->action()->
reverse() + d->extension;
104 if (templateFile.isEmpty()) {
105 c->
error(QStringLiteral(
"Cannot render template, template name or template stash key not defined"));
110 qCDebug(CUTELYST_CLEARSILVER) <<
"Rendering template" <<templateFile;
112 if (!d->render(c, templateFile, stash, body)) {
116 if (!d->wrapper.isEmpty()) {
117 QString wrapperFile = d->wrapper;
119 QVariantHash data = stash;
120 data.insert(QStringLiteral(
"content"), body);
123 if (!d->render(c, wrapperFile, data, body)) {
132 NEOERR* findFile(
void *c, HDF *hdf,
const char *filename,
char **contents)
134 const ClearSilverPrivate *priv =
static_cast<ClearSilverPrivate*
>(c);
136 return nerr_raise(NERR_NOMEM,
"Cound not cast ClearSilverPrivate");
139 for (
const QString &includePath : priv->includePaths) {
140 QFile file(includePath + QLatin1Char(
'/') + QString::fromLatin1(filename));
143 if (!file.open(QFile::ReadOnly)) {
144 return nerr_raise(NERR_IO,
"Cound not open file: %s", file.errorString().toLatin1().data());
147 *contents = qstrdup(file.readAll().constData());
148 qCDebug(CUTELYST_CLEARSILVER) <<
"Rendering template:" << file.fileName();
153 return nerr_raise(NERR_NOT_FOUND,
"Cound not find file: %s", filename);
156 bool ClearSilverPrivate::render(
Context *c,
const QString &filename,
const QVariantHash &stash, QByteArray &output)
const 158 HDF *hdf = hdfForStash(c, stash);
162 error = cs_init(&cs, hdf);
166 nerr_error_traceback(error, &msg);
168 errorMsg = QStringLiteral(
"Failed to init ClearSilver:\n+1").arg(QString::fromLatin1(msg.buf, msg.len));
169 renderError(c, errorMsg);
177 cs_register_fileload(cs, const_cast<ClearSilverPrivate*>(
this), findFile);
179 error = cs_parse_file(cs, filename.toLatin1().data());
183 nerr_error_traceback(error, &msg);
185 errorMsg = QStringLiteral(
"Failed to parse template file: +1\n+2").arg(filename, QString::fromLatin1(msg.buf, msg.len));
186 renderError(c, errorMsg);
187 nerr_log_error(error);
195 cs_render(cs, &output, cutelyst_render);
203 void ClearSilverPrivate::renderError(
Context *c,
const QString &error)
const 209 HDF *ClearSilverPrivate::hdfForStash(
Context *c,
const QVariantHash &stash)
const 214 serializeHash(hdf, stash);
216 const QMetaObject *meta = c->metaObject();
217 for (
int i = 0; i < meta->propertyCount(); ++i) {
218 QMetaProperty prop = meta->property(i);
219 QString
name = QLatin1String(
"c.") + QString::fromLatin1(prop.name());
220 QVariant value = prop.read(c);
221 serializeVariant(hdf, value, name);
226 void ClearSilverPrivate::serializeHash(HDF *hdf,
const QVariantHash &hash,
const QString &prefix)
const 229 if (!prefix.isEmpty()) {
230 _prefix = prefix + QLatin1Char(
'.');
233 auto it = hash.constBegin();
234 while (it != hash.constEnd()) {
235 serializeVariant(hdf, it.value(), _prefix + it.key());
240 void ClearSilverPrivate::serializeMap(HDF *hdf,
const QVariantMap &map,
const QString &prefix)
const 243 if (!prefix.isEmpty()) {
244 _prefix = prefix + QLatin1Char(
'.');
247 auto it = map.constBegin();
248 while (it != map.constEnd()) {
249 serializeVariant(hdf, it.value(), _prefix + it.key());
254 void ClearSilverPrivate::serializeVariant(HDF *hdf,
const QVariant &value,
const QString &key)
const 258 switch (value.type()) {
259 case QMetaType::QString:
260 hdf_set_value(hdf, key.toLatin1().data(), value.toString().toLatin1().data());
263 hdf_set_int_value(hdf, key.toLatin1().data(), value.toInt());
265 case QMetaType::QVariantHash:
266 serializeHash(hdf, value.toHash(), key);
268 case QMetaType::QVariantMap:
269 serializeMap(hdf, value.toMap(), key);
272 if (value.canConvert(QMetaType::QString)) {
273 hdf_set_value(hdf, key.toLatin1().data(), value.toString().toLatin1().data());
279 #include "moc_clearsilver.cpp" QString templateExtension() const
Returns the template extension.
QString wrapper() const
Returns the template wrapper.
ClearSilver(QObject *parent=nullptr, const QString &name=QString())
Constructs a ClearSilver object with the given parent and name.
QByteArray render(Context *c) const final
The Cutelyst namespace holds all public Cutelyst API.
void setTemplateExtension(const QString &extension)
Sets the template extension, defaults to ".html".
QStringList includePaths() const
Returns the list of include paths.
void setIncludePaths(const QStringList &paths)
Sets the list of include paths which will be looked for when resolving templates files.
Cutelyst View abstract view component
void setWrapper(const QString &name)
Sets the template wrapper name, the template will be rendered into content variable in which the wrap...
void setBody(QIODevice *body)
bool error() const
Returns true if an error was set.
void stash(const QVariantHash &unite)