18 #include "grantleeview_p.h"
20 #include "application.h"
26 #include <grantlee/qtlocalizer.h>
29 #include <QDirIterator>
30 #include <QtCore/QLoggingCategory>
31 #include <QTranslator>
33 Q_LOGGING_CATEGORY(CUTELYST_GRANTLEE,
"cutelyst.grantlee", QtWarningMsg)
41 d->loader = QSharedPointer<Grantlee::FileSystemTemplateLoader>(
new Grantlee::FileSystemTemplateLoader);
43 d->engine =
new Grantlee::Engine(
this);
44 d->engine->addTemplateLoader(d->loader);
47 const QByteArrayList dirs = QByteArrayList{ QByteArrayLiteral(CUTELYST_PLUGINS_DIR) } + qgetenv(
"CUTELYST_PLUGINS_DIR").split(
';');
48 for (
const QByteArray &dir : dirs) {
49 d->engine->addPluginPath(QString::fromLocal8Bit(dir));
52 d->engine->addDefaultLibrary(QStringLiteral(
"grantlee_cutelyst"));
54 auto app = qobject_cast<Application *>(parent);
61 d->cutelystVar = app->config(QStringLiteral(
"CUTELYST_VAR"), QStringLiteral(
"c")).toString();
63 app->loadTranslations(QStringLiteral(
"plugin_view_grantlee"));
70 QStringList GrantleeView::includePaths()
const
73 return d->includePaths;
79 d->loader->setTemplateDirs(paths);
80 d->includePaths = paths;
84 QString GrantleeView::templateExtension()
const
93 d->extension = extension;
97 QString GrantleeView::wrapper()
const
114 if (enable != d->cache.isNull()) {
119 d->engine =
new Grantlee::Engine(
this);
122 d->cache = QSharedPointer<Grantlee::CachingLoaderDecorator>(
new Grantlee::CachingLoaderDecorator(d->loader));
123 d->engine->addTemplateLoader(d->cache);
126 d->engine->addTemplateLoader(d->loader);
145 const auto includePaths = d->includePaths;
146 for (
const QString &includePath : includePaths) {
147 QDirIterator it(includePath, {
148 QLatin1Char(
'*') + d->extension
150 QDir::Files | QDir::NoDotAndDotDot,
151 QDirIterator::Subdirectories);
152 while (it.hasNext()) {
153 QString path = it.next();
154 path.remove(includePath);
155 if (path.startsWith(QLatin1Char(
'/'))) {
159 if (d->cache->canLoadTemplate(path)) {
160 d->cache->loadByName(path, d->engine);
169 return !d->cache.isNull();
177 c->
setStash(d->cutelystVar, QVariant::fromValue(c));
178 const QVariantHash stash = c->
stash();
179 auto it = stash.constFind(QStringLiteral(
"template"));
180 QString templateFile;
181 if (it != stash.constEnd()) {
182 templateFile = it.value().toString();
184 if (c->action() && !c->action()->
reverse().isEmpty()) {
185 templateFile = c->action()->
reverse() + d->extension;
186 if (templateFile.startsWith(QLatin1Char(
'/'))) {
187 templateFile.remove(0, 1);
191 if (templateFile.isEmpty()) {
192 c->
error(QStringLiteral(
"Cannot render template, template name or template stash key not defined"));
197 qCDebug(CUTELYST_GRANTLEE) <<
"Rendering template" << templateFile;
199 Grantlee::Context gc(stash);
201 auto localizer = QSharedPointer<Grantlee::QtLocalizer>::create(c->
locale());
203 auto transIt = d->translators.constFind(c->
locale());
204 if (transIt != d->translators.constEnd()) {
205 localizer.data()->installTranslator(transIt.value(), transIt.key().name());
208 auto catalogIt = d->translationCatalogs.constBegin();
209 while (catalogIt != d->translationCatalogs.constEnd()) {
210 localizer.data()->loadCatalog(catalogIt.value(), catalogIt.key());
214 gc.setLocalizer(localizer);
216 Grantlee::Template tmpl = d->engine->loadByName(templateFile);
217 if (tmpl->error() != Grantlee::NoError) {
219 c->
error(QLatin1String(
"Error while rendering template: ") + tmpl->errorString());
223 QString content = tmpl->render(&gc);
224 if (tmpl->error() != Grantlee::NoError) {
226 c->
error(QLatin1String(
"Error while rendering template: ") + tmpl->errorString());
230 if (!d->wrapper.isEmpty()) {
231 Grantlee::Template wrapper = d->engine->loadByName(d->wrapper);
232 if (tmpl->error() != Grantlee::NoError) {
234 c->
error(QLatin1String(
"Error while rendering template: ") + tmpl->errorString());
238 Grantlee::SafeString safeContent(content,
true);
239 gc.insert(QStringLiteral(
"content"), safeContent);
240 content = wrapper->render(&gc);
242 if (wrapper->error() != Grantlee::NoError) {
244 c->
error(QLatin1String(
"Error while rendering template: ") + tmpl->errorString());
249 ret = content.toUtf8();
256 Q_ASSERT_X(translator,
"add translator to GrantleeView",
"invalid QTranslator object");
257 d->translators.insert(locale, translator);
268 Q_ASSERT_X(!path.isEmpty(),
"add translation catalog to GrantleeView",
"empty path");
269 Q_ASSERT_X(!catalog.isEmpty(),
"add translation catalog to GrantleeView",
"empty catalog name");
270 d->translationCatalogs.insert(catalog, path);
276 Q_ASSERT_X(!catalogs.empty(),
"add translation catalogs to GranteleeView",
"empty QHash");
277 d->translationCatalogs.unite(catalogs);
282 QVector<QLocale> locales;
284 if (Q_LIKELY(!filename.isEmpty() && !directory.isEmpty())) {
285 const QDir i18nDir(directory);
286 if (Q_LIKELY(i18nDir.exists())) {
287 const QString _prefix = prefix.isEmpty() ? QStringLiteral(
".") : prefix;
288 const QString _suffix = suffix.isEmpty() ? QStringLiteral(
".qm") : suffix;
289 const QStringList namesFilter = QStringList({filename + _prefix + QLatin1Char(
'*') + _suffix});
290 const QFileInfoList tsFiles = i18nDir.entryInfoList(namesFilter, QDir::Files);
291 if (Q_LIKELY(!tsFiles.empty())) {
292 locales.reserve(tsFiles.size());
293 for (
const QFileInfo &ts : tsFiles) {
294 const QString fn = ts.fileName();
295 const int prefIdx = fn.indexOf(_prefix);
296 const QString locString = fn.mid(prefIdx + _prefix.length(), fn.length() - prefIdx - _suffix.length() - _prefix.length());
297 QLocale loc(locString);
298 if (Q_LIKELY(loc.language() != QLocale::C)) {
299 auto trans =
new QTranslator(
this);
300 if (Q_LIKELY(trans->load(loc, filename, _prefix, directory))) {
303 qCDebug(CUTELYST_GRANTLEE) <<
"Loaded translations for locale" << loc <<
"from" << ts.absoluteFilePath();
306 qCWarning(CUTELYST_GRANTLEE) <<
"Can not load translations for locale" << loc;
309 qCWarning(CUTELYST_GRANTLEE) <<
"Can not load translations for invalid locale string" << locString;
314 qCWarning(CUTELYST_GRANTLEE) <<
"Can not find translation files for" << filename <<
"in directory" << directory;
317 qCWarning(CUTELYST_GRANTLEE) <<
"Can not load translations from not existing directory:" << directory;
320 qCWarning(CUTELYST_GRANTLEE) <<
"Can not load translations for empty file name or empty path.";
326 #include "moc_grantleeview.cpp"