1
0
mirror of https://github.com/ohwgiles/laminar.git synced 2025-06-13 12:54:29 +00:00

Add the ability to customize index.html

This commit is contained in:
Cameron Eagans 2020-03-03 11:05:39 -07:00
parent f981491a34
commit 0dd0e1c9d8
4 changed files with 37 additions and 5 deletions

View File

@ -622,6 +622,10 @@ If it exists, the file `/var/lib/laminar/custom/style.css` will be served by lam
This directory is also a good place to add any extra assets needed for this customization, but note that in this case you will need to serve this directory directly from your [HTTP reverse proxy](#Service-configuration) (highly recommended). This directory is also a good place to add any extra assets needed for this customization, but note that in this case you will need to serve this directory directly from your [HTTP reverse proxy](#Service-configuration) (highly recommended).
## Custom HTML template
If it exists, the file `/var/lib/laminar/custom/index.html` will be served by laminar instead of the default markup that is bundled into the Laminar binary. This file can be used to change any aspect of Laminar's WebUI, including adding custom menu links, stylesheets, or anything else. Any additional assets that are needed will need to be served directly from your [HTTP reverse proxy](#Service-configuration) (highly recommended).
--- ---
# Badges # Badges

View File

@ -211,14 +211,16 @@ kj::Promise<void> Http::request(kj::HttpMethod method, kj::StringPtr url, const
return writeEvents(p,s); return writeEvents(p,s);
}).attach(kj::mv(stream)).attach(kj::mv(peer)); }).attach(kj::mv(stream)).attach(kj::mv(peer));
} }
} else if(url.startsWith("/archive/")) { }
if(url.startsWith("/archive/")) {
KJ_IF_MAYBE(file, laminar.getArtefact(url.slice(strlen("/archive/")))) { KJ_IF_MAYBE(file, laminar.getArtefact(url.slice(strlen("/archive/")))) {
auto array = (*file)->mmap(0, (*file)->stat().size); auto array = (*file)->mmap(0, (*file)->stat().size);
responseHeaders.add("Content-Transfer-Encoding", "binary"); responseHeaders.add("Content-Transfer-Encoding", "binary");
auto stream = response.send(200, "OK", responseHeaders, array.size()); auto stream = response.send(200, "OK", responseHeaders, array.size());
return stream->write(array.begin(), array.size()).attach(kj::mv(array)).attach(kj::mv(file)).attach(kj::mv(stream)); return stream->write(array.begin(), array.size()).attach(kj::mv(array)).attach(kj::mv(file)).attach(kj::mv(stream));
} }
} else if(parseLogEndpoint(url, name, num)) { }
if(parseLogEndpoint(url, name, num)) {
auto lw = kj::heap<WithSetRef<LogWatcher>>(logWatchers); auto lw = kj::heap<WithSetRef<LogWatcher>>(logWatchers);
lw->job = name; lw->job = name;
lw->run = num; lw->run = num;
@ -236,19 +238,33 @@ kj::Promise<void> Http::request(kj::HttpMethod method, kj::StringPtr url, const
return writeLogChunk(c, s); return writeLogChunk(c, s);
}).attach(kj::mv(output)).attach(kj::mv(stream)).attach(kj::mv(lw)); }).attach(kj::mv(output)).attach(kj::mv(stream)).attach(kj::mv(lw));
} }
} else if(url == "/custom/style.css") { }
if(url == "/custom/style.css") {
responseHeaders.set(kj::HttpHeaderId::CONTENT_TYPE, "text/css; charset=utf-8"); responseHeaders.set(kj::HttpHeaderId::CONTENT_TYPE, "text/css; charset=utf-8");
responseHeaders.add("Content-Transfer-Encoding", "binary"); responseHeaders.add("Content-Transfer-Encoding", "binary");
std::string css = laminar.getCustomCss(); std::string css = laminar.getCustomCss();
auto stream = response.send(200, "OK", responseHeaders, css.size()); auto stream = response.send(200, "OK", responseHeaders, css.size());
return stream->write(css.data(), css.size()).attach(kj::mv(css)).attach(kj::mv(stream)); return stream->write(css.data(), css.size()).attach(kj::mv(css)).attach(kj::mv(stream));
} else if(resources->handleRequest(url.cStr(), &start, &end, &content_type)) { }
// If there is custom html defined, serve it. Otherwise, the default html
// will be served by the next block.
if(url == "/index.html" || url == "/") {
responseHeaders.set(kj::HttpHeaderId::CONTENT_TYPE, "text/html; charset=utf-8");
responseHeaders.add("Content-Transfer-Encoding", "binary");
std::string html = laminar.getCustomIndexHtml();
if (!html.empty()) {
auto stream = response.send(200, "OK", responseHeaders, html.size());
return stream->write(html.data(), html.size()).attach(kj::mv(html)).attach(kj::mv(stream));
}
}
if(resources->handleRequest(url.cStr(), &start, &end, &content_type)) {
responseHeaders.set(kj::HttpHeaderId::CONTENT_TYPE, content_type); responseHeaders.set(kj::HttpHeaderId::CONTENT_TYPE, content_type);
responseHeaders.add("Content-Encoding", "gzip"); responseHeaders.add("Content-Encoding", "gzip");
responseHeaders.add("Content-Transfer-Encoding", "binary"); responseHeaders.add("Content-Transfer-Encoding", "binary");
auto stream = response.send(200, "OK", responseHeaders, end-start); auto stream = response.send(200, "OK", responseHeaders, end-start);
return stream->write(start, end-start).attach(kj::mv(stream)); return stream->write(start, end-start).attach(kj::mv(stream));
} else if(url.startsWith("/badge/") && url.endsWith(".svg") && laminar.handleBadgeRequest(std::string(url.begin()+7, url.size()-11), badge)) { }
if(url.startsWith("/badge/") && url.endsWith(".svg") && laminar.handleBadgeRequest(std::string(url.begin()+7, url.size()-11), badge)) {
responseHeaders.set(kj::HttpHeaderId::CONTENT_TYPE, "image/svg+xml"); responseHeaders.set(kj::HttpHeaderId::CONTENT_TYPE, "image/svg+xml");
responseHeaders.add("Cache-Control", "no-cache"); responseHeaders.add("Cache-Control", "no-cache");
auto stream = response.send(200, "OK", responseHeaders, badge.size()); auto stream = response.send(200, "OK", responseHeaders, badge.size());

View File

@ -796,3 +796,11 @@ std::string Laminar::getCustomCss() {
return std::string(); return std::string();
} }
} }
std::string Laminar::getCustomIndexHtml() {
KJ_IF_MAYBE(htmlFile, fsHome->tryOpenFile(kj::Path{"custom","index.html"})) {
return (*htmlFile)->readAllText().cStr();
} else {
return std::string();
}
}

View File

@ -95,6 +95,10 @@ public:
// which handles this url. // which handles this url.
std::string getCustomCss(); std::string getCustomCss();
// Fetches the content of $LAMINAR_HOME/custom/index.html or an empty
// string. This is used for custom template overrides.
std::string getCustomIndexHtml();
// Aborts a single job // Aborts a single job
bool abort(std::string job, uint buildNum); bool abort(std::string job, uint buildNum);