Start templating engine.

This commit is contained in:
jmsgrogan 2022-10-12 09:01:19 +01:00
parent c0bcfaccac
commit cdd0cc6b78
9 changed files with 230 additions and 1 deletions

View file

@ -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})

View file

View 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" };
};

View file

@ -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;

View file

@ -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);
}; };

View file

@ -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()

View 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
View 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 %}
&copy; Copyright 2008 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
</html>

14
test/data/index.html Normal file
View 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 %}