Start templating engine.
This commit is contained in:
parent
c0bcfaccac
commit
cdd0cc6b78
9 changed files with 230 additions and 1 deletions
|
@ -1,9 +1,11 @@
|
||||||
list(APPEND compiler_HEADERS
|
list(APPEND compiler_HEADERS
|
||||||
Lexer.h
|
Lexer.h
|
||||||
|
TemplatingEngine.h
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND compiler_LIB_INCLUDES
|
list(APPEND compiler_LIB_INCLUDES
|
||||||
Lexer.cpp
|
Lexer.cpp
|
||||||
|
TemplatingEngine.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(compiler SHARED ${compiler_LIB_INCLUDES} ${compiler_HEADERS})
|
add_library(compiler SHARED ${compiler_LIB_INCLUDES} ${compiler_HEADERS})
|
||||||
|
|
0
src/compiler/TemplatingEngine.cpp
Normal file
0
src/compiler/TemplatingEngine.cpp
Normal file
147
src/compiler/TemplatingEngine.h
Normal file
147
src/compiler/TemplatingEngine.h
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "File.h"
|
||||||
|
#include "Directory.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class TemplateBlock
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class TemplateFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TemplateFile(const Path& path)
|
||||||
|
: mPath(path)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> getProcessedContent() const
|
||||||
|
{
|
||||||
|
return mProcessedContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getName() const
|
||||||
|
{
|
||||||
|
return mPath.stem().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadContent()
|
||||||
|
{
|
||||||
|
std::cout << "Trying to load file at: " << mPath << std::endl;
|
||||||
|
mRawContent = File(mPath).readLines();
|
||||||
|
mWorkingLine = 0;
|
||||||
|
for (const auto& line : mRawContent)
|
||||||
|
{
|
||||||
|
processLine(line);
|
||||||
|
mWorkingLine++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void processLine(const std::string& line)
|
||||||
|
{
|
||||||
|
bool last_was_ldelimiter{ false };
|
||||||
|
bool last_was_rdelimiter{ false };
|
||||||
|
bool in_tag{ false };
|
||||||
|
std::string working_string;
|
||||||
|
for (auto c : line)
|
||||||
|
{
|
||||||
|
if (c == '{')
|
||||||
|
{
|
||||||
|
last_was_ldelimiter = true;
|
||||||
|
}
|
||||||
|
else if (c == '%' && last_was_ldelimiter)
|
||||||
|
{
|
||||||
|
last_was_ldelimiter = false;
|
||||||
|
in_tag = true;
|
||||||
|
working_string = "";
|
||||||
|
}
|
||||||
|
else if (c == '%' && in_tag)
|
||||||
|
{
|
||||||
|
last_was_rdelimiter = true;
|
||||||
|
}
|
||||||
|
else if (c == '}' && last_was_rdelimiter)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
working_string += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_tag)
|
||||||
|
{
|
||||||
|
onFoundTag(working_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onFoundTag(const std::string& tag_string)
|
||||||
|
{
|
||||||
|
const auto tag_elements = StringUtils::split(tag_string);
|
||||||
|
|
||||||
|
for (const auto& element : tag_elements)
|
||||||
|
{
|
||||||
|
std::cout << "Got tag element: " << element << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Path mPath;
|
||||||
|
unsigned mWorkingLine{ 0 };
|
||||||
|
std::string mParentName;
|
||||||
|
std::vector<std::string> mRawContent;
|
||||||
|
std::vector<std::string> mProcessedContent;
|
||||||
|
std::vector<TemplateBlock> mBlocks;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TemplatingEngine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TemplatingEngine(const Path& workingDirectory)
|
||||||
|
: mWorkingDirectory(workingDirectory)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadTemplateFiles()
|
||||||
|
{
|
||||||
|
const auto files = Directory::getFilesWithExtension(mWorkingDirectory, mTemplateExtension);
|
||||||
|
for (const auto& file : files)
|
||||||
|
{
|
||||||
|
mTemplateFiles.push_back(TemplateFile(file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void processTemplate(const std::string& name)
|
||||||
|
{
|
||||||
|
for (auto& file : mTemplateFiles)
|
||||||
|
{
|
||||||
|
const auto filename = file.getName();
|
||||||
|
if (filename == name)
|
||||||
|
{
|
||||||
|
processTemplate(file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void processTemplate(TemplateFile& file)
|
||||||
|
{
|
||||||
|
file.loadContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<TemplateFile> mTemplateFiles;
|
||||||
|
Path mWorkingDirectory;
|
||||||
|
std::string mTemplateExtension{ ".html" };
|
||||||
|
};
|
|
@ -20,6 +20,37 @@ bool StringUtils::IsSpace(char c)
|
||||||
return std::isspace(c, loc);
|
return std::isspace(c, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> StringUtils::split(const std::string& input)
|
||||||
|
{
|
||||||
|
std::vector<std::string> substrings;
|
||||||
|
std::string working_string;
|
||||||
|
std::locale loc;
|
||||||
|
bool last_was_nonspace{ false };
|
||||||
|
for (auto c : input)
|
||||||
|
{
|
||||||
|
if (std::isspace(c, loc))
|
||||||
|
{
|
||||||
|
if (last_was_nonspace)
|
||||||
|
{
|
||||||
|
substrings.push_back(working_string);
|
||||||
|
working_string = "";
|
||||||
|
last_was_nonspace = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_was_nonspace = true;
|
||||||
|
working_string += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!working_string.empty())
|
||||||
|
{
|
||||||
|
substrings.push_back(working_string);
|
||||||
|
}
|
||||||
|
return substrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string StringUtils::ToLower(const std::string& s)
|
std::string StringUtils::ToLower(const std::string& s)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class StringUtils
|
class StringUtils
|
||||||
{
|
{
|
||||||
|
@ -20,4 +21,5 @@ public:
|
||||||
static std::string ToLower(const std::string& s);
|
static std::string ToLower(const std::string& s);
|
||||||
static std::string convert(const std::wstring& input);
|
static std::string convert(const std::wstring& input);
|
||||||
static std::string ToPaddedString(unsigned numBytes, unsigned entry);
|
static std::string ToPaddedString(unsigned numBytes, unsigned entry);
|
||||||
|
static std::vector<std::string> split(const std::string& input);
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@ list(APPEND TestFiles
|
||||||
core/TestBinaryStream.cpp
|
core/TestBinaryStream.cpp
|
||||||
core/TestTomlReader.cpp
|
core/TestTomlReader.cpp
|
||||||
compiler/TestLexer.cpp
|
compiler/TestLexer.cpp
|
||||||
|
compiler/TestTemplatingEngine.cpp
|
||||||
compression/TestStreamCompressor.cpp
|
compression/TestStreamCompressor.cpp
|
||||||
database/TestDatabase.cpp
|
database/TestDatabase.cpp
|
||||||
fonts/TestFontReader.cpp
|
fonts/TestFontReader.cpp
|
||||||
|
@ -50,7 +51,7 @@ foreach(TestFile ${TestFiles})
|
||||||
|
|
||||||
add_executable(${TestName} ${TestFile})
|
add_executable(${TestName} ${TestFile})
|
||||||
|
|
||||||
target_link_libraries(${TestName} PUBLIC core compression fonts network image publishing video database geometry audio graphics web client test_utils ${DBUS_LIBRARIES})
|
target_link_libraries(${TestName} PUBLIC core compiler compression fonts network image publishing video database geometry audio graphics web client test_utils ${DBUS_LIBRARIES})
|
||||||
set_property(TARGET ${TestName} PROPERTY FOLDER test)
|
set_property(TARGET ${TestName} PROPERTY FOLDER test)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
|
15
test/compiler/TestTemplatingEngine.cpp
Normal file
15
test/compiler/TestTemplatingEngine.cpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "TemplatingEngine.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
const auto data_loc = std::filesystem::path(__FILE__) / "../../data";
|
||||||
|
|
||||||
|
auto engine = TemplatingEngine(data_loc);
|
||||||
|
engine.loadTemplateFiles();
|
||||||
|
engine.processTemplate("index");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
17
test/data/base.html
Normal file
17
test/data/base.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
{% block head %}
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<title>{% block title %}{% endblock %} - My Webpage</title>
|
||||||
|
{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="content">{% block content %}{% endblock %}</div>
|
||||||
|
<div id="footer">
|
||||||
|
{% block footer %}
|
||||||
|
© Copyright 2008 by <a href="http://domain.invalid/">you</a>.
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
14
test/data/index.html
Normal file
14
test/data/index.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}Index{% endblock %}
|
||||||
|
{% block head %}
|
||||||
|
{{ super() }}
|
||||||
|
<style type="text/css">
|
||||||
|
.important { color: #336699; }
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h1>Index</h1>
|
||||||
|
<p class="important">
|
||||||
|
Welcome to my awesome homepage.
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue