Rewrite to improve performance and the overall api
This commit is contained in:
parent
1fbb94e9a2
commit
9f9cff55fa
12 changed files with 237 additions and 323 deletions
|
@ -1,34 +1,20 @@
|
|||
namespace Example_Website;
|
||||
|
||||
using System;
|
||||
|
||||
using Aven;
|
||||
using Aven.HTML;
|
||||
|
||||
class Index : Page
|
||||
class Index : Template
|
||||
{
|
||||
|
||||
public override void LoadPageContents()
|
||||
public this()
|
||||
{
|
||||
this.AddElement(
|
||||
Div("Content aisjdoasjiodashuihnsduijhnuisdhfsd",
|
||||
H1("Hello from Aven"),
|
||||
Raw("Aven is a website generation library, that can be used from"), A("Beef")..SetValue("href", "https://Beeflang.org"), Raw("to generate reuseable html."), Br(),
|
||||
Raw("By being integrated into a programming language you can freely write your own templating and generation logic"), Br()
|
||||
)..SetValue("style", "padding: 15px;")
|
||||
);
|
||||
Title = "An aven website";
|
||||
OutputFile = "\\Index.html";
|
||||
}
|
||||
|
||||
public this() : base()
|
||||
public override void Body(HTML body)
|
||||
{
|
||||
Title = scope $"Aven - {Aven.Version}";
|
||||
|
||||
this.AddInlineStyle("""
|
||||
body {
|
||||
margin:0px;
|
||||
}
|
||||
""");
|
||||
|
||||
|
||||
body.Children.Add(Div(
|
||||
H1("Aven Website"),
|
||||
Div("adssadsadsadsadsad", "asidosadsadsd")..SetValue("Style", "color:red;")
|
||||
));
|
||||
}
|
||||
}
|
|
@ -9,8 +9,7 @@ class Program
|
|||
public static void Main()
|
||||
{
|
||||
Aven aven = scope .();
|
||||
aven.Pages.Add(scope Example_Website.Index());
|
||||
aven.OutputDirectory = "../output/";
|
||||
aven.Register(.Owning(new Example_Website.Index()));
|
||||
aven.Build();
|
||||
}
|
||||
}
|
140
src/Aven.bf
140
src/Aven.bf
|
@ -1,94 +1,88 @@
|
|||
namespace Aven;
|
||||
using Aven.Internal;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
|
||||
class Aven
|
||||
{
|
||||
private static readonly Logger _defaultLogger = new .() ~ delete _;
|
||||
private static readonly Builder _defaultBuilder = new .() ~ delete _;
|
||||
private List<Template> _templates = new .() ~ DeleteContainerAndItems!(_);
|
||||
private Stopwatch _timer = new .() ~ delete _;
|
||||
|
||||
public static readonly String Version = "0.5.0";
|
||||
|
||||
private Dictionary<String, String> _dirs = new .() ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||
private Dictionary<String, String> _files = new .() ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||
|
||||
|
||||
public List<Page> Pages = new .(10) ~ delete _;
|
||||
public Logger Log = _defaultLogger;
|
||||
public Builder Builder = _defaultBuilder;
|
||||
public String OutputDirectory = null;
|
||||
|
||||
///Copy a directory to the output directory
|
||||
public Result<void> IncludeDirInOutput(StringView dir, StringView outdir)
|
||||
///Registers an instance of a web template
|
||||
public Result<void> Register(Owning<Template> template)
|
||||
{
|
||||
if(!Directory.Exists(dir))
|
||||
return .Err;
|
||||
_dirs.Add(new .(dir), new .(outdir));
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
///Copy a file to the output directory
|
||||
public Result<void> IncludeFileInOutput(StringView dir, StringView outdir)
|
||||
{
|
||||
if(!File.Exists(dir))
|
||||
return .Err;
|
||||
_files.Add(new .(dir), new .(outdir));
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
///Builds the website
|
||||
public void Build()
|
||||
{
|
||||
Log.Info(scope $"Starting Aven {Version}");
|
||||
Log.Info("Start building");
|
||||
|
||||
if(!EnsureOutputExists())
|
||||
return;
|
||||
|
||||
Builder.Build(this);
|
||||
|
||||
Log.Info("Successfully build");
|
||||
}
|
||||
|
||||
///Writes a file to the location specified by output
|
||||
private Result<void> WriteToOutput(StringView file, StringView data)
|
||||
{
|
||||
String outdir = scope .();
|
||||
if (Path.GetDirectoryPath(scope $"{OutputDirectory}/{file}", outdir) case .Ok)
|
||||
if (template case .Owning(let val))
|
||||
{
|
||||
if (Directory.CreateDirectory(outdir) case .Ok)
|
||||
{
|
||||
if(File.WriteAllText(scope $"{OutputDirectory}/{file}", data) case .Ok)
|
||||
{
|
||||
Log.Info(scope $"Wrote file to {OutputDirectory}/{file}");
|
||||
}
|
||||
}
|
||||
Log.Debug("Registered new template instance");
|
||||
_templates.Add(val);
|
||||
return .Ok;
|
||||
}
|
||||
Log.Error(scope $"Attempt to write to {OutputDirectory}/{file} failed");
|
||||
Log.Warn("Unable to register template instance");
|
||||
return .Err;
|
||||
}
|
||||
|
||||
private bool EnsureOutputExists()
|
||||
public void Build(StringView outputDir = "./output")
|
||||
{
|
||||
if(OutputDirectory == null)
|
||||
_timer.Start();
|
||||
|
||||
String toWrite = new .(10000);
|
||||
defer delete toWrite;
|
||||
|
||||
Log.Info("Start building");
|
||||
for (var page in _templates)
|
||||
{
|
||||
Log.Error("No output directory is has been set");
|
||||
return false;
|
||||
toWrite.Clear();
|
||||
toWrite
|
||||
..Append("""
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
""")
|
||||
|
||||
|
||||
..Append("<title>")
|
||||
..Append(page.Title)
|
||||
..Append("</title>\n")
|
||||
|
||||
..Append("<script>")
|
||||
..Append(page.Scripts)
|
||||
..Append("</script>\n")
|
||||
|
||||
..Append("<style>")
|
||||
..Append(page.Styles)
|
||||
..Append("</style>\n")
|
||||
|
||||
..Append("</head>\n");
|
||||
|
||||
var body = page.Body(.. Custom("body"))..ToString(toWrite);
|
||||
delete body;
|
||||
|
||||
toWrite.Append("</html>\n");
|
||||
|
||||
Log.Debug("Successfully build page");
|
||||
|
||||
String outFile = scope $"{outputDir}/{page.OutputFile}";
|
||||
String outDir = scope .();
|
||||
if (Path.GetDirectoryPath(outFile, outDir) case .Err)
|
||||
{
|
||||
Log.Error(scope $"Unable to write to file: {outputDir}{page.OutputFile}");
|
||||
continue;
|
||||
}
|
||||
Directory.CreateDirectory(outDir).IgnoreError();
|
||||
|
||||
if (File.WriteAllText(scope $"{outputDir}{page.OutputFile}", toWrite) case .Err)
|
||||
{
|
||||
Log.Error(scope $"Unable to write to file: {outputDir}{page.OutputFile}");
|
||||
continue;
|
||||
}
|
||||
Log.Info(scope $"Wrote to file: {outputDir}{page.OutputFile}");
|
||||
}
|
||||
|
||||
if(Directory.Exists(OutputDirectory))
|
||||
return true;
|
||||
|
||||
if(Directory.CreateDirectory(OutputDirectory) case .Err)
|
||||
{
|
||||
Log.Error("Unable to create output directoy");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.Info("Output directory has been created");
|
||||
|
||||
return true;
|
||||
Log.Info(scope $"Finished generation in: {_timer.ElapsedMilliseconds}ms");
|
||||
_timer.Reset();
|
||||
_timer.Stop();
|
||||
}
|
||||
}
|
102
src/HTML.bf
102
src/HTML.bf
|
@ -1,73 +1,73 @@
|
|||
namespace Aven.HTML;
|
||||
namespace Aven;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
class HTML
|
||||
{
|
||||
static public implicit operator HTML (StringView v) => Raw(v);
|
||||
|
||||
private String _Name = new .("") ~ delete _;
|
||||
private String _Body = new .("") ~ delete _;
|
||||
private String _Id = new .("") ~ delete _;
|
||||
private HashSet<String> _Classes = new .() ~ DeleteContainerAndItems!(_);
|
||||
private List<HTML> _Children = new .() ~ DeleteContainerAndItems!(_);
|
||||
private bool _SelfClosing = false; //makes an object <name />
|
||||
private Dictionary<String, String> _Values = new .() ~ DeleteDictionaryAndKeysAndValues!(_); //Most of these values should come from fields
|
||||
//This is just used to allow arbitrary values for stuff ive missed
|
||||
static public implicit operator HTML(StringView v) => Raw(v);
|
||||
|
||||
public List<HTML> Children = new .() ~ DeleteContainerAndItems!(_);
|
||||
public Dictionary<String, String> Values = new .() ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||
public HashSet<String> Classes = new .() ~ DeleteContainerAndItems!(_);
|
||||
public bool SelfClosing = false; //<name />
|
||||
|
||||
private String _name = new .("") ~ delete _;
|
||||
public StringView Name
|
||||
{
|
||||
get => _Name;
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
_Name.Clear();
|
||||
_Name.Append(value);
|
||||
_name.Clear();
|
||||
_name.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
private String _body = new .("") ~ delete _;
|
||||
public StringView Body
|
||||
{
|
||||
get => _Body;
|
||||
get => _body;
|
||||
set
|
||||
{
|
||||
_Body.Clear();
|
||||
_Body.Append(value);
|
||||
_body.Clear();
|
||||
_body.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
private String _id = new .("") ~ delete _;
|
||||
public StringView Id
|
||||
{
|
||||
get => _Id;
|
||||
get => _id;
|
||||
set
|
||||
{
|
||||
_Id.Clear();
|
||||
_Id.Append(value);
|
||||
_id.Clear();
|
||||
_id.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
public this(params Span<HTML> children)
|
||||
{
|
||||
for (var i in children)
|
||||
_Children.Add(i);
|
||||
Children.Add(i);
|
||||
}
|
||||
|
||||
public void SetValue(StringView key, StringView value)
|
||||
{
|
||||
if (_Values.ContainsKeyAlt<StringView>(key))
|
||||
_Values[scope .(key)]..Clear().Append(value);
|
||||
if (Values.ContainsKeyAlt<StringView>(key))
|
||||
Values[scope .(key)]..Clear().Append(value);
|
||||
else
|
||||
_Values.Add(new .(key), new .(value));
|
||||
Values.Add(new .(key), new .(value));
|
||||
}
|
||||
|
||||
public void AddClass(StringView clas) => _Classes.Add(new .(clas));
|
||||
public void SetBody(StringView value) => Body = value;
|
||||
public void SetId(StringView value) => Id = value;
|
||||
public void AddClass(StringView clas) => Classes.Add(new .(clas));
|
||||
public void RemoveClass(StringView clas) => Classes.Remove(scope .(clas));
|
||||
|
||||
public void RemoveClass(StringView clas) => _Classes.Remove(scope .(clas));
|
||||
|
||||
public void Build(String buffer)
|
||||
public override void ToString(String buffer)
|
||||
{
|
||||
if (_SelfClosing && _Name != "")
|
||||
if (SelfClosing && Name != "")
|
||||
{
|
||||
buffer.Append(scope $"<{Name} {CalculateValues(.. scope .())} />");
|
||||
return;
|
||||
|
@ -77,11 +77,11 @@ class HTML
|
|||
if (Name != "")
|
||||
buffer.Append(scope $"<{Name} {CalculateValues(.. scope .())}>\n");
|
||||
|
||||
if (_Body != .Empty)
|
||||
buffer.Append(_Body);
|
||||
if (_body != .Empty)
|
||||
buffer.Append(_body);
|
||||
|
||||
for (var i in _Children)
|
||||
i.Build(buffer);
|
||||
for (var i in Children)
|
||||
i.ToString(buffer);
|
||||
|
||||
if (Name != "")
|
||||
buffer.Append(scope $"</{Name}>\n");
|
||||
|
@ -89,21 +89,19 @@ class HTML
|
|||
|
||||
private void CalculateValues(String buffer)
|
||||
{
|
||||
if(_Id != .Empty)
|
||||
buffer.Append(scope $"id=\"{_Id}\"");
|
||||
if(_id != .Empty)
|
||||
buffer.Append(scope $"id=\"{_id}\"");
|
||||
|
||||
if(_Classes.Count > 0)
|
||||
if(Classes.Count > 0)
|
||||
{
|
||||
buffer.Append("class=\"");
|
||||
for(var i in _Classes)
|
||||
for(var i in Classes)
|
||||
buffer.Append(scope $"{i} ");
|
||||
buffer.Append("\" ");
|
||||
}
|
||||
|
||||
for(var i in _Values)
|
||||
{
|
||||
for(var i in Values)
|
||||
buffer.Append(scope $"{i.key}=\"{i.value}\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +110,7 @@ static
|
|||
public static HTML Raw(StringView body = "")
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_Body.Append(body);
|
||||
toReturn.Body = body;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
@ -137,9 +135,9 @@ static
|
|||
|
||||
var sum = new HTML(children: summary);
|
||||
sum.Name = .("summary");
|
||||
toReturn.[Friend]_Children.Add(sum);
|
||||
toReturn.Children.Add(sum);
|
||||
for(var i in details)
|
||||
toReturn.[Friend]_Children.Add(i);
|
||||
toReturn.Children.Add(i);
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -309,7 +307,7 @@ static
|
|||
public static HTML Hr()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("hr");
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -394,7 +392,7 @@ static
|
|||
public static HTML Br()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("br");
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -556,7 +554,7 @@ static
|
|||
public static HTML Wbr()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("wbr");
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -564,7 +562,7 @@ static
|
|||
public static HTML Area()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("area");
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -579,7 +577,7 @@ static
|
|||
public static HTML Img(StringView src = "", int64 width = -1, int64 height = -1, StringView alt = "")
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
if(src != "") toReturn.SetValue("src", src);
|
||||
if(alt != "") toReturn.SetValue("alt", alt);
|
||||
if(width > 0) toReturn.SetValue("width", width.ToString(.. scope .()));
|
||||
|
@ -598,7 +596,7 @@ static
|
|||
public static HTML Track()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("track");
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -613,7 +611,7 @@ static
|
|||
public static HTML Embed()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("embed");
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -656,7 +654,7 @@ static
|
|||
public static HTML Source()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("source");
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -720,7 +718,7 @@ static
|
|||
public static HTML Col()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("col");
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -812,7 +810,7 @@ static
|
|||
public static HTML Input()
|
||||
{
|
||||
var toReturn = new HTML();
|
||||
toReturn.[Friend]_SelfClosing = true;
|
||||
toReturn.SelfClosing = true;
|
||||
toReturn.Name = .("input");
|
||||
return toReturn;
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
namespace Aven;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
|
||||
class Builder
|
||||
{
|
||||
public void Build(Aven aven)
|
||||
{
|
||||
aven.Log.Debug("Default Builder");
|
||||
|
||||
String output = new .(1000);
|
||||
defer delete output;
|
||||
|
||||
for(var page in aven.Pages)
|
||||
{
|
||||
page.Build(output);
|
||||
if(aven.[Friend]WriteToOutput(page.GetPageFileOutput(), output) case .Err)
|
||||
aven.Log.Warn("Page has not been written");
|
||||
}
|
||||
}
|
||||
}
|
35
src/Internal/Log.bf
Normal file
35
src/Internal/Log.bf
Normal file
|
@ -0,0 +1,35 @@
|
|||
namespace Aven.Internal;
|
||||
|
||||
using System;
|
||||
|
||||
class Log
|
||||
{
|
||||
#if DEBUG
|
||||
public static LogLevel LogLevel = .Debug;
|
||||
#else
|
||||
public static LogLevel LogLevel = .Info;
|
||||
#endif
|
||||
|
||||
public static void Log(LogLevel level, StringView message)
|
||||
{
|
||||
if(level.Underlying >= LogLevel.Underlying)
|
||||
|
||||
switch(level)
|
||||
{
|
||||
case .Debug:
|
||||
Console.WriteLine(scope $"\x1b[36m[Debug]:{message}\x1b[39m");
|
||||
case .Info:
|
||||
Console.WriteLine(scope $"\x1b[34m[Info]:{message}\x1b[39m");
|
||||
case .Warning:
|
||||
Console.WriteLine(scope $"\x1b[33m[Warn]:{message}\x1b[39m");
|
||||
case .Error:
|
||||
Console.WriteLine(scope $"\x1b[31m[Err]:{message}\x1b[39m");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Debug(StringView message) => Log(.Debug, message);
|
||||
public static void Info(StringView message) => Log(.Info, message);
|
||||
public static void Warn(StringView message) => Log(.Warning, message);
|
||||
public static void Error(StringView message) => Log(.Error, message);
|
||||
|
||||
}
|
9
src/Internal/LogLevel.bf
Normal file
9
src/Internal/LogLevel.bf
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Aven.Internal;
|
||||
|
||||
enum LogLevel
|
||||
{
|
||||
Debug,
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
namespace Aven;
|
||||
|
||||
using System;
|
||||
|
||||
class Logger
|
||||
{
|
||||
public enum LogLevel
|
||||
{
|
||||
Debug,
|
||||
Info,
|
||||
Warn,
|
||||
Error
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public LogLevel CurrentLogLevel = .Debug;
|
||||
#else
|
||||
public LogLevel CurrentLogLevel = .Info;
|
||||
#endif
|
||||
|
||||
///Log a message
|
||||
public virtual void Log(LogLevel logLevel, StringView message)
|
||||
{
|
||||
switch(logLevel)
|
||||
{
|
||||
case .Debug:
|
||||
Console.WriteLine(scope $"[Aven][Debug]: {message}");
|
||||
case .Info:
|
||||
Console.WriteLine(scope $"[Aven][Info]: {message}");
|
||||
case .Warn:
|
||||
Console.WriteLine(scope $"[Aven][Warn]: {message}");
|
||||
case .Error:
|
||||
Console.WriteLine(scope $"[Aven][Error]: {message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Debug(StringView message) => Log(.Debug, message);
|
||||
public void Info(StringView message) => Log(.Info, message);
|
||||
public void Warn(StringView message) => Log(.Warn, message);
|
||||
public void Error(StringView message) => Log(.Error, message);
|
||||
}
|
12
src/Internal/Owning.bf
Normal file
12
src/Internal/Owning.bf
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace Aven.Internal;
|
||||
|
||||
/*
|
||||
Owning indicates object ownership.
|
||||
A method which has this enum as a parameter takes
|
||||
over ownership of the object and ensures proper deletion
|
||||
*/
|
||||
|
||||
enum Owning<T>
|
||||
{
|
||||
case Owning(T val);
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
namespace Aven;
|
||||
using Aven.HTML;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
/**
|
||||
An instance of this class represents a single .html website
|
||||
*/
|
||||
abstract class Page
|
||||
{
|
||||
private String _title = new .("") ~ delete _;
|
||||
private List<HTML> _elements = new .() ~ DeleteContainerAndItems!(_);
|
||||
private List<String> _scripts = new .() ~ DeleteContainerAndItems!(_);
|
||||
private List<String> _inlineStyle = new .() ~ DeleteContainerAndItems!(_);
|
||||
private List<String> _styles = new .() ~ DeleteContainerAndItems!(_);
|
||||
|
||||
public virtual StringView GetPageFileOutput() => "Index.html";
|
||||
|
||||
public void AddElement(params Span<HTML> elmt)
|
||||
{
|
||||
for(var i in elmt)
|
||||
_elements.Add(i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Build(String buffer)
|
||||
{
|
||||
LoadPageContents();
|
||||
buffer.Append(scope $"""
|
||||
<!Doctype HTML>
|
||||
<!-- Made with Quill version 0.1 -->
|
||||
<html>
|
||||
<head>
|
||||
<title>{Title}</title>
|
||||
{BuildStyles(.. scope .())}
|
||||
{BuildScripts(.. scope .())}
|
||||
</head>
|
||||
<body>
|
||||
{BuildElements(.. scope .())}
|
||||
</body>
|
||||
</html>
|
||||
""");
|
||||
}
|
||||
|
||||
private void BuildElements(String buffer)
|
||||
{
|
||||
for(var i in _elements)
|
||||
{
|
||||
i.Build(buffer);
|
||||
buffer.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildStyles(String buffer)
|
||||
{
|
||||
for(var i in _styles)
|
||||
buffer.Append(scope $"<link rel=\"stylesheet\" href=\"{i}\" />\n");
|
||||
for(var i in _inlineStyle)
|
||||
buffer.Append(scope $"""
|
||||
<style>
|
||||
{i}
|
||||
</style>
|
||||
""");
|
||||
}
|
||||
|
||||
private void BuildScripts(String buffer)
|
||||
{
|
||||
for(var i in _scripts)
|
||||
buffer.Append(scope $"<script src=\"{i}\"></script>\n");
|
||||
}
|
||||
}
|
36
src/Page.bf
36
src/Page.bf
|
@ -1,36 +0,0 @@
|
|||
namespace Aven;
|
||||
|
||||
using System;
|
||||
|
||||
extension Page
|
||||
{
|
||||
public StringView Title
|
||||
{
|
||||
get => _title;
|
||||
set
|
||||
{
|
||||
_title.Clear();
|
||||
_title.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddScripts(params Span<StringView> scripts)
|
||||
{
|
||||
for(var i in scripts)
|
||||
_scripts.Add(new .(i));
|
||||
}
|
||||
|
||||
public void AddStyles(params Span<StringView> styles)
|
||||
{
|
||||
for(var i in styles)
|
||||
_styles.Add(new .(i));
|
||||
}
|
||||
|
||||
public void AddInlineStyle(StringView style)
|
||||
{
|
||||
_inlineStyle.Add(new .(style));
|
||||
}
|
||||
|
||||
public abstract void LoadPageContents();
|
||||
|
||||
}
|
54
src/Template.bf
Normal file
54
src/Template.bf
Normal file
|
@ -0,0 +1,54 @@
|
|||
namespace Aven;
|
||||
|
||||
using System;
|
||||
|
||||
abstract class Template
|
||||
{
|
||||
private String _output = new .("Index.html") ~ delete _;
|
||||
public StringView OutputFile
|
||||
{
|
||||
get => _output;
|
||||
set
|
||||
{
|
||||
_output.Clear();
|
||||
_output.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
private String _title = new .() ~ delete _;
|
||||
public StringView Title
|
||||
{
|
||||
get => _title;
|
||||
set
|
||||
{
|
||||
_title.Clear();
|
||||
_title.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
private String _scripts = new .() ~ delete _;
|
||||
public StringView Scripts
|
||||
{
|
||||
get => _scripts;
|
||||
set
|
||||
{
|
||||
_scripts.Clear();
|
||||
_scripts.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
private String _styles = new .() ~ delete _;
|
||||
public StringView Styles
|
||||
{
|
||||
get => _styles;
|
||||
set
|
||||
{
|
||||
_styles.Clear();
|
||||
_styles.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void Body(HTML body); ///Returns the html element thats supposed to be the page body
|
||||
|
||||
public virtual void Head(String buffer) {}; //Allows template files to have their own custom head beyond our defaults
|
||||
}
|
Loading…
Add table
Reference in a new issue