Cutelee 6.1.0
templateloader.cpp
1/*
2 This file is part of the Cutelee template system.
3
4 Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either version
9 2.1 of the Licence, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library. If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21#include "templateloader.h"
22
23#include "engine.h"
24#include "exception.h"
25#include "nulllocalizer_p.h"
26
27#include <QtCore/QDir>
28#include <QtCore/QFile>
29#include <QtCore/QFileInfo>
30
31using namespace Cutelee;
32
34
35namespace Cutelee
36{
38{
40 std::shared_ptr<AbstractLocalizer> localizer)
41 : q_ptr(loader),
42 m_localizer(localizer
43 ? localizer
44 : std::shared_ptr<AbstractLocalizer>(new NullLocalizer))
45 {
46 }
47 Q_DECLARE_PUBLIC(FileSystemTemplateLoader)
48 FileSystemTemplateLoader *const q_ptr;
49
50 QString m_themeName;
51 QStringList m_templateDirs;
52 const std::shared_ptr<AbstractLocalizer> m_localizer;
53};
54}
55
57 const std::shared_ptr<AbstractLocalizer> localizer)
59 d_ptr(new FileSystemTemplateLoaderPrivate(this, localizer))
60{
61}
62
64{
65 Q_FOREACH (const QString &dir, templateDirs())
66 d_ptr->m_localizer->unloadCatalog(dir + QLatin1Char('/') + themeName());
67 delete d_ptr;
68}
69
70InMemoryTemplateLoader::InMemoryTemplateLoader() : AbstractTemplateLoader() {}
71
72InMemoryTemplateLoader::~InMemoryTemplateLoader() {}
73
75{
77 Q_FOREACH (const QString &dir, templateDirs())
78 d->m_localizer->unloadCatalog(dir + QLatin1Char('/') + d->m_themeName);
79 d->m_themeName = themeName;
80 Q_FOREACH (const QString &dir, templateDirs())
81 d->m_localizer->loadCatalog(dir + QLatin1Char('/') + themeName, themeName);
82}
83
85{
86 Q_D(const FileSystemTemplateLoader);
87 return d->m_themeName;
88}
89
90void FileSystemTemplateLoader::setTemplateDirs(const QStringList &dirs)
91{
93
94 Q_FOREACH (const QString &dir, templateDirs())
95 d->m_localizer->unloadCatalog(dir + QLatin1Char('/') + d->m_themeName);
96 d->m_templateDirs = dirs;
97 Q_FOREACH (const QString &dir, templateDirs())
98 d->m_localizer->loadCatalog(dir + QLatin1Char('/') + d->m_themeName,
99 d->m_themeName);
100}
101
103{
104 Q_D(const FileSystemTemplateLoader);
105 return d->m_templateDirs;
106}
107
109{
110 Q_D(const FileSystemTemplateLoader);
111 auto i = 0;
112 QFile file;
113
114 while (!file.exists()) {
115 if (i >= d->m_templateDirs.size())
116 break;
117
118 file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName
119 + QLatin1Char('/') + name);
120 ++i;
121 }
122
123 if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) {
124 return false;
125 }
126 file.close();
127 return true;
128}
129
131 Engine const *engine) const
132{
133 Q_D(const FileSystemTemplateLoader);
134 auto i = 0;
135 QFile file;
136
137 while (!file.exists()) {
138 if (i >= d->m_templateDirs.size())
139 break;
140
141 file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName
142 + QLatin1Char('/') + fileName);
143 const QFileInfo fi(file);
144
145 if (file.exists()
146 && !fi.canonicalFilePath().contains(
147 QDir(d->m_templateDirs.at(i)).canonicalPath()))
148 return Template();
149 ++i;
150 }
151
152 if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) {
153 return Template();
154 }
155
156 QTextStream fstream(&file);
157#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
158 fstream.setCodec("UTF-8");
159#else
160 fstream.setEncoding(QStringConverter::Utf8);
161#endif
162 const auto fileContent = fstream.readAll();
163
164 return engine->newTemplate(fileContent, fileName);
165}
166
167std::pair<QString, QString>
169{
170 Q_D(const FileSystemTemplateLoader);
171 auto i = 0;
172 QFile file;
173 while (!file.exists()) {
174 if (i >= d->m_templateDirs.size())
175 break;
176
177 file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName
178 + QLatin1Char('/') + fileName);
179
180 const QFileInfo fi(file);
181 if (!fi.canonicalFilePath().contains(
182 QDir(d->m_templateDirs.at(i)).canonicalPath())) {
183 ++i;
184 continue;
185 }
186
187 if (file.exists()) {
188 auto path = fi.absoluteFilePath();
189 path.chop(fileName.size());
190 return {path, fileName};
191 }
192 ++i;
193 }
194 return {};
195}
196
198 const QString &content)
199{
200 m_namedTemplates.insert(name, content);
201}
202
204{
205 return m_namedTemplates.contains(name);
206}
207
209 Engine const *engine) const
210{
211 const auto it = m_namedTemplates.constFind(name);
212 if (it != m_namedTemplates.constEnd()) {
213 return engine->newTemplate(it.value(), name);
214 }
215 throw Cutelee::Exception(
216 TagSyntaxError,
217 QStringLiteral("Couldn't load template %1. Template does not exist.")
218 .arg(name));
219}
220
221std::pair<QString, QString>
223{
224 Q_UNUSED(fileName)
225 // This loader doesn't make any media available yet.
226 return std::pair<QString, QString>();
227}
An retrieval interface to a storage location for Template objects.
Cutelee::Engine is the main entry point for creating Cutelee Templates.
Definition engine.h:121
Template newTemplate(const QString &content, const QString &name) const
Definition engine.cpp:391
An exception for use when implementing template tags.
Definition exception.h:85
The FileSystemTemplateLoader loads Templates from the file system.
FileSystemTemplateLoader(const std::shared_ptr< AbstractLocalizer > localizer={})
Template loadByName(const QString &name, Engine const *engine) const override
void setTheme(const QString &themeName)
bool canLoadTemplate(const QString &name) const override
void setTemplateDirs(const QStringList &dirs)
std::pair< QString, QString > getMediaUri(const QString &fileName) const override
bool canLoadTemplate(const QString &name) const override
void setTemplate(const QString &name, const QString &content)
std::pair< QString, QString > getMediaUri(const QString &fileName) const override
Template loadByName(const QString &name, Engine const *engine) const override
The Template class is a tree of nodes which may be rendered.
Definition template.h:95
The Cutelee namespace holds all public Cutelee API.
Definition Mainpage.dox:8