Porovnat revize
24 Commity
next
...
0325cdf936
Autor | SHA1 | Datum | |
---|---|---|---|
0325cdf936 | |||
b0c715c4ea | |||
63a4437de7 | |||
c88889b10b | |||
634cb2d7ee | |||
1c1416934b | |||
622ef5af6a | |||
5f83981d68 | |||
b5b2a42839 | |||
e217218a3f | |||
82c081385b | |||
91951abe9c | |||
9b35e43161 | |||
73a4e4c10f | |||
1e224fdac6 | |||
fbca85e5ed | |||
15e4f081cc | |||
e876b15c5d | |||
3e736db0ef | |||
03c5646858 | |||
ba06d04a08 | |||
5bb3f55945 | |||
1ae5495e61 | |||
7bb7600d39 |
9
cli.cpp
9
cli.cpp
@ -141,10 +141,9 @@ std::pair<bool, std::string> CLIHandler::page_list([[maybe_unused]] const std::v
|
||||
QueryOption o;
|
||||
auto result = pageDao->getPageList(o);
|
||||
std::stringstream stream;
|
||||
for(std::string pagename : result)
|
||||
for(Page &page : result)
|
||||
{
|
||||
Page p = pageDao->find(pagename).value();
|
||||
stream << p.name << " " << p.pageid << " " << std::string(p.listed ? "listed" : "unlisted") << std::endl;
|
||||
stream << page.name << " " << page.pageid << " " << std::string(page.listed ? "listed" : "unlisted") << std::endl;
|
||||
}
|
||||
return {true, stream.str()};
|
||||
}
|
||||
@ -271,9 +270,9 @@ std::pair<bool, std::string> CLIHandler::category_show(const std::vector<std::st
|
||||
auto categoryDao = this->db->createCategoryDao();
|
||||
auto members = categoryDao->fetchMembers(args.at(0), QueryOption{});
|
||||
std::stringstream stream;
|
||||
for(std::string &member : members)
|
||||
for(Page &member : members)
|
||||
{
|
||||
stream << member << std::endl;
|
||||
stream << member.name << std::endl;
|
||||
}
|
||||
return {true, stream.str()};
|
||||
}
|
||||
|
@ -78,13 +78,16 @@ Config::Config(const std::map<std::string, std::string> &map)
|
||||
this->templatepath = required("templatepath");
|
||||
this->urls.linkallcats = required("linkallcats");
|
||||
this->urls.linkallpages = required("linkallpages");
|
||||
this->urls.linkallpagesrendertype = required ("linkallpagesrendertype");
|
||||
this->urls.linkcategory = required("linkcategory");
|
||||
this->urls.linkcategoryrendertype = required("linkcategoryrendertype");
|
||||
this->urls.linkdelete = required("linkdelete");
|
||||
this->urls.linkedit = required("linkedit");
|
||||
this->urls.linkhistory = required("linkhistory");
|
||||
this->urls.linkindex = required("linkindex");
|
||||
this->urls.linklogout = required("linklogout");
|
||||
this->urls.linkpage = required("linkpage");
|
||||
this->urls.linkpagebytitle = required("linkpagebytitle");
|
||||
this->urls.linkrecent = required("linkrecent");
|
||||
this->urls.linkrevision = required("linkrevision");
|
||||
this->urls.linksettings = required("linksettings");
|
||||
|
3
config.h
3
config.h
@ -23,9 +23,11 @@ struct ConfigUrls
|
||||
std::string linkindex;
|
||||
std::string linkrecent;
|
||||
std::string linkallpages;
|
||||
std::string linkallpagesrendertype;
|
||||
std::string linkallcats;
|
||||
std::string linkshere;
|
||||
std::string linkpage;
|
||||
std::string linkpagebytitle;
|
||||
std::string linkrevision;
|
||||
std::string linkhistory;
|
||||
std::string linkedit;
|
||||
@ -33,6 +35,7 @@ struct ConfigUrls
|
||||
std::string linkdelete;
|
||||
std::string linklogout;
|
||||
std::string linkcategory;
|
||||
std::string linkcategoryrendertype;
|
||||
std::string loginurl;
|
||||
std::string linkrecentsort;
|
||||
std::string actionurl;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <optional>
|
||||
#include "queryoption.h"
|
||||
#include "../category.h"
|
||||
|
||||
#include "../page.h"
|
||||
class CategoryDao
|
||||
{
|
||||
public:
|
||||
@ -14,7 +14,7 @@ class CategoryDao
|
||||
virtual std::vector<std::string> fetchList(QueryOption o) = 0;
|
||||
virtual std::optional<Category> find(std::string name) = 0;
|
||||
virtual void deleteCategory(std::string name) = 0;
|
||||
virtual std::vector<std::string> fetchMembers(std::string name, QueryOption o) = 0;
|
||||
virtual std::vector<Page> fetchMembers(std::string name, QueryOption o) = 0;
|
||||
};
|
||||
|
||||
#endif // CATEGORYDAO_H
|
||||
|
@ -94,9 +94,10 @@ std::vector<std::string> CategoryDaoSqlite::fetchList(QueryOption o)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
std::vector<std::string> CategoryDaoSqlite::fetchMembers(std::string name, QueryOption o)
|
||||
|
||||
std::vector<Page> CategoryDaoSqlite::fetchMembers(std::string name, QueryOption o)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::vector<Page> result;
|
||||
|
||||
SqliteQueryOption queryOption{o};
|
||||
std::string queryoptions =
|
||||
@ -104,11 +105,18 @@ std::vector<std::string> CategoryDaoSqlite::fetchMembers(std::string name, Query
|
||||
|
||||
try
|
||||
{
|
||||
auto query = *db << "SELECT page.name AS name FROM categorymember INNER JOIN page ON page.id = "
|
||||
auto query = *db << "SELECT page.id, page.name AS name, page.title, page.lastrevision, page.visible FROM categorymember INNER JOIN page ON page.id = "
|
||||
"categorymember.page WHERE category = (SELECT id FROM category WHERE name = ? ) AND " +
|
||||
queryoptions
|
||||
<< name;
|
||||
query >> [&](std::string p) { result.push_back(p); };
|
||||
query >> [&](unsigned int id, std::string name, std::string title, unsigned int lastrevision, bool visible) {
|
||||
Page p;
|
||||
p.name = name;
|
||||
p.pageid = id;
|
||||
p.title = title;
|
||||
p.current_revision = lastrevision;
|
||||
p.listed = visible;
|
||||
result.push_back(p); };
|
||||
}
|
||||
catch(const sqlite::exceptions::no_rows &e)
|
||||
{
|
||||
|
@ -3,12 +3,13 @@
|
||||
|
||||
#include "categorydao.h"
|
||||
#include "sqlitedao.h"
|
||||
#include "../page.h"
|
||||
class CategoryDaoSqlite : public CategoryDao, protected SqliteDao
|
||||
{
|
||||
public:
|
||||
CategoryDaoSqlite();
|
||||
std::vector<std::string> fetchList(QueryOption o) override;
|
||||
std::vector<std::string> fetchMembers(std::string name, QueryOption o) override;
|
||||
std::vector<Page> fetchMembers(std::string name, QueryOption o) override;
|
||||
void save(const Category &c) override;
|
||||
void deleteCategory(std::string name) override;
|
||||
std::optional<Category> find(std::string name) override;
|
||||
|
@ -13,8 +13,9 @@ class PageDao
|
||||
virtual bool exists(std::string page) const = 0;
|
||||
virtual bool exists(unsigned int id) const = 0;
|
||||
virtual std::optional<Page> find(std::string name) = 0;
|
||||
virtual std::optional<Page> findByTitle(std::string title) = 0;
|
||||
virtual std::optional<Page> find(unsigned int id) = 0;
|
||||
virtual std::vector<std::string> getPageList(QueryOption option) = 0;
|
||||
virtual std::vector<Page> getPageList(QueryOption option) = 0;
|
||||
virtual std::vector<std::string> fetchCategories(std::string pagename, QueryOption option) = 0;
|
||||
virtual void deletePage(std::string page) = 0;
|
||||
virtual void save(const Page &page) = 0;
|
||||
|
@ -52,6 +52,26 @@ std::optional<Page> PageDaoSqlite::find(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Page> PageDaoSqlite::findByTitle(std::string title)
|
||||
{
|
||||
Page result;
|
||||
try
|
||||
{
|
||||
auto ps = *db << "SELECT id, name, title, lastrevision, visible FROM page WHERE title = ?";
|
||||
ps << title >> std::tie(result.pageid, result.name, result.title, result.current_revision, result.listed);
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<Page> PageDaoSqlite::find(unsigned int id)
|
||||
{
|
||||
Page result;
|
||||
@ -107,21 +127,28 @@ void PageDaoSqlite::save(const Page &page)
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
std::vector<std::string> PageDaoSqlite::getPageList(QueryOption option)
|
||||
|
||||
std::vector<Page> PageDaoSqlite::getPageList(QueryOption option)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::vector<Page> result;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
std::string queryOption = SqliteQueryOption(option)
|
||||
.setOrderByColumn("lower(name)")
|
||||
.setVisibleColumnName("visible")
|
||||
.setPrependWhere(true)
|
||||
.build();
|
||||
std::string query = "SELECT name FROM page " + queryOption;
|
||||
std::string query = "SELECT id, name, title, lastrevision, visible FROM page " + queryOption;
|
||||
*db << query >> [&](unsigned int pageid, std::string name, std::string title,unsigned int current_revision, bool visible ) {
|
||||
|
||||
*db << query >> [&](std::string name) { result.push_back(name); };
|
||||
Page tmp;
|
||||
tmp.pageid = pageid;
|
||||
tmp.name = name;
|
||||
tmp.title = title;
|
||||
tmp.current_revision = current_revision;
|
||||
tmp.listed = visible;
|
||||
result.push_back(tmp); };
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
|
@ -20,8 +20,9 @@ class PageDaoSqlite : public PageDao, protected SqliteDao
|
||||
bool exists(std::string name) const override;
|
||||
void save(const Page &page) override;
|
||||
std::optional<Page> find(std::string name) override;
|
||||
std::optional<Page> findByTitle(std::string title) override;
|
||||
std::optional<Page> find(unsigned int id) override;
|
||||
std::vector<std::string> getPageList(QueryOption option) override;
|
||||
std::vector<Page> getPageList(QueryOption option) override;
|
||||
std::vector<std::string> fetchCategories(std::string pagename, QueryOption option) override;
|
||||
using SqliteDao::SqliteDao;
|
||||
int fetchPageId(std::string pagename);
|
||||
|
@ -11,9 +11,15 @@ class DynamicContent
|
||||
Database *database;
|
||||
UrlProvider *urlProvider;
|
||||
|
||||
std::string argument;
|
||||
|
||||
public:
|
||||
DynamicContent(Template &templ, Database &database, UrlProvider &urlProvider);
|
||||
virtual std::string render() = 0;
|
||||
virtual void setArgument(std::string argument)
|
||||
{
|
||||
this->argument = argument;
|
||||
}
|
||||
virtual ~DynamicContent()
|
||||
{
|
||||
}
|
||||
|
11
dynamic/dynamiccontentgetvar.cpp
Normální soubor
11
dynamic/dynamiccontentgetvar.cpp
Normální soubor
@ -0,0 +1,11 @@
|
||||
#include "dynamiccontentgetvar.h"
|
||||
|
||||
std::string DynamicContentGetVar::render()
|
||||
{
|
||||
return (*this->map)[this->argument];
|
||||
}
|
||||
|
||||
void DynamicContentGetVar::setMap(std::map<std::string, std::string> &map)
|
||||
{
|
||||
this->map = ↦
|
||||
}
|
19
dynamic/dynamiccontentgetvar.h
Normální soubor
19
dynamic/dynamiccontentgetvar.h
Normální soubor
@ -0,0 +1,19 @@
|
||||
#ifndef DYNAMICCONTENTGETVAR_H
|
||||
#define DYNAMICCONTENTGETVAR_H
|
||||
|
||||
#include "dynamiccontent.h"
|
||||
class DynamicContentGetVar : public DynamicContent
|
||||
{
|
||||
private:
|
||||
std::map<std::string, std::string> *map;
|
||||
|
||||
public:
|
||||
using DynamicContent::DynamicContent;
|
||||
|
||||
// DynamicContent interface
|
||||
public:
|
||||
std::string render();
|
||||
void setMap(std::map<std::string, std::string> &map);
|
||||
};
|
||||
|
||||
#endif // DYNAMICCONTENTGETVAR_H
|
12
dynamic/dynamiccontentincludepage.cpp
Normální soubor
12
dynamic/dynamiccontentincludepage.cpp
Normální soubor
@ -0,0 +1,12 @@
|
||||
#include "dynamiccontentincludepage.h"
|
||||
#include "../parser.h"
|
||||
std::string DynamicContentIncludePage::render()
|
||||
{
|
||||
auto revisionDao = this->database->createRevisionDao();
|
||||
auto rev = revisionDao->getCurrentForPage(this->argument);
|
||||
if(rev)
|
||||
{
|
||||
return rev->content;
|
||||
}
|
||||
return {};
|
||||
}
|
12
dynamic/dynamiccontentincludepage.h
Normální soubor
12
dynamic/dynamiccontentincludepage.h
Normální soubor
@ -0,0 +1,12 @@
|
||||
#ifndef DYNAMICCONTENTINCLUDEPAGE_H
|
||||
#define DYNAMICCONTENTINCLUDEPAGE_H
|
||||
#include "dynamiccontent.h"
|
||||
class DynamicContentIncludePage : public DynamicContent
|
||||
{
|
||||
public:
|
||||
using DynamicContent::DynamicContent;
|
||||
|
||||
std::string render();
|
||||
};
|
||||
|
||||
#endif // DYNAMICCONTENTINCLUDEPAGE_H
|
@ -1,11 +1,6 @@
|
||||
#include <chrono>
|
||||
#include "dynamiccontentpostlist.h"
|
||||
|
||||
void DynamicContentPostList::setCategory(std::string catname)
|
||||
{
|
||||
this->catname = catname;
|
||||
}
|
||||
|
||||
std::string DynamicContentPostList::render()
|
||||
{
|
||||
auto categoryDao = this->database->createCategoryDao();
|
||||
@ -13,12 +8,12 @@ std::string DynamicContentPostList::render()
|
||||
auto revisionDao = this->database->createRevisionDao();
|
||||
QueryOption option;
|
||||
option.includeInvisible = false;
|
||||
auto members = categoryDao->fetchMembers(this->catname, option);
|
||||
auto members = categoryDao->fetchMembers(this->argument, option);
|
||||
std::vector<std::pair<std::string, time_t>> pageList;
|
||||
for(std::string &member : members)
|
||||
for(const Page &member : members)
|
||||
{
|
||||
auto revision = revisionDao->getRevisionForPage(member, 1);
|
||||
pageList.push_back({member, revision->timestamp});
|
||||
auto revision = revisionDao->getRevisionForPage(member.name, 1);
|
||||
pageList.push_back({member.name, revision->timestamp});
|
||||
}
|
||||
std::sort(pageList.begin(), pageList.end(),
|
||||
[](std::pair<std::string, time_t> &a, std::pair<std::string, time_t> &b) { return a.second > b.second; });
|
||||
|
@ -4,12 +4,8 @@
|
||||
#include "dynamiccontent.h"
|
||||
class DynamicContentPostList : public DynamicContent
|
||||
{
|
||||
private:
|
||||
std::string catname;
|
||||
|
||||
public:
|
||||
using DynamicContent::DynamicContent;
|
||||
void setCategory(std::string catname);
|
||||
std::string render() override;
|
||||
};
|
||||
|
||||
|
21
dynamic/dynamiccontentsetvar.cpp
Normální soubor
21
dynamic/dynamiccontentsetvar.cpp
Normální soubor
@ -0,0 +1,21 @@
|
||||
#include "dynamiccontentsetvar.h"
|
||||
|
||||
std::string DynamicContentSetVar::render()
|
||||
{
|
||||
auto result = utils::split(this->argument, '=');
|
||||
if(result.size() == 2)
|
||||
{
|
||||
this->map->emplace(std::make_pair(result[0], result[1]));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void DynamicContentSetVar::setArgument(std::string argument)
|
||||
{
|
||||
this->argument = argument;
|
||||
}
|
||||
|
||||
void DynamicContentSetVar::setMap(std::map<std::string, std::string> &map)
|
||||
{
|
||||
this->map = ↦
|
||||
}
|
17
dynamic/dynamiccontentsetvar.h
Normální soubor
17
dynamic/dynamiccontentsetvar.h
Normální soubor
@ -0,0 +1,17 @@
|
||||
#ifndef DYNAMCCONTENTPUSHVAR_H
|
||||
#define DYNAMCCONTENTPUSHVAR_H
|
||||
#include "dynamiccontent.h"
|
||||
class DynamicContentSetVar : public DynamicContent
|
||||
{
|
||||
private:
|
||||
std::map<std::string, std::string> *map;
|
||||
|
||||
public:
|
||||
using DynamicContent::DynamicContent;
|
||||
|
||||
std::string render();
|
||||
void setArgument(std::string argument);
|
||||
void setMap(std::map<std::string, std::string> &map);
|
||||
};
|
||||
|
||||
#endif // DYNAMCCONTENTPUSHVAR_H
|
0
grouper.cpp
Normální soubor
0
grouper.cpp
Normální soubor
26
grouper.h
Normální soubor
26
grouper.h
Normální soubor
@ -0,0 +1,26 @@
|
||||
#include "utils.h"
|
||||
|
||||
template<class G, class V, class C>
|
||||
class Grouper
|
||||
{
|
||||
std::map<G, std::vector<const V*>, C> results;
|
||||
public:
|
||||
|
||||
Grouper(C c)
|
||||
{
|
||||
results = std::map<G, std::vector<const V*>, C>(c);
|
||||
}
|
||||
|
||||
void group(const std::function<G(const V&)> &map, const std::vector<V> &values)
|
||||
{
|
||||
for(const V &v : values)
|
||||
{
|
||||
results[map(v)].push_back(&v);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<G, std::vector<const V*>, C> &getResults()
|
||||
{
|
||||
return this->results;
|
||||
}
|
||||
};
|
@ -19,6 +19,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerallpages.h"
|
||||
#include "../grouper.h"
|
||||
#include "../pagelistrenderer.h"
|
||||
|
||||
Response HandlerAllPages::handleRequest(const Request &r)
|
||||
{
|
||||
@ -27,17 +29,21 @@ Response HandlerAllPages::handleRequest(const Request &r)
|
||||
Response response;
|
||||
auto pageDao = this->database->createPageDao();
|
||||
QueryOption qo = queryOption(r);
|
||||
auto resultList = pageDao->getPageList(qo);
|
||||
if(resultList.size() == 0)
|
||||
std::vector<Page> pageList = pageDao->getPageList(qo);
|
||||
if(pageList.size() == 0)
|
||||
{
|
||||
return errorResponse("No pages", "This wiki does not have any pages yet");
|
||||
}
|
||||
TemplatePage searchPage = this->templ->getPage("allpages");
|
||||
std::string body = this->templ->renderSearch(resultList);
|
||||
searchPage.setVar("pagelist", body);
|
||||
searchPage.setVar("title", createPageTitle("All pages"));
|
||||
setGeneralVars(searchPage);
|
||||
response.setBody(searchPage.render());
|
||||
|
||||
PageListRenderer pagelistrender(*this->templ, *this->urlProvider, *this->database);
|
||||
TemplatePage allPages = this->templ->getPage("allpages");
|
||||
allPages.setVar("pagelistcontent", pagelistrender.render(pageList, r.get("rendertype")));
|
||||
allPages.setVar("pagelistletterlink", this->urlProvider->allPages(PageListRenderer::RENDER_GROUP_BY_LETTER));
|
||||
allPages.setVar("pagelistcreationdatelink", this->urlProvider->allPages(PageListRenderer::RENDER_GROUP_BY_CREATIONDATE));
|
||||
|
||||
allPages.setVar("title", createPageTitle("All pages"));
|
||||
setGeneralVars(allPages);
|
||||
response.setBody(allPages.render());
|
||||
response.setStatus(200);
|
||||
return response;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlercategory.h"
|
||||
#include "../pagelistrenderer.h"
|
||||
|
||||
Response HandlerCategory::handleRequest(const Request &r)
|
||||
{
|
||||
@ -34,8 +35,12 @@ Response HandlerCategory::handleRequest(const Request &r)
|
||||
QueryOption qo = queryOption(r);
|
||||
auto resultList = categoryDao->fetchMembers(categoryname, qo);
|
||||
TemplatePage searchPage = this->templ->getPage("show_category");
|
||||
std::string body = this->templ->renderSearch(resultList);
|
||||
searchPage.setVar("pagelist", body);
|
||||
PageListRenderer pagelistrender(*this->templ, *this->urlProvider, *this->database);
|
||||
|
||||
std::string body = pagelistrender.render(resultList, r.get("rendertype"));
|
||||
searchPage.setVar("pagelistcontent", body);
|
||||
searchPage.setVar("pagelistletterlink", this->urlProvider->category(categoryname, PageListRenderer::RENDER_GROUP_BY_LETTER));
|
||||
searchPage.setVar("pagelistcreationdatelink", this->urlProvider->category(categoryname, PageListRenderer::RENDER_GROUP_BY_CREATIONDATE));
|
||||
searchPage.setVar("categoryname", categoryname);
|
||||
setGeneralVars(searchPage);
|
||||
searchPage.setVar("title", createPageTitle("Category: " + categoryname));
|
||||
|
@ -10,7 +10,9 @@ std::vector<HandlerFeedGenerator::EntryRevisionPair> HandlerFeedGenerator::fetch
|
||||
QueryOption option;
|
||||
option.includeInvisible = false;
|
||||
// option.limit = 20;
|
||||
std::set<std::string> members;
|
||||
|
||||
auto comppage = [](const Page &a, const Page &b) { return a.name < b.name; };
|
||||
std::set<Page, decltype(comppage)> members (comppage);
|
||||
if(categories.empty())
|
||||
{
|
||||
auto pages = pageDao->getPageList(option);
|
||||
@ -21,15 +23,18 @@ std::vector<HandlerFeedGenerator::EntryRevisionPair> HandlerFeedGenerator::fetch
|
||||
auto categoryDao = this->database->createCategoryDao();
|
||||
for(std::string cat : categories)
|
||||
{
|
||||
if(!categoryDao->find(cat))
|
||||
{
|
||||
throw std::runtime_error("No such category");
|
||||
}
|
||||
auto catmembers = categoryDao->fetchMembers(cat, option);
|
||||
std::copy(catmembers.begin(), catmembers.end(), std::inserter(members, members.end()));
|
||||
}
|
||||
}
|
||||
for(const std::string &member : members)
|
||||
for(const Page &member : members)
|
||||
{
|
||||
auto page = pageDao->find(member).value();
|
||||
auto revision = revisionDao->getRevisionForPage(page.name, 1).value();
|
||||
result.push_back({page, revision});
|
||||
auto revision = revisionDao->getRevisionForPage(member.name, 1).value();
|
||||
result.push_back({member, revision});
|
||||
}
|
||||
std::sort(result.begin(), result.end(),
|
||||
[](EntryRevisionPair &a, EntryRevisionPair &b) { return a.second.timestamp > b.second.timestamp; });
|
||||
@ -43,8 +48,8 @@ std::vector<HandlerFeedGenerator::EntryRevisionPair> HandlerFeedGenerator::fetch
|
||||
return result;
|
||||
}
|
||||
|
||||
Response HandlerFeedGenerator::generateAtom(const std::vector<HandlerFeedGenerator::EntryRevisionPair> &entries,
|
||||
std::string filter)
|
||||
std::string HandlerFeedGenerator::generateAtom(const std::vector<HandlerFeedGenerator::EntryRevisionPair> &entries,
|
||||
std::string filter)
|
||||
{
|
||||
|
||||
std::stringstream stream;
|
||||
@ -56,9 +61,10 @@ Response HandlerFeedGenerator::generateAtom(const std::vector<HandlerFeedGenerat
|
||||
auto revisionDao = this->database->createRevisionDao();
|
||||
auto pageDao = this->database->createPageDao();
|
||||
|
||||
std::string subtitle = filter;
|
||||
if(utils::trim(filter).empty())
|
||||
{
|
||||
filter = "All pages";
|
||||
subtitle = "All pages";
|
||||
}
|
||||
|
||||
for(const EntryRevisionPair &entry : entries)
|
||||
@ -72,6 +78,7 @@ Response HandlerFeedGenerator::generateAtom(const std::vector<HandlerFeedGenerat
|
||||
newestPublished = initialRevision.timestamp;
|
||||
}
|
||||
std::string entryPublished = utils::formatLocalDate(initialRevision.timestamp, dateformat) + "Z";
|
||||
std::string entryUpdated = utils::formatLocalDate(current.timestamp, dateformat) + "Z";
|
||||
std::string entryurl =
|
||||
this->urlProvider->combine({this->urlProvider->rootUrl(), this->urlProvider->page(page.name)});
|
||||
TemplatePage atomentry = this->templ->getPage("feeds/atomentry");
|
||||
@ -79,21 +86,19 @@ Response HandlerFeedGenerator::generateAtom(const std::vector<HandlerFeedGenerat
|
||||
atomentry.setVar("entryurl", utils::html_xss(entryurl));
|
||||
atomentry.setVar("entryid", utils::html_xss(entryurl));
|
||||
atomentry.setVar("entrypublished", entryPublished);
|
||||
atomentry.setVar("entryupdated", entryUpdated);
|
||||
Parser parser;
|
||||
atomentry.setVar("entrycontent", utils::html_xss(parser.parse(*pageDao, *this->urlProvider, current.content)));
|
||||
stream << atomentry.render();
|
||||
}
|
||||
stream << atomfooter;
|
||||
TemplatePage atomheader = this->templ->getPage("feeds/atomheader");
|
||||
atomheader.setVar("subtitle", filter);
|
||||
atomheader.setVar("atomfeeduniqueid", utils::html_xss(this->urlProvider->atomFeed(filter)));
|
||||
atomheader.setVar("subtitle", subtitle);
|
||||
std::string selflink = utils::html_xss(this->urlProvider->atomFeed(filter));
|
||||
atomheader.setVar("atomfeeduniqueid", selflink);
|
||||
atomheader.setVar("atomselflink", selflink);
|
||||
atomheader.setVar("atomfeedupdate", utils::formatLocalDate(newestPublished, dateformat) + "Z");
|
||||
|
||||
Response result;
|
||||
result.setStatus(200);
|
||||
result.setContentType("application/atom+xml");
|
||||
result.setBody(atomheader.render() + stream.str());
|
||||
return result;
|
||||
return atomheader.render() + stream.str();
|
||||
}
|
||||
|
||||
Response HandlerFeedGenerator::handleRequest(const Request &r)
|
||||
@ -103,12 +108,26 @@ Response HandlerFeedGenerator::handleRequest(const Request &r)
|
||||
{
|
||||
std::string type = r.get("type");
|
||||
std::string categories = r.get("cats");
|
||||
|
||||
auto entries = fetchEntries(utils::split(categories, ','));
|
||||
if(type == "atom")
|
||||
{
|
||||
std::string filter = categories;
|
||||
response = generateAtom(entries, filter);
|
||||
Response result;
|
||||
result.setStatus(200);
|
||||
result.setContentType("application/atom+xml");
|
||||
std::string cacheKey = "feed:atom:" + filter;
|
||||
auto cached = this->cache->get(cacheKey);
|
||||
if(cached)
|
||||
{
|
||||
result.setBody(cached.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto entries = fetchEntries(utils::split(categories, ','));
|
||||
std::string feed = generateAtom(entries, filter);
|
||||
result.setBody(feed);
|
||||
this->cache->put(cacheKey, feed);
|
||||
}
|
||||
response = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ class HandlerFeedGenerator : public Handler
|
||||
|
||||
protected:
|
||||
std::vector<EntryRevisionPair> fetchEntries(std::vector<std::string> categories);
|
||||
Response generateAtom(const std::vector<EntryRevisionPair> &entries, std::string atomtitle);
|
||||
std::string generateAtom(const std::vector<EntryRevisionPair> &entries, std::string atomtitle);
|
||||
Response generateRss(const std::vector<EntryRevisionPair> &entries);
|
||||
|
||||
public:
|
||||
|
@ -27,7 +27,18 @@ Response HandlerPage::handle(const Request &r)
|
||||
auto pageDao = this->database->createPageDao();
|
||||
if(pagename.empty())
|
||||
{
|
||||
return errorResponse("No page given", "No page given to request");
|
||||
std::string title = r.get("title");
|
||||
if(title.empty())
|
||||
{
|
||||
return errorResponse("No page given", "No page given to request");
|
||||
}
|
||||
title = utils::strreplace(title, "-", " ");
|
||||
auto page = pageDao->findByTitle(title);
|
||||
if(!page)
|
||||
{
|
||||
return errorResponse("No page by such title", "No page with such title exists");
|
||||
}
|
||||
pagename = page->name;
|
||||
}
|
||||
|
||||
if(pageMustExist() && !pageDao->exists(pagename))
|
||||
|
@ -45,6 +45,7 @@ Response HandlerPageDelete::handleRequest(PageDao &pageDao, std::string pagename
|
||||
{
|
||||
pageDao.deletePage(pagename);
|
||||
this->cache->removePrefix("page:"); // TODO: overkill?
|
||||
this->cache->removePrefix("feed:");
|
||||
return Response::redirectTemporarily(this->urlProvider->index());
|
||||
}
|
||||
TemplatePage delPage = this->templ->getPage("page_deletion");
|
||||
|
@ -101,6 +101,7 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename,
|
||||
pageDao.setCategories(pagename, cats);
|
||||
this->database->commitTransaction();
|
||||
this->cache->removePrefix("page:"); // TODO: overkill?
|
||||
this->cache->removePrefix("feed:");
|
||||
}
|
||||
catch(const DatabaseException &e)
|
||||
{
|
||||
|
@ -24,6 +24,10 @@ SOFTWARE.
|
||||
#include "../parser.h"
|
||||
#include "../htmllink.h"
|
||||
#include "../dynamic/dynamiccontentpostlist.h"
|
||||
#include "../dynamic/dynamiccontentincludepage.h"
|
||||
#include "../dynamic/dynamiccontentsetvar.h"
|
||||
#include "../dynamic/dynamiccontentgetvar.h"
|
||||
|
||||
bool HandlerPageView::canAccess(std::string page)
|
||||
{
|
||||
return effectivePermissions(page).canRead();
|
||||
@ -136,21 +140,46 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
|
||||
std::string indexcontent;
|
||||
std::string parsedcontent;
|
||||
|
||||
std::map<std::string, std::string> dynamicVarsMap;
|
||||
std::function<std::string(std::string_view, std::string_view)> dynamicParseCallback =
|
||||
[&](std::string_view key, std::string_view value) -> std::string
|
||||
{
|
||||
if(key == "dynamic:postlist")
|
||||
{
|
||||
std::shared_ptr<DynamicContentPostList> postlist = createDynamic<DynamicContentPostList>();
|
||||
postlist->setCategory(std::string(value));
|
||||
postlist->setArgument(std::string(value));
|
||||
return postlist->render();
|
||||
}
|
||||
if(key == "dynamic:includepage")
|
||||
{
|
||||
if((effectivePermissions(std::string(value)).canRead()))
|
||||
{
|
||||
std::shared_ptr<DynamicContentIncludePage> includePage = createDynamic<DynamicContentIncludePage>();
|
||||
includePage->setArgument(std::string(value));
|
||||
return parser.parseDynamics(includePage->render(), dynamicParseCallback);
|
||||
}
|
||||
}
|
||||
if(key == "dynamic:setvar")
|
||||
{
|
||||
std::shared_ptr<DynamicContentSetVar> setVar = createDynamic<DynamicContentSetVar>();
|
||||
setVar->setMap(dynamicVarsMap);
|
||||
setVar->setArgument(std::string(value));
|
||||
return setVar->render();
|
||||
}
|
||||
if(key == "dynamic:getvar")
|
||||
{
|
||||
std::shared_ptr<DynamicContentGetVar> getVar = createDynamic<DynamicContentGetVar>();
|
||||
getVar->setMap(dynamicVarsMap);
|
||||
getVar->setArgument(std::string(value));
|
||||
return getVar->render();
|
||||
}
|
||||
return std::string{};
|
||||
};
|
||||
std::string resolvedContent = parser.parseDynamics(revision->content, dynamicParseCallback);
|
||||
if(revisionid > 0)
|
||||
{
|
||||
indexcontent = createIndexContent(parser, revision->content);
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, revision->content, dynamicParseCallback);
|
||||
indexcontent = createIndexContent(parser, resolvedContent);
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, resolvedContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -164,7 +193,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
|
||||
}
|
||||
else
|
||||
{
|
||||
indexcontent = createIndexContent(parser, revision->content);
|
||||
indexcontent = createIndexContent(parser, resolvedContent);
|
||||
this->cache->put(cachekeyindexcontent, indexcontent);
|
||||
}
|
||||
if(cachedparsedcontent)
|
||||
@ -173,7 +202,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, revision->content, dynamicParseCallback);
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, resolvedContent);
|
||||
this->cache->put(cachekeyparsedcontent, parsedcontent);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,10 @@ class IParser
|
||||
}
|
||||
virtual std::string parse(const PageDao &pagedao, UrlProvider &provider, const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const = 0;
|
||||
|
||||
virtual std::string parseDynamics(
|
||||
const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const = 0;
|
||||
virtual std::vector<std::string> extractCategories(const std::string &content) const = 0;
|
||||
|
||||
virtual ~IParser(){};
|
||||
|
66
pagelistrenderer.cpp
Normální soubor
66
pagelistrenderer.cpp
Normální soubor
@ -0,0 +1,66 @@
|
||||
#include "pagelistrenderer.h"
|
||||
#include "grouper.h"
|
||||
|
||||
PageListRenderer::PageListRenderer(Template &templ, UrlProvider &provider, Database &database)
|
||||
{
|
||||
this->templ = &templ;
|
||||
this->urlProvider = &provider;
|
||||
this->database = &database;
|
||||
}
|
||||
|
||||
std::string PageListRenderer::render(const std::vector<Page> &pagelist, std::string type) const
|
||||
{
|
||||
TemplatePage pagelistrendergroup = this->templ->loadResolvedPart("pagelistrender_group");
|
||||
TemplatePage pagelistlink = this->templ->loadResolvedPart("pagelistrender_link");
|
||||
|
||||
|
||||
std::function<bool(const std::string &, const std::string &)> lesser = [](const std::string &a, const std::string &b) -> bool {
|
||||
return a < b;
|
||||
};
|
||||
|
||||
std::function<bool(const std::string &, const std::string &)> greater = [](const std::string &a, const std::string &b) -> bool {
|
||||
return a > b;
|
||||
};
|
||||
|
||||
using Grouper = Grouper<std::string, Page, std::function<bool(const std::string &,const std::string &)>>;
|
||||
|
||||
Grouper grouper = (type == "letter") ? Grouper(lesser) : Grouper(greater);
|
||||
if(type == "letter")
|
||||
{
|
||||
auto az = [&](const Page &p) -> std::string {
|
||||
int upper = toupper(p.title[0]); // TODO: this is not unicode safe.
|
||||
return { (char)upper };
|
||||
};
|
||||
grouper.group(az, pagelist);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto revisionDao = this->database->createRevisionDao();
|
||||
auto creationdate = [&revisionDao](const Page &p) -> std::string {
|
||||
return utils::formatLocalDate(revisionDao->getRevisionForPage(p.name, 1).value().timestamp, "%Y-%m");
|
||||
};
|
||||
grouper.group(creationdate, pagelist);
|
||||
}
|
||||
|
||||
std::stringstream stream;
|
||||
std::string lastGroup = "";
|
||||
|
||||
for(auto &entry : grouper.getResults())
|
||||
{
|
||||
std::string groupname = entry.first;
|
||||
const std::vector<const Page*> &pages = entry.second;
|
||||
if(lastGroup != groupname)
|
||||
{
|
||||
lastGroup = groupname;
|
||||
pagelistrendergroup.setVar("groupname", groupname);
|
||||
stream << pagelistrendergroup.render();
|
||||
}
|
||||
for(const Page *p : pages)
|
||||
{
|
||||
pagelistlink.setVar("inner", p->title);
|
||||
pagelistlink.setVar("href", this->urlProvider->page(p->name));
|
||||
stream << pagelistlink.render();
|
||||
}
|
||||
}
|
||||
return stream.str();
|
||||
}
|
27
pagelistrenderer.h
Normální soubor
27
pagelistrenderer.h
Normální soubor
@ -0,0 +1,27 @@
|
||||
#ifndef PAGELISTRENDERER_H
|
||||
#define PAGELISTRENDERER_H
|
||||
#include "utils.h"
|
||||
#include "page.h"
|
||||
#include "template.h"
|
||||
#include "htmllink.h"
|
||||
#include "urlprovider.h"
|
||||
#include "database/database.h"
|
||||
|
||||
class PageListRenderer
|
||||
{
|
||||
private:
|
||||
Template *templ;
|
||||
UrlProvider *urlProvider;
|
||||
Database *database;
|
||||
|
||||
public:
|
||||
PageListRenderer(Template &templ, UrlProvider &provider, Database &database);
|
||||
|
||||
std::string render(const std::vector<Page> &pages, std::string type) const;
|
||||
|
||||
inline static const std::string RENDER_GROUP_BY_LETTER { "letter" };
|
||||
inline static const std::string RENDER_GROUP_BY_CREATIONDATE { "creationdate" };
|
||||
|
||||
|
||||
};
|
||||
#endif
|
46
parser.cpp
46
parser.cpp
@ -30,7 +30,8 @@ SOFTWARE.
|
||||
std::vector<Headline> Parser::extractHeadlines(const std::string &content) const
|
||||
{
|
||||
std::vector<Headline> result;
|
||||
std::string reg = R"(\[h(1|2|3)\](.*?)\[/h\1\])";
|
||||
|
||||
std::string reg = R"(\[h(1|2|3)\](\[.*?\])*(.*?)(\[.*?\])*\[\/h\1\])";
|
||||
std::regex headerfinder(reg);
|
||||
auto begin = std::sregex_iterator(content.begin(), content.end(), headerfinder);
|
||||
auto end = std::sregex_iterator();
|
||||
@ -40,7 +41,7 @@ std::vector<Headline> Parser::extractHeadlines(const std::string &content) const
|
||||
auto smatch = *it;
|
||||
Headline h;
|
||||
h.level = utils::toUInt(smatch.str(1));
|
||||
h.title = smatch.str(2);
|
||||
h.title = smatch.str(3);
|
||||
result.push_back(h);
|
||||
}
|
||||
return result;
|
||||
@ -116,20 +117,45 @@ std::string Parser::processLink(const PageDao &pageDao, UrlProvider &urlProvider
|
||||
return htmllink.render();
|
||||
}
|
||||
|
||||
std::string Parser::processImage(std::smatch &match) const
|
||||
{
|
||||
std::string tag = match.str(1);
|
||||
std::string inside = match.str(2);
|
||||
std::vector<std::string> splitted = utils::split(inside, '|');
|
||||
std::string width;
|
||||
std::string height;
|
||||
std::string src;
|
||||
if(splitted.size() == 3)
|
||||
{
|
||||
width = splitted[0];
|
||||
height = splitted[1];
|
||||
src = splitted[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
src = splitted[0];
|
||||
}
|
||||
if(!width.empty() && !height.empty())
|
||||
{
|
||||
return "<img src=\"" + src + "\" width=\"" + width + "\" height=\"" + height + "\"/>";
|
||||
}
|
||||
return "<img src=\"" + src + "\"/>";
|
||||
}
|
||||
|
||||
std::string Parser::parse(const PageDao &pagedao, UrlProvider &provider, const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const
|
||||
{
|
||||
std::string result;
|
||||
// we don't care about commands, but we nevertheless replace them with empty strings
|
||||
std::regex tagfinder(
|
||||
R"(\[(b|i|u|li||ul|ol|link|wikilink|h\d|cmd:rename|cmd:redirect|cmd:pagetitle|category|dynamic:postlist)*?\]((\s|\S)*?)\[/\1])");
|
||||
R"(\[(b|i|u|li||ul|ol|code|blockquote|img|link|wikilink|h\d|cmd:visible|cmd:rename|cmd:redirect|cmd:pagetitle|category|dynamic:postlist|dynamic:includepage|dynamic:getvar|dynamic:setvar)*?\]((\s|\S)*?)\[/\1])");
|
||||
result = utils::regex_callback_replacer(
|
||||
tagfinder, content,
|
||||
[&](std::smatch &match)
|
||||
{
|
||||
std::string tag = match.str(1);
|
||||
std::string content = match.str(2);
|
||||
std::string justreplace[] = {"b", "i", "u", "ul", "li", "ol"};
|
||||
std::string justreplace[] = {"b", "i", "u", "ul", "li", "ol", "code", "blockquote"};
|
||||
content = parse(pagedao, provider, content, callback);
|
||||
if(std::find(std::begin(justreplace), std::end(justreplace), tag) != std::end(justreplace))
|
||||
{
|
||||
@ -141,6 +167,10 @@ std::string Parser::parse(const PageDao &pagedao, UrlProvider &provider, const s
|
||||
pagedao, provider,
|
||||
match); // TODO: recreate this so we don't check inside the function stuff again
|
||||
}
|
||||
if(tag == "img")
|
||||
{
|
||||
return this->processImage(match);
|
||||
}
|
||||
if(tag[0] == 'h')
|
||||
{
|
||||
return "<" + tag + " id='" + content + "'>" + content + "</" + tag + ">";
|
||||
@ -150,3 +180,11 @@ std::string Parser::parse(const PageDao &pagedao, UrlProvider &provider, const s
|
||||
result = utils::strreplace(result, "\r\n", "<br>");
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Parser::parseDynamics(const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const
|
||||
{
|
||||
std::regex tagfinder(R"(\[(dynamic:\w+)*?\]((\s|\S)*?)\[/\1])");
|
||||
return utils::regex_callback_replacer(tagfinder, content,
|
||||
[&](std::smatch &match) { return callback(match.str(1), match.str(2)); });
|
||||
}
|
||||
|
4
parser.h
4
parser.h
@ -6,6 +6,7 @@ class Parser : public IParser
|
||||
{
|
||||
private:
|
||||
std::string processLink(const PageDao &pageDao, UrlProvider &urlProvider, std::smatch &match) const;
|
||||
std::string processImage(std::smatch &match) const;
|
||||
|
||||
public:
|
||||
std::string extractCommand(std::string cmdname, const std::string &content) const;
|
||||
@ -15,6 +16,9 @@ class Parser : public IParser
|
||||
virtual std::string parse(
|
||||
const PageDao &pagedao, UrlProvider &provider, const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const override;
|
||||
std::string parseDynamics(
|
||||
const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const override;
|
||||
|
||||
using IParser::IParser;
|
||||
};
|
||||
|
@ -40,7 +40,7 @@ std::pair<std::string, std::string> Request::createPairFromVar(std::string var)
|
||||
else
|
||||
{
|
||||
std::string key = var.substr(0, equal);
|
||||
std::string val = utils::html_xss(var.substr(equal + 1));
|
||||
std::string val = utils::html_xss(utils::urldecode(var.substr(equal + 1)));
|
||||
return std::make_pair(std::move(key), std::move(val));
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,7 @@ void Request::initPostMap(const std::string &url)
|
||||
void Request::initCookies(const std::string &cookiestr)
|
||||
{
|
||||
// TODO: find out what it really should be, ";" or "; "?
|
||||
std::regex regex { ";+\\s?" };
|
||||
std::regex regex{";+\\s?"};
|
||||
auto cookiesplitted = utils::split(cookiestr, regex);
|
||||
for(const std::string &part : cookiesplitted)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
{qswiki:include:general_header}
|
||||
<div id="content" style="margin-top: 10px;">
|
||||
<h2>All pages</h2>
|
||||
{qswiki:var:pagelist}
|
||||
{qswiki:include:pagelistrender}
|
||||
</div>
|
||||
{qswiki:include:general_footer}
|
||||
{qswiki:include:general_footer}
|
||||
|
@ -3,5 +3,6 @@
|
||||
<link href="{qswiki:var:entryurl}"/>
|
||||
<id>{qswiki:var:entryid}</id>
|
||||
<published>{qswiki:var:entrypublished}</published>
|
||||
<updated>{qswiki:var:entryupdated}</updated>
|
||||
<content type="html">{qswiki:var:entrycontent}</content>
|
||||
</entry>
|
||||
|
@ -5,4 +5,5 @@
|
||||
</author>
|
||||
<title>{qswiki:config:wikiname} - {qswiki:var:subtitle}</title>
|
||||
<id>{qswiki:var:atomfeeduniqueid}</id>
|
||||
<link rel="self" href="{qswiki:var:atomselflink}"/>
|
||||
<updated>{qswiki:var:atomfeedupdate}</updated>
|
||||
|
3
template/quitesimple/pagelistrender
Normální soubor
3
template/quitesimple/pagelistrender
Normální soubor
@ -0,0 +1,3 @@
|
||||
{qswiki:include:pagelistrender_header}
|
||||
{qswiki:var:pagelistcontent}
|
||||
{qswiki:include:pagelistrender_footer}
|
0
template/quitesimple/pagelistrender_footer
Normální soubor
0
template/quitesimple/pagelistrender_footer
Normální soubor
1
template/quitesimple/pagelistrender_group
Normální soubor
1
template/quitesimple/pagelistrender_group
Normální soubor
@ -0,0 +1 @@
|
||||
<div class="letter_search_result">{qswiki:var:groupname}</div>
|
1
template/quitesimple/pagelistrender_header
Normální soubor
1
template/quitesimple/pagelistrender_header
Normální soubor
@ -0,0 +1 @@
|
||||
Sort by: <a href="{qswiki:var:pagelistletterlink}">A-Z</a> - <a href="{qswiki:var:pagelistcreationdatelink}">Creation date</a>
|
1
template/quitesimple/pagelistrender_link
Normální soubor
1
template/quitesimple/pagelistrender_link
Normální soubor
@ -0,0 +1 @@
|
||||
<a href="{qswiki:var:href}">{qswiki:var:inner}</a><br>
|
@ -1,6 +1,6 @@
|
||||
{qswiki:include:general_header}
|
||||
<main id="content">
|
||||
<h2>Category: {qswiki:var:categoryname}</h2>
|
||||
{qswiki:var:pagelist}
|
||||
{qswiki:include:pagelistrender}
|
||||
</main>
|
||||
{qswiki:include:general_footer}
|
||||
{qswiki:include:general_footer}
|
||||
|
@ -53,6 +53,11 @@ std::string UrlProvider::allPages()
|
||||
return config->linkallpages;
|
||||
}
|
||||
|
||||
std::string UrlProvider::allPages(std::string rendertype)
|
||||
{
|
||||
return replaceSingleVar(config->linkallpagesrendertype, "type", rendertype);
|
||||
}
|
||||
|
||||
std::string UrlProvider::allCats()
|
||||
{
|
||||
return config->linkallcats;
|
||||
@ -63,6 +68,11 @@ std::string UrlProvider::page(std::string pagename)
|
||||
return replaceOnlyPage(config->linkpage, pagename);
|
||||
}
|
||||
|
||||
std::string UrlProvider::pageByTitle(std::string title)
|
||||
{
|
||||
return replaceSingleVar(config->linkpagebytitle, "title", utils::strreplace(title, " ", "-"));
|
||||
}
|
||||
|
||||
std::string UrlProvider::linksHere(std::string pagename)
|
||||
{
|
||||
return replaceOnlyPage(config->linkshere, pagename);
|
||||
@ -116,6 +126,16 @@ std::string UrlProvider::category(std::string catname)
|
||||
{
|
||||
return replaceSingleVar(config->linkcategory, "category", catname);
|
||||
}
|
||||
|
||||
std::string UrlProvider::category(std::string catname, std::string rendertype)
|
||||
{
|
||||
Varreplacer replace("{");
|
||||
replace.addKeyValue("category", catname);
|
||||
replace.addKeyValue("type", rendertype);
|
||||
return replace.parse(config->linkcategoryrendertype);
|
||||
}
|
||||
|
||||
|
||||
std::string UrlProvider::login(std::string page)
|
||||
{
|
||||
return replaceOnlyPage(config->loginurl, page);
|
||||
|
@ -22,11 +22,14 @@ class UrlProvider
|
||||
std::string recentSorted(unsigned int limit, unsigned int offset, unsigned int sort);
|
||||
|
||||
std::string allPages();
|
||||
|
||||
std::string allPages(std::string rendertype);
|
||||
|
||||
std::string allCats();
|
||||
|
||||
std::string page(std::string pagename);
|
||||
|
||||
std::string pageByTitle(std::string title);
|
||||
|
||||
std::string linksHere(std::string pagename);
|
||||
|
||||
std::string pageHistory(std::string pagename);
|
||||
@ -46,7 +49,8 @@ class UrlProvider
|
||||
std::string refreshSession();
|
||||
|
||||
std::string category(std::string catname);
|
||||
|
||||
std::string category(std::string catname, std::string rendertype);
|
||||
|
||||
std::string login(std::string page);
|
||||
|
||||
std::string rootUrl();
|
||||
|
@ -136,11 +136,10 @@ std::string utils::getenv(const std::string &key)
|
||||
|
||||
std::string utils::readCompleteFile(std::string_view filepath)
|
||||
{
|
||||
|
||||
std::fstream stream(std::string{filepath});
|
||||
if(!stream.is_open())
|
||||
{
|
||||
throw std::runtime_error("stream is not open");
|
||||
throw std::runtime_error("utils::readCompleteFile(): stream is not open");
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << stream.rdbuf();
|
||||
|
Odkázat v novém úkolu
Zablokovat Uživatele