dynamic logic based control inside html files using mustash syntax
{{%bool1 && bool2 || (bool3 && !bool4)}} must be closed exactly as stated!! {{/bool1 && bool2 || (bool3 && !bool4)}}main
parent
cd3e660765
commit
429b39cf08
|
@ -18,8 +18,16 @@
|
||||||
|
|
||||||
<div class="center">
|
<div class="center">
|
||||||
HAXsdsad
|
HAXsdsad
|
||||||
{{#_admin}}
|
{{%_admin}}
|
||||||
Admin detected
|
<p>Admin detected</p>
|
||||||
|
{{/_admin}}
|
||||||
|
{{%_admin && _create_posts}}
|
||||||
|
<p>Admin and can read!</p>
|
||||||
|
{{/_admin && _create_posts}}
|
||||||
|
{{%_admin}}
|
||||||
|
{{%_read_files}}
|
||||||
|
Nested time!
|
||||||
|
{{/_read_files}}
|
||||||
{{/_admin}}
|
{{/_admin}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
2
libs/BLT
2
libs/BLT
|
@ -1 +1 @@
|
||||||
Subproject commit 34536e2a633050ed241b951c292aca58c55435b9
|
Subproject commit 1b4e36416ae67d3a3789333ff965866ae45bb98b
|
|
@ -9,6 +9,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <blt/std/time.h>
|
#include <blt/std/time.h>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <blt/std/assert.h>
|
||||||
|
|
||||||
namespace cs
|
namespace cs
|
||||||
{
|
{
|
||||||
|
@ -65,9 +66,7 @@ namespace cs
|
||||||
while (!hasTemplateSuffix())
|
while (!hasTemplateSuffix())
|
||||||
{
|
{
|
||||||
if (!hasNext())
|
if (!hasNext())
|
||||||
{
|
blt_throw(LexerSyntaxError());
|
||||||
throw LexerSyntaxError();
|
|
||||||
}
|
|
||||||
token += consume();
|
token += consume();
|
||||||
}
|
}
|
||||||
consumeTemplateSuffix();
|
consumeTemplateSuffix();
|
||||||
|
@ -195,12 +194,12 @@ namespace cs
|
||||||
{
|
{
|
||||||
case '&':
|
case '&':
|
||||||
if (consume() != '&')
|
if (consume() != '&')
|
||||||
throw LexerSyntaxError("Unable to parse logical expression. Found single '&' missing second '&'");
|
blt_throw(LexerSyntaxError("Unable to parse logical expression. Found single '&' missing second '&'"));
|
||||||
tokens.emplace_back(TokenType::AND);
|
tokens.emplace_back(TokenType::AND);
|
||||||
break;
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
if (consume() != '|')
|
if (consume() != '|')
|
||||||
throw LexerSyntaxError("Unable to parse logical expression. Found single '|' missing second '|'");
|
blt_throw(LexerSyntaxError("Unable to parse logical expression. Found single '|' missing second '|'"));
|
||||||
tokens.emplace_back(TokenType::OR);
|
tokens.emplace_back(TokenType::OR);
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!':
|
||||||
|
@ -225,19 +224,19 @@ namespace cs
|
||||||
|
|
||||||
static inline bool isTrue(const RuntimeContext& context, const std::string& token)
|
static inline bool isTrue(const RuntimeContext& context, const std::string& token)
|
||||||
{
|
{
|
||||||
BLT_DEBUG("isTrue for token '%s' contains? %s", token.c_str(), context.contains(token) ? "True" : "False");
|
//BLT_DEBUG("isTrue for token '%s' contains? %s", token.c_str(), context.contains(token) ? "True" : "False");
|
||||||
return context.contains(token) && !context.at(token).empty();
|
return context.contains(token) && !context.at(token).empty();
|
||||||
}
|
}
|
||||||
// http://www.cs.unb.ca/~wdu/cs4613/a2ans.htm
|
// http://www.cs.unb.ca/~wdu/cs4613/a2ans.htm
|
||||||
bool factor(const RuntimeContext& context)
|
bool factor(const RuntimeContext& context)
|
||||||
{
|
{
|
||||||
if (!hasNextToken())
|
if (!hasNextToken())
|
||||||
throw LexerSyntaxError("Processing boolean factor but no token was found!");
|
blt_throw(LexerSyntaxError("Processing boolean factor but no token was found!"));
|
||||||
auto next = consumeToken();
|
auto next = consumeToken();
|
||||||
switch (next.type){
|
switch (next.type){
|
||||||
case TokenType::IDENT:
|
case TokenType::IDENT:
|
||||||
if (!next.value.has_value())
|
if (!next.value.has_value())
|
||||||
throw LexerSyntaxError("Token identifier does not have a value!");
|
blt_throw(LexerSyntaxError("Token identifier does not have a value!"));
|
||||||
return isTrue(context, next.value.value());
|
return isTrue(context, next.value.value());
|
||||||
case TokenType::NOT:
|
case TokenType::NOT:
|
||||||
return !factor(context);
|
return !factor(context);
|
||||||
|
@ -245,11 +244,11 @@ namespace cs
|
||||||
{
|
{
|
||||||
// auto ret = ;
|
// auto ret = ;
|
||||||
// if (consume() != ')')
|
// if (consume() != ')')
|
||||||
// throw LexerSyntaxError("Found token '(', parsed expression, but not ')' was found!");
|
// blt_throw( LexerSyntaxError("Found token '(', parsed expression, but not ')' was found!");
|
||||||
return expr(context);
|
return expr(context);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw LexerSyntaxError("Weird token found while parsing tokens, type: " + decodeName(next.type));
|
blt_throw(LexerSyntaxError("Weird token found while parsing tokens, type: " + decodeName(next.type)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,9 +298,7 @@ namespace cs
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t findLastTagLocation(const std::string& tag, const std::string& data)
|
static void getTagLocations(std::vector<size_t>& tagLocations, const std::string& tag, const std::string& data){
|
||||||
{
|
|
||||||
std::vector<size_t> tagLocations{};
|
|
||||||
RuntimeLexer lexer(data);
|
RuntimeLexer lexer(data);
|
||||||
while (lexer.hasNext())
|
while (lexer.hasNext())
|
||||||
{
|
{
|
||||||
|
@ -315,10 +312,22 @@ namespace cs
|
||||||
lexer.consume();
|
lexer.consume();
|
||||||
}
|
}
|
||||||
if (tagLocations.empty())
|
if (tagLocations.empty())
|
||||||
throw LexerSearchFailure(tag);
|
blt_throw( LexerSearchFailure(tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t findLastTagLocation(const std::string& tag, const std::string& data)
|
||||||
|
{
|
||||||
|
std::vector<size_t> tagLocations{};
|
||||||
|
getTagLocations(tagLocations, tag, data);
|
||||||
return tagLocations[tagLocations.size() - 1];
|
return tagLocations[tagLocations.size() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t findNextTagLocation(const std::string& tag, const std::string& data) {
|
||||||
|
std::vector<size_t> tagLocations{};
|
||||||
|
getTagLocations(tagLocations, tag, data);
|
||||||
|
return tagLocations[0];
|
||||||
|
}
|
||||||
|
|
||||||
static std::string searchAndReplace(const std::string& data, const RuntimeContext& context)
|
static std::string searchAndReplace(const std::string& data, const RuntimeContext& context)
|
||||||
{
|
{
|
||||||
RuntimeLexer lexer(data);
|
RuntimeLexer lexer(data);
|
||||||
|
@ -329,8 +338,21 @@ namespace cs
|
||||||
{
|
{
|
||||||
auto token = lexer.consumeToken();
|
auto token = lexer.consumeToken();
|
||||||
auto searchField = lexer.str.substr(lexer.index);
|
auto searchField = lexer.str.substr(lexer.index);
|
||||||
auto endTokenLoc = RuntimeLexer::findLastTagLocation(token, searchField);
|
auto endTokenLoc = RuntimeLexer::findNextTagLocation(token, searchField);
|
||||||
|
auto internalData = searchField.substr(0, endTokenLoc);
|
||||||
|
|
||||||
|
LogicalEval eval(token);
|
||||||
|
|
||||||
|
if (eval.eval(context)) {
|
||||||
|
results += searchAndReplace(internalData, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer.index += endTokenLoc;
|
||||||
|
if (lexer.hasTemplatePrefix('/'))
|
||||||
|
lexer.consumeToken();
|
||||||
|
else {
|
||||||
|
blt_throw(LexerSyntaxError("Ending token not found!"));
|
||||||
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
results += lexer.consume();
|
results += lexer.consume();
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <crowsite/site/auth.h>
|
#include <crowsite/site/auth.h>
|
||||||
#include <crow/middlewares/session.h>
|
#include <crow/middlewares/session.h>
|
||||||
#include <crow/middlewares/cookie_parser.h>
|
#include <crow/middlewares/cookie_parser.h>
|
||||||
|
#include "blt/std/assert.h"
|
||||||
|
|
||||||
using Session = crow::SessionMiddleware<crow::FileStore>;
|
using Session = crow::SessionMiddleware<crow::FileStore>;
|
||||||
using CrowApp = crow::App<crow::CookieParser, Session>;
|
using CrowApp = crow::App<crow::CookieParser, Session>;
|
||||||
|
@ -152,6 +153,8 @@ crow::response handle_root_page(const site_params& params)
|
||||||
crow::mustache::context ctx;
|
crow::mustache::context ctx;
|
||||||
cs::RuntimeContext context;
|
cs::RuntimeContext context;
|
||||||
|
|
||||||
|
generateRuntimeContext(params, context);
|
||||||
|
|
||||||
// pass perms in
|
// pass perms in
|
||||||
if (user_perms & cs::PERM_ADMIN)
|
if (user_perms & cs::PERM_ADMIN)
|
||||||
ctx["_admin"] = true;
|
ctx["_admin"] = true;
|
||||||
|
@ -189,6 +192,7 @@ int main(int argc, const char** argv)
|
||||||
blt::logging::setLogOutputFormat(
|
blt::logging::setLogOutputFormat(
|
||||||
"\033[94m[${{FULL_TIME}}]${{RC}} ${{LF}}[${{LOG_LEVEL}}]${{RC}} \033[35m(${{FILE}}:${{LINE}})${{RC}} ${{CNR}}${{STR}}${{RC}}\n"
|
"\033[94m[${{FULL_TIME}}]${{RC}} ${{LF}}[${{LOG_LEVEL}}]${{RC}} \033[35m(${{FILE}}:${{LINE}})${{RC}} ${{CNR}}${{STR}}${{RC}}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
cs::requests::init();
|
cs::requests::init();
|
||||||
|
|
||||||
blt::arg_parse parser;
|
blt::arg_parse parser;
|
||||||
|
|
Loading…
Reference in New Issue