mirror of
https://github.com/ohwgiles/laminar.git
synced 2024-10-27 20:34:20 +00:00
webui may be modified with custom style.css
This commit is contained in:
parent
6919a74d0a
commit
93b428529e
@ -66,7 +66,7 @@ For Apache, see [Apache Reverse Proxy](https://httpd.apache.org/docs/2.4/howto/r
|
|||||||
|
|
||||||
#### Set the page title
|
#### Set the page title
|
||||||
|
|
||||||
Change `LAMINAR_TITLE` in `/etc/laminar.conf` to your preferred page title.
|
Change `LAMINAR_TITLE` in `/etc/laminar.conf` to your preferred page title. For further WebUI customization, consider using a [custom style sheet](#customizing-the-webui).
|
||||||
|
|
||||||
#### More configuration options
|
#### More configuration options
|
||||||
|
|
||||||
@ -483,6 +483,11 @@ cmake src
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Customizing the WebUI
|
||||||
|
|
||||||
|
If it exists, the file `/var/lib/laminar/custom/style.css` will be served by laminar and may be used to change the appearance of Laminar's WebUI.
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
|
@ -120,6 +120,11 @@ struct LaminarInterface {
|
|||||||
// $LAMINAR_HOME/archive. This shouldn't be used, because the sysadmin
|
// $LAMINAR_HOME/archive. This shouldn't be used, because the sysadmin
|
||||||
// should have configured a real webserver to serve these things.
|
// should have configured a real webserver to serve these things.
|
||||||
virtual bool getArtefact(std::string path, std::string& result) = 0;
|
virtual bool getArtefact(std::string path, std::string& result) = 0;
|
||||||
|
|
||||||
|
// Fetches the content of $LAMINAR_HOME/custom/style.css or an empty
|
||||||
|
// string. This shouldn't be used, because the sysadmin should have
|
||||||
|
// configured a real webserver to serve these things.
|
||||||
|
virtual std::string getCustomCss() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LAMINAR_INTERFACE_H_
|
#endif // LAMINAR_INTERFACE_H_
|
||||||
|
@ -795,25 +795,38 @@ void Laminar::runFinished(Run * r) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Small helper function to return the full contents of a file given its path.
|
||||||
|
// It reads in the whole file into the given string reference.
|
||||||
|
// This is a terrible way to serve files (especially large ones). Hopefully
|
||||||
|
// no-one uses this function and configures their webservers appropriately.
|
||||||
|
static bool slurp(fs::path path, std::string& output) {
|
||||||
|
if(!fs::is_regular_file(path))
|
||||||
|
return false;
|
||||||
|
std::ifstream fstr(path.string());
|
||||||
|
fstr.seekg(0, std::ios::end);
|
||||||
|
ssize_t sz = fstr.tellg();
|
||||||
|
if(fstr.good()) {
|
||||||
|
output.resize(static_cast<size_t>(sz));
|
||||||
|
fstr.seekg(0);
|
||||||
|
fstr.read(&output[0], sz);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Laminar::getArtefact(std::string path, std::string& result) {
|
bool Laminar::getArtefact(std::string path, std::string& result) {
|
||||||
if(archiveUrl != ARCHIVE_URL_DEFAULT) {
|
if(archiveUrl != ARCHIVE_URL_DEFAULT) {
|
||||||
// we shouldn't have got here. Probably an invalid link.
|
// we shouldn't have got here. Probably an invalid link.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Reads in the whole file into the given string reference.
|
|
||||||
// This is a terrible way to serve files (especially large ones).
|
|
||||||
fs::path file(fs::path(homeDir)/"archive"/path);
|
fs::path file(fs::path(homeDir)/"archive"/path);
|
||||||
// no support for browsing archived directories
|
return slurp(file, result);
|
||||||
if(fs::is_directory(file))
|
}
|
||||||
return false;
|
|
||||||
std::ifstream fstr(file.string());
|
std::string Laminar::getCustomCss()
|
||||||
fstr.seekg(0, std::ios::end);
|
{
|
||||||
ssize_t sz = fstr.tellg();
|
fs::path file(fs::path(homeDir)/"custom"/"style.css");
|
||||||
if(fstr.good()) {
|
std::string result;
|
||||||
result.resize(static_cast<size_t>(sz));
|
slurp(file, result);
|
||||||
fstr.seekg(0);
|
return result;
|
||||||
fstr.read(&result[0], sz);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ public:
|
|||||||
void sendStatus(LaminarClient* client) override;
|
void sendStatus(LaminarClient* client) override;
|
||||||
bool setParam(std::string job, uint buildNum, std::string param, std::string value) override;
|
bool setParam(std::string job, uint buildNum, std::string param, std::string value) override;
|
||||||
bool getArtefact(std::string path, std::string& result) override;
|
bool getArtefact(std::string path, std::string& result) override;
|
||||||
|
std::string getCustomCss() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool loadConfiguration();
|
bool loadConfiguration();
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
<script src="/js/Chart.min.js"></script>
|
<script src="/js/Chart.min.js"></script>
|
||||||
<script src="/js/Chart.HorizontalBar.js"></script>
|
<script src="/js/Chart.HorizontalBar.js"></script>
|
||||||
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="/custom/style.css" rel="stylesheet">
|
||||||
<script src="/js/app.js" defer></script>
|
<script src="/js/app.js" defer></script>
|
||||||
<style>
|
<style>
|
||||||
body, html { height: 100%; }
|
body, html { height: 100%; }
|
||||||
|
@ -210,6 +210,10 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
c->set_status(websocketpp::http::status_code::not_found);
|
c->set_status(websocketpp::http::status_code::not_found);
|
||||||
}
|
}
|
||||||
|
} else if(resource.compare("/custom/style.css") == 0) {
|
||||||
|
c->set_status(websocketpp::http::status_code::ok);
|
||||||
|
c->append_header("Content-Transfer-Encoding", "binary");
|
||||||
|
c->set_body(laminar.getCustomCss());
|
||||||
} else if(resources.handleRequest(resource, &start, &end, &content_type)) {
|
} else if(resources.handleRequest(resource, &start, &end, &content_type)) {
|
||||||
c->set_status(websocketpp::http::status_code::ok);
|
c->set_status(websocketpp::http::status_code::ok);
|
||||||
c->append_header("Content-Type", content_type);
|
c->append_header("Content-Type", content_type);
|
||||||
|
Loading…
Reference in New Issue
Block a user