Skip to content

Commit

Permalink
new configs CustomFavIconPath + CustomTitle
Browse files Browse the repository at this point in the history
  • Loading branch information
amazy committed Sep 9, 2024
1 parent f55d2ec commit 65a68f9
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 13 deletions.
4 changes: 4 additions & 0 deletions Plugin/DefaultConfiguration.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
// "CustomCssPath": "/home/my/path/to/custom.css",
// "CustomLogoUrl": "https://my.company/logo.png",
// "CustomLogoPath": "/home/my/path/to/logo.png",
// "CustomFavIconPath": "/home/my/path/to/favicon.ico", // note: this can be a .png, .svg or .ico file

// Custom Window/Tab Title
// "CustomTitle": "Orthanc Explorer 2",

// This block of configuration is transmitted as is to the frontend application.
// Make sure not to store any secret here
Expand Down
75 changes: 63 additions & 12 deletions Plugin/Plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ std::string customCssPath_;
std::string theme_ = "light";
std::string customLogoPath_;
std::string customLogoUrl_;
std::string customFavIconPath_;
std::string customTitle_;

enum CustomFilesPath
{
CustomFilesPath_Logo,
CustomFilesPath_FavIcon
};


template <enum Orthanc::EmbeddedResources::DirectoryResourceId folder>
Expand Down Expand Up @@ -102,7 +110,8 @@ void ServeEmbeddedFile(OrthancPluginRestOutput* output,
}
}

void ServeCustomLogo(OrthancPluginRestOutput* output,
template <enum CustomFilesPath customFile>
void ServeCustomFile(OrthancPluginRestOutput* output,
const char* url,
const OrthancPluginHttpRequest* request)
{
Expand All @@ -114,22 +123,35 @@ void ServeCustomLogo(OrthancPluginRestOutput* output,
}
else
{
std::string logoFileContent;
std::string fileContent;
std::string customFileContent;
std::string customFilePath;
if (customFile == CustomFilesPath_FavIcon)
{
customFilePath = customFavIconPath_;
}
else if (customFile == CustomFilesPath_Logo)
{
customFilePath = customLogoPath_;
}
else
{
throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
}

std::string customCssFileContent;
Orthanc::SystemToolbox::ReadFile(logoFileContent, customLogoPath_);
Orthanc::MimeType mimeType = Orthanc::SystemToolbox::AutodetectMimeType(customLogoPath_);
Orthanc::SystemToolbox::ReadFile(fileContent, customFilePath);
Orthanc::MimeType mimeType = Orthanc::SystemToolbox::AutodetectMimeType(customFilePath);

// include an ETag for correct cache handling
OrthancPlugins::OrthancString md5;
size_t size = logoFileContent.size();
md5.Assign(OrthancPluginComputeMd5(OrthancPlugins::GetGlobalContext(), logoFileContent.c_str(), size));
size_t size = fileContent.size();
md5.Assign(OrthancPluginComputeMd5(OrthancPlugins::GetGlobalContext(), fileContent.c_str(), size));

std::string etag = "\"" + std::string(md5.GetContent()) + "\"";
OrthancPluginSetHttpHeader(OrthancPlugins::GetGlobalContext(), output, "ETag", etag.c_str());
OrthancPluginSetHttpHeader(OrthancPlugins::GetGlobalContext(), output, "Cache-Control", "no-cache");

OrthancPluginAnswerBuffer(context, output, logoFileContent.c_str(), size, Orthanc::EnumerationToString(mimeType));
OrthancPluginAnswerBuffer(context, output, fileContent.c_str(), size, Orthanc::EnumerationToString(mimeType));
}
}

Expand Down Expand Up @@ -303,6 +325,21 @@ void ReadConfiguration()
{
theme_ = "dark";
}

if (jsonConfig.isMember("CustomFavIconPath") && jsonConfig["CustomFavIconPath"].isString())
{
customFavIconPath_ = jsonConfig["CustomFavIconPath"].asString();
if (!Orthanc::SystemToolbox::IsExistingFile(customFavIconPath_))
{
LOG(ERROR) << "Unable to accesss the 'CustomFavIconPath': " << customFavIconPath_;
throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentFile);
}
}

if (jsonConfig.isMember("CustomTitle") && jsonConfig["CustomTitle"].isString())
{
customTitle_ = jsonConfig["CustomTitle"].asString();
}
}

enableShares_ = pluginJsonConfiguration_["UiOptions"]["EnableShares"].asBool(); // we are sure that the value exists since it is in the default configuration file
Expand Down Expand Up @@ -581,6 +618,11 @@ void GetOE2Configuration(OrthancPluginRestOutput* output,
oe2Configuration["CustomLogoUrl"] = customLogoUrl_;
}

if (!customTitle_.empty())
{
oe2Configuration["CustomTitle"] = customTitle_;
}

Json::Value& uiOptions = oe2Configuration["UiOptions"];

if (hasUserProfile_)
Expand Down Expand Up @@ -769,7 +811,7 @@ extern "C"
if (!customLogoPath_.empty())
{
OrthancPlugins::RegisterRestCallback
<ServeCustomLogo>
<ServeCustomFile<CustomFilesPath_Logo> >
(oe2BaseUrl_ + "app/customizable/custom-logo", true);
}

Expand All @@ -787,10 +829,19 @@ extern "C"
OrthancPlugins::RegisterRestCallback
<ServeEmbeddedFile<Orthanc::EmbeddedResources::WEB_APPLICATION_INDEX_RETRIEVE_AND_VIEW, Orthanc::MimeType_Html> >
(oe2BaseUrl_ + "app/retrieve-and-view.html", true);
OrthancPlugins::RegisterRestCallback
<ServeEmbeddedFile<Orthanc::EmbeddedResources::WEB_APPLICATION_FAVICON, Orthanc::MimeType_Ico> >
(oe2BaseUrl_ + "app/favicon.ico", true);

if (customFavIconPath_.empty())
{
OrthancPlugins::RegisterRestCallback
<ServeEmbeddedFile<Orthanc::EmbeddedResources::WEB_APPLICATION_FAVICON, Orthanc::MimeType_Ico> >
(oe2BaseUrl_ + "app/favicon.ico", true);
}
else
{
OrthancPlugins::RegisterRestCallback
<ServeCustomFile<CustomFilesPath_FavIcon> >
(oe2BaseUrl_ + "app/favicon.ico", true);
}
// second part are all the routes that are actually handled by vue-router and that are actually returning the same file (index.html)
OrthancPlugins::RegisterRestCallback
<ServeEmbeddedFile<Orthanc::EmbeddedResources::WEB_APPLICATION_INDEX, Orthanc::MimeType_Html> >
Expand Down
2 changes: 1 addition & 1 deletion WebApplication/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Orthanc Explorer 2</title>
<title>...</title>
<script>
// Custom bit of code to redirect to /app/ if the uri is /app
// The reason for this is that the path to assets is relative
Expand Down
6 changes: 6 additions & 0 deletions WebApplication/src/store/modules/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ const actions = {
commit('setCustomLogo', { customLogoUrl: customLogoUrl, hasCustomLogo: oe2Config['HasCustomLogo']});
}

if ('CustomTitle' in oe2Config) {
document.title = oe2Config['CustomTitle'];
} else {
document.title = "Orthanc Explorer 2";
}

for (const [pluginName, pluginConfiguration] of Object.entries(oe2Config['Plugins'])) {

commit('setInstalledPlugin', { plugin: pluginName, pluginConfiguration: pluginConfiguration})
Expand Down
8 changes: 8 additions & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
Pending changes in the mainline
===============================

Changes:
- new configuration "CustomFavIconPath" to customize the FavIcon
- new configuration "CustomTitle" to customize the tab/window title


1.6.1 (2024-08-29)
==================

Expand Down

0 comments on commit 65a68f9

Please sign in to comment.