mirror of
				https://github.com/ohwgiles/laminar.git
				synced 2025-06-13 12:54:29 +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 | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
| @ -483,6 +483,11 @@ cmake src | ||||
| 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 | ||||
| 
 | ||||
|  | ||||
| @ -120,6 +120,11 @@ struct LaminarInterface { | ||||
|     // $LAMINAR_HOME/archive. This shouldn't be used, because the sysadmin
 | ||||
|     // should have configured a real webserver to serve these things.
 | ||||
|     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_
 | ||||
|  | ||||
| @ -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) { | ||||
|     if(archiveUrl != ARCHIVE_URL_DEFAULT) { | ||||
|         // we shouldn't have got here. Probably an invalid link.
 | ||||
|         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); | ||||
|     // no support for browsing archived directories
 | ||||
|     if(fs::is_directory(file)) | ||||
|         return false; | ||||
|     std::ifstream fstr(file.string()); | ||||
|     fstr.seekg(0, std::ios::end); | ||||
|     ssize_t sz = fstr.tellg(); | ||||
|     if(fstr.good()) { | ||||
|         result.resize(static_cast<size_t>(sz)); | ||||
|         fstr.seekg(0); | ||||
|         fstr.read(&result[0], sz); | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
|     return slurp(file, result); | ||||
| } | ||||
| 
 | ||||
| std::string Laminar::getCustomCss() | ||||
| { | ||||
|     fs::path file(fs::path(homeDir)/"custom"/"style.css"); | ||||
|     std::string result; | ||||
|     slurp(file, result); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| @ -56,6 +56,7 @@ public: | ||||
|     void sendStatus(LaminarClient* client) override; | ||||
|     bool setParam(std::string job, uint buildNum, std::string param, std::string value) override; | ||||
|     bool getArtefact(std::string path, std::string& result) override; | ||||
|     std::string getCustomCss() override; | ||||
| 
 | ||||
| private: | ||||
|     bool loadConfiguration(); | ||||
|  | ||||
| @ -14,6 +14,7 @@ | ||||
|  <script src="/js/Chart.min.js"></script> | ||||
|  <script src="/js/Chart.HorizontalBar.js"></script> | ||||
|  <link href="/css/bootstrap.min.css" rel="stylesheet"> | ||||
|  <link href="/custom/style.css" rel="stylesheet"> | ||||
|  <script src="/js/app.js" defer></script> | ||||
|  <style> | ||||
|   body, html { height: 100%; } | ||||
|  | ||||
| @ -210,6 +210,10 @@ public: | ||||
|                 } else { | ||||
|                     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)) { | ||||
|                 c->set_status(websocketpp::http::status_code::ok); | ||||
|                 c->append_header("Content-Type", content_type); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user