From b219ef767e54ea4c76b0a4393a155016ff4b9d02 Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Wed, 20 Sep 2023 14:07:20 -0400 Subject: [PATCH 1/9] Add the ability to supply your own custom css file --- docs/example/assets/site/custom.css | 12 ++++++++ docs/example/workspace.dsl | 2 ++ .../generatr/site/model/CustomCSSViewModel.kt | 28 +++++++++++++++++++ .../site/generatr/site/model/PageViewModel.kt | 7 +++-- .../site/generatr/site/views/Page.kt | 16 +++++------ 5 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 docs/example/assets/site/custom.css create mode 100644 src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt diff --git a/docs/example/assets/site/custom.css b/docs/example/assets/site/custom.css new file mode 100644 index 00000000..a42e8e1c --- /dev/null +++ b/docs/example/assets/site/custom.css @@ -0,0 +1,12 @@ +svg g g[id^="link"]:hover path { + stroke:#FF0000 !important; + stroke-width: 2.0; +} + +svg g g[id^="link"]:hover polygon { + stroke:#FF0000 !important; +} + +svg g g[id^="link"]:hover text { + fill:#FF0000 !important; +} diff --git a/docs/example/workspace.dsl b/docs/example/workspace.dsl index 7b3260c9..9c802982 100644 --- a/docs/example/workspace.dsl +++ b/docs/example/workspace.dsl @@ -161,6 +161,8 @@ workspace "Big Bank plc" "This is an example workspace to illustrate the key fea "generatr.style.colors.secondary" "#ffffff" "generatr.style.faviconPath" "site/favicon.ico" "generatr.style.logoPath" "site/logo.png" + "generatr.style.customCSSPath" "site/custom.css" + "generatr.svglink.target" "_self" // full list of available "generatr.markdown.flexmark.extensions" diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt new file mode 100644 index 00000000..9d36dddc --- /dev/null +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt @@ -0,0 +1,28 @@ +package nl.avisi.structurizr.site.generatr.site.model + +import nl.avisi.structurizr.site.generatr.site.GeneratorContext +import nl.avisi.structurizr.site.generatr.site.asUrlToFile +import java.io.File + +class CustomCSSViewModel(generatorContext: GeneratorContext, pageViewModel: PageViewModel) { + val url = customCSSPath(generatorContext)?.let { "/$it".asUrlToFile(pageViewModel.url) } + val type = extractType() + val includecustomCSS = url != null + + private fun customCSSPath(generatorContext: GeneratorContext) = + generatorContext.workspace.views.configuration.properties + .getOrDefault( + "generatr.style.customCSSPath", + null + ) + + private fun extractType(): String? { + return url?.let { + val extension = File(it).extension.lowercase() + if (extension.isBlank() || !arrayOf("css").contains(extension)) + throw IllegalArgumentException("Custom CSS must be a valid *.css file") + + "image/$extension" + } + } +} diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt index bbbdb27f..15fd134a 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt @@ -12,12 +12,13 @@ abstract class PageViewModel(protected val generatorContext: GeneratorContext) { pageSubTitle } val favicon by lazy { FaviconViewModel(generatorContext, this) } + val customCSS by lazy { CustomCSSViewModel(generatorContext, this) } val headerBar by lazy { HeaderBarViewModel(this, generatorContext) } val menu by lazy { MenuViewModel(generatorContext, this) } val includeAutoReloading = generatorContext.serving - - val flexmarkConfig by lazy { - buildFlexmarkConfig(generatorContext) + + val flexmarkConfig by lazy { + buildFlexmarkConfig(generatorContext) } val includeAdmonition = flexmarkConfig.selectedExtensionMap.containsKey("Admonition") val includeKatex = flexmarkConfig.selectedExtensionMap.containsKey("GitLab") diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt index e013ab8b..19621708 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt @@ -18,16 +18,14 @@ private fun HTML.headFragment(viewModel: PageViewModel) { meta(name = "viewport", content = "width=device-width, initial-scale=1") title { +viewModel.pageTitle } link(rel = "stylesheet", href = "https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css") - link( - rel = "stylesheet", - href = "../" + "/style.css".asUrlToFile(viewModel.url) - ) - link( - rel = "stylesheet", - href = "./" + "/style-branding.css".asUrlToFile(viewModel.url) - ) + link(rel = "stylesheet", href = "../" + "/style.css".asUrlToFile(viewModel.url)) + link(rel = "stylesheet", href = "./" + "/style-branding.css".asUrlToFile(viewModel.url)) - if (viewModel.includeAdmonition) + if (viewModel.customCSS.includecustomCSS){ + link(rel = "stylesheet", href = "./" + viewModel.customCSS.url) + } + + if (viewModel.includeAdmonition) markdownAdmonitionStylesheet(viewModel) if (viewModel.includeKatex) From 8e6c2c3f5f6184d96deddf45f9fe3e63edffc33d Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Wed, 20 Sep 2023 14:11:41 -0400 Subject: [PATCH 2/9] Added reference to new property in readme file. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 314df5af..e0cc5336 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,7 @@ architecture model: | `generatr.style.colors.secondary` | Secondary site color, used for font color in header bar and for active menu. | `#cccccc` | `#ffffff` | | `generatr.style.faviconPath` | Site logo location relative to the configured `assets` folder. When configured, the logo image will be place on the left side in the header bar. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/favicon.ico` | | `generatr.style.logoPath` | Site favicon location relative to the configured `assets` folder. When configured, the favicon will be set for all generated pages. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/logo.png` | +| `generatr.style.customCSSPath` | Site custom css location relative to the configured `assets` folder. When configured this css file will be loaded for all pages. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/custom.css` | | `generatr.search.language` | Indexing/stemming language for the search index. See [Lunr language support](https://github.com/olivernn/lunr-languages) | `en` | `nl` | | `generatr.markdown.flexmark.extensions` | Additional extensions to the markdown generator to add new markdown capabilities. [More Details](https://avisi-cloud.github.io/structurizr-site-generatr/main/extended-markdown-features/) | Tables | `Tables,Admonition` | | `generatr.svglink.target` | Specifies the link target for element links in the exported svg | `_top` | `_self` | From dda250aef672b5e30e730ab193f0313cfb51716c Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Thu, 21 Sep 2023 13:45:10 -0400 Subject: [PATCH 3/9] Moved the loading of the custom CSS to be the last item in the header so you can override css for FlexMark plugins also. Also a small bit of code cleanup --- docs/example/workspace.dsl | 1 - .../structurizr/site/generatr/site/model/PageViewModel.kt | 6 +----- .../nl/avisi/structurizr/site/generatr/site/views/Page.kt | 8 ++++---- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/docs/example/workspace.dsl b/docs/example/workspace.dsl index 9c802982..b2b760eb 100644 --- a/docs/example/workspace.dsl +++ b/docs/example/workspace.dsl @@ -162,7 +162,6 @@ workspace "Big Bank plc" "This is an example workspace to illustrate the key fea "generatr.style.faviconPath" "site/favicon.ico" "generatr.style.logoPath" "site/logo.png" "generatr.style.customCSSPath" "site/custom.css" - "generatr.svglink.target" "_self" // full list of available "generatr.markdown.flexmark.extensions" diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt index 15fd134a..ee45d58a 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt @@ -16,13 +16,9 @@ abstract class PageViewModel(protected val generatorContext: GeneratorContext) { val headerBar by lazy { HeaderBarViewModel(this, generatorContext) } val menu by lazy { MenuViewModel(generatorContext, this) } val includeAutoReloading = generatorContext.serving - - val flexmarkConfig by lazy { - buildFlexmarkConfig(generatorContext) - } + val flexmarkConfig by lazy { buildFlexmarkConfig(generatorContext) } val includeAdmonition = flexmarkConfig.selectedExtensionMap.containsKey("Admonition") val includeKatex = flexmarkConfig.selectedExtensionMap.containsKey("GitLab") - val configuration = generatorContext.workspace.views.configuration.properties abstract val url: String diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt index 19621708..096a2395 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt @@ -21,10 +21,6 @@ private fun HTML.headFragment(viewModel: PageViewModel) { link(rel = "stylesheet", href = "../" + "/style.css".asUrlToFile(viewModel.url)) link(rel = "stylesheet", href = "./" + "/style-branding.css".asUrlToFile(viewModel.url)) - if (viewModel.customCSS.includecustomCSS){ - link(rel = "stylesheet", href = "./" + viewModel.customCSS.url) - } - if (viewModel.includeAdmonition) markdownAdmonitionStylesheet(viewModel) @@ -40,6 +36,10 @@ private fun HTML.headFragment(viewModel: PageViewModel) { if (viewModel.includeAutoReloading) autoReloadScript(viewModel) + + if (viewModel.customCSS.includecustomCSS){ + link(rel = "stylesheet", href = "./" + viewModel.customCSS.url) + } } } From 7ea9f86c949446c147c0b02db310b2c6146dbe63 Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Wed, 11 Oct 2023 11:46:07 -0400 Subject: [PATCH 4/9] Add support for customer CSS to be either a local file or a hosted file --- README.md | 20 +++++++++---------- docs/example/workspace.dsl | 3 ++- .../generatr/site/model/CustomCSSViewModel.kt | 13 +++--------- .../site/generatr/site/views/Page.kt | 6 +++++- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index e0cc5336..284262cd 100644 --- a/README.md +++ b/README.md @@ -254,16 +254,16 @@ and limitations for this exporter. The look and feel of the generated site can be customized with several additional view properties in the C4 architecture model: -| Property name | Description | Default | Example | -|-----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|---------------------| -| `generatr.style.colors.primary` | Primary site color, used for header bar background and active menu background. | `#333333` | `#485fc7` | -| `generatr.style.colors.secondary` | Secondary site color, used for font color in header bar and for active menu. | `#cccccc` | `#ffffff` | -| `generatr.style.faviconPath` | Site logo location relative to the configured `assets` folder. When configured, the logo image will be place on the left side in the header bar. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/favicon.ico` | -| `generatr.style.logoPath` | Site favicon location relative to the configured `assets` folder. When configured, the favicon will be set for all generated pages. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/logo.png` | -| `generatr.style.customCSSPath` | Site custom css location relative to the configured `assets` folder. When configured this css file will be loaded for all pages. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/custom.css` | -| `generatr.search.language` | Indexing/stemming language for the search index. See [Lunr language support](https://github.com/olivernn/lunr-languages) | `en` | `nl` | -| `generatr.markdown.flexmark.extensions` | Additional extensions to the markdown generator to add new markdown capabilities. [More Details](https://avisi-cloud.github.io/structurizr-site-generatr/main/extended-markdown-features/) | Tables | `Tables,Admonition` | -| `generatr.svglink.target` | Specifies the link target for element links in the exported svg | `_top` | `_self` | +| Property name | Description | Default | Example | +|-----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|------------------------------------------------------| +| `generatr.style.colors.primary` | Primary site color, used for header bar background and active menu background. | `#333333` | `#485fc7` | +| `generatr.style.colors.secondary` | Secondary site color, used for font color in header bar and for active menu. | `#cccccc` | `#ffffff` | +| `generatr.style.faviconPath` | Site logo location relative to the configured `assets` folder. When configured, the logo image will be place on the left side in the header bar. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/favicon.ico` | +| `generatr.style.logoPath` | Site favicon location relative to the configured `assets` folder. When configured, the favicon will be set for all generated pages. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/logo.png` | +| `generatr.style.customCSS` | URL to hosted custom CSS or path to custom css location relative to the configured `assets` folder. When configured this css file will be loaded for all pages. When using a path to a file the `--assets-dir` switch must be used when generating the site and the corresponding file is available in the `assets` folder. | | `site/custom.css` or 'https://uri.example/custom.css | +| `generatr.search.language` | Indexing/stemming language for the search index. See [Lunr language support](https://github.com/olivernn/lunr-languages) | `en` | `nl` | +| `generatr.markdown.flexmark.extensions` | Additional extensions to the markdown generator to add new markdown capabilities. [More Details](https://avisi-cloud.github.io/structurizr-site-generatr/main/extended-markdown-features/) | Tables | `Tables,Admonition` | +| `generatr.svglink.target` | Specifies the link target for element links in the exported svg | `_top` | `_self` | See the included example for usage of some those properties in the diff --git a/docs/example/workspace.dsl b/docs/example/workspace.dsl index b2b760eb..ba59ae79 100644 --- a/docs/example/workspace.dsl +++ b/docs/example/workspace.dsl @@ -161,7 +161,8 @@ workspace "Big Bank plc" "This is an example workspace to illustrate the key fea "generatr.style.colors.secondary" "#ffffff" "generatr.style.faviconPath" "site/favicon.ico" "generatr.style.logoPath" "site/logo.png" - "generatr.style.customCSSPath" "site/custom.css" + "generatr.style.customCSS" "site/custom.css" + //"generatr.style.customCSS" "https://example.com/custom.css" "generatr.svglink.target" "_self" // full list of available "generatr.markdown.flexmark.extensions" diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt index 9d36dddc..91d67b39 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt @@ -2,7 +2,6 @@ package nl.avisi.structurizr.site.generatr.site.model import nl.avisi.structurizr.site.generatr.site.GeneratorContext import nl.avisi.structurizr.site.generatr.site.asUrlToFile -import java.io.File class CustomCSSViewModel(generatorContext: GeneratorContext, pageViewModel: PageViewModel) { val url = customCSSPath(generatorContext)?.let { "/$it".asUrlToFile(pageViewModel.url) } @@ -12,17 +11,11 @@ class CustomCSSViewModel(generatorContext: GeneratorContext, pageViewModel: Page private fun customCSSPath(generatorContext: GeneratorContext) = generatorContext.workspace.views.configuration.properties .getOrDefault( - "generatr.style.customCSSPath", + "generatr.style.customCSS", null ) - private fun extractType(): String? { - return url?.let { - val extension = File(it).extension.lowercase() - if (extension.isBlank() || !arrayOf("css").contains(extension)) - throw IllegalArgumentException("Custom CSS must be a valid *.css file") - - "image/$extension" - } + private fun extractType(): String { + return if (url?.lowercase()?.startsWith("http") == true) "URI" else "FILE" } } diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt index 096a2395..930da827 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt @@ -38,8 +38,12 @@ private fun HTML.headFragment(viewModel: PageViewModel) { autoReloadScript(viewModel) if (viewModel.customCSS.includecustomCSS){ - link(rel = "stylesheet", href = "./" + viewModel.customCSS.url) + when (viewModel.customCSS.type) { + "FILE" -> link(rel = "stylesheet", href = "./" + viewModel.customCSS.url) + "URI" -> link(rel = "stylesheet", href = viewModel.customCSS.url) + } } + } } From d0be0261cd76ae5c49cf887925902089b80c1e04 Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Wed, 11 Oct 2023 11:51:08 -0400 Subject: [PATCH 5/9] Change from customCSS to customStylesheet --- ...tomCSSViewModel.kt => CustomStylesheetViewModel.kt} | 10 +++++----- .../site/generatr/site/model/PageViewModel.kt | 2 +- .../avisi/structurizr/site/generatr/site/views/Page.kt | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) rename src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/{CustomCSSViewModel.kt => CustomStylesheetViewModel.kt} (55%) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModel.kt similarity index 55% rename from src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt rename to src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModel.kt index 91d67b39..1da0ed02 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomCSSViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModel.kt @@ -3,15 +3,15 @@ package nl.avisi.structurizr.site.generatr.site.model import nl.avisi.structurizr.site.generatr.site.GeneratorContext import nl.avisi.structurizr.site.generatr.site.asUrlToFile -class CustomCSSViewModel(generatorContext: GeneratorContext, pageViewModel: PageViewModel) { - val url = customCSSPath(generatorContext)?.let { "/$it".asUrlToFile(pageViewModel.url) } +class CustomStylesheetViewModel(generatorContext: GeneratorContext, pageViewModel: PageViewModel) { + val url = customStylesheetPath(generatorContext)?.let { "/$it".asUrlToFile(pageViewModel.url) } val type = extractType() - val includecustomCSS = url != null + val includeCustomStylesheet = url != null - private fun customCSSPath(generatorContext: GeneratorContext) = + private fun customStylesheetPath(generatorContext: GeneratorContext) = generatorContext.workspace.views.configuration.properties .getOrDefault( - "generatr.style.customCSS", + "generatr.style.customStylesheet", null ) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt index ee45d58a..dc575aad 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt @@ -12,7 +12,7 @@ abstract class PageViewModel(protected val generatorContext: GeneratorContext) { pageSubTitle } val favicon by lazy { FaviconViewModel(generatorContext, this) } - val customCSS by lazy { CustomCSSViewModel(generatorContext, this) } + val customStylesheet by lazy { CustomStylesheetViewModel(generatorContext, this) } val headerBar by lazy { HeaderBarViewModel(this, generatorContext) } val menu by lazy { MenuViewModel(generatorContext, this) } val includeAutoReloading = generatorContext.serving diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt index 930da827..1ed07042 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt @@ -37,10 +37,10 @@ private fun HTML.headFragment(viewModel: PageViewModel) { if (viewModel.includeAutoReloading) autoReloadScript(viewModel) - if (viewModel.customCSS.includecustomCSS){ - when (viewModel.customCSS.type) { - "FILE" -> link(rel = "stylesheet", href = "./" + viewModel.customCSS.url) - "URI" -> link(rel = "stylesheet", href = viewModel.customCSS.url) + if (viewModel.customStylesheet.includeCustomStylesheet){ + when (viewModel.customStylesheet.type) { + "FILE" -> link(rel = "stylesheet", href = "./" + viewModel.customStylesheet.url) + "URI" -> link(rel = "stylesheet", href = viewModel.customStylesheet.url) } } From eec9cf75e4a1e85b980be0eb7b164f10f1bde98e Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Wed, 11 Oct 2023 11:52:31 -0400 Subject: [PATCH 6/9] Change from customCSS to customStylesheet ( readme file ) --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 284262cd..82c171b6 100644 --- a/README.md +++ b/README.md @@ -254,16 +254,16 @@ and limitations for this exporter. The look and feel of the generated site can be customized with several additional view properties in the C4 architecture model: -| Property name | Description | Default | Example | -|-----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|------------------------------------------------------| -| `generatr.style.colors.primary` | Primary site color, used for header bar background and active menu background. | `#333333` | `#485fc7` | -| `generatr.style.colors.secondary` | Secondary site color, used for font color in header bar and for active menu. | `#cccccc` | `#ffffff` | -| `generatr.style.faviconPath` | Site logo location relative to the configured `assets` folder. When configured, the logo image will be place on the left side in the header bar. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/favicon.ico` | -| `generatr.style.logoPath` | Site favicon location relative to the configured `assets` folder. When configured, the favicon will be set for all generated pages. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/logo.png` | -| `generatr.style.customCSS` | URL to hosted custom CSS or path to custom css location relative to the configured `assets` folder. When configured this css file will be loaded for all pages. When using a path to a file the `--assets-dir` switch must be used when generating the site and the corresponding file is available in the `assets` folder. | | `site/custom.css` or 'https://uri.example/custom.css | -| `generatr.search.language` | Indexing/stemming language for the search index. See [Lunr language support](https://github.com/olivernn/lunr-languages) | `en` | `nl` | -| `generatr.markdown.flexmark.extensions` | Additional extensions to the markdown generator to add new markdown capabilities. [More Details](https://avisi-cloud.github.io/structurizr-site-generatr/main/extended-markdown-features/) | Tables | `Tables,Admonition` | -| `generatr.svglink.target` | Specifies the link target for element links in the exported svg | `_top` | `_self` | +| Property name | Description | Default | Example | +|-----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|------------------------------------------------------| +| `generatr.style.colors.primary` | Primary site color, used for header bar background and active menu background. | `#333333` | `#485fc7` | +| `generatr.style.colors.secondary` | Secondary site color, used for font color in header bar and for active menu. | `#cccccc` | `#ffffff` | +| `generatr.style.faviconPath` | Site logo location relative to the configured `assets` folder. When configured, the logo image will be place on the left side in the header bar. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/favicon.ico` | +| `generatr.style.logoPath` | Site favicon location relative to the configured `assets` folder. When configured, the favicon will be set for all generated pages. This requires the `--assets-dir` switch when generating the site and the corresponding file to be available in the `assets` folder. | | `site/logo.png` | +| `generatr.style.customStylesheet` | URL to hosted custom stylesheet or path to custom stylesheet file (location relative to the configured `assets` folder). When configured this css file will be loaded for all pages. When using a path to a file the `--assets-dir` switch must be used when generating the site and the corresponding file is available in the `assets` folder. | | `site/custom.css` or 'https://uri.example/custom.css | +| `generatr.search.language` | Indexing/stemming language for the search index. See [Lunr language support](https://github.com/olivernn/lunr-languages) | `en` | `nl` | +| `generatr.markdown.flexmark.extensions` | Additional extensions to the markdown generator to add new markdown capabilities. [More Details](https://avisi-cloud.github.io/structurizr-site-generatr/main/extended-markdown-features/) | Tables | `Tables,Admonition` | +| `generatr.svglink.target` | Specifies the link target for element links in the exported svg | `_top` | `_self` | See the included example for usage of some those properties in the From 8f7aa35437aed8bee018918c7c18f3ff6546c5e4 Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Wed, 11 Oct 2023 13:29:06 -0400 Subject: [PATCH 7/9] move view logic to modal and simplify code. --- .../site/model/CustomStylesheetViewModel.kt | 26 ++++++++++--------- .../site/generatr/site/model/PageViewModel.kt | 2 +- .../site/generatr/site/views/Page.kt | 9 ++----- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModel.kt index 1da0ed02..3cc9906a 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModel.kt @@ -1,21 +1,23 @@ package nl.avisi.structurizr.site.generatr.site.model import nl.avisi.structurizr.site.generatr.site.GeneratorContext -import nl.avisi.structurizr.site.generatr.site.asUrlToFile -class CustomStylesheetViewModel(generatorContext: GeneratorContext, pageViewModel: PageViewModel) { - val url = customStylesheetPath(generatorContext)?.let { "/$it".asUrlToFile(pageViewModel.url) } - val type = extractType() - val includeCustomStylesheet = url != null +class CustomStylesheetViewModel(generatorContext: GeneratorContext) { + val resourceURI = getResourceURI(generatorContext) + val includeCustomStylesheet = resourceURI != null - private fun customStylesheetPath(generatorContext: GeneratorContext) = - generatorContext.workspace.views.configuration.properties + private fun getResourceURI(generatorContext: GeneratorContext): String? { + val stylesheet = generatorContext.workspace.views.configuration.properties .getOrDefault( - "generatr.style.customStylesheet", - null - ) + "generatr.style.customStylesheet", + null + ) - private fun extractType(): String { - return if (url?.lowercase()?.startsWith("http") == true) "URI" else "FILE" + if (stylesheet != null) { + return if (stylesheet.lowercase().startsWith("http")) stylesheet else "./$stylesheet" + } + + return null } + } diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt index dc575aad..9ea1c83d 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PageViewModel.kt @@ -12,7 +12,7 @@ abstract class PageViewModel(protected val generatorContext: GeneratorContext) { pageSubTitle } val favicon by lazy { FaviconViewModel(generatorContext, this) } - val customStylesheet by lazy { CustomStylesheetViewModel(generatorContext, this) } + val customStylesheet by lazy { CustomStylesheetViewModel(generatorContext) } val headerBar by lazy { HeaderBarViewModel(this, generatorContext) } val menu by lazy { MenuViewModel(generatorContext, this) } val includeAutoReloading = generatorContext.serving diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt index 1ed07042..c78ac257 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt @@ -37,13 +37,8 @@ private fun HTML.headFragment(viewModel: PageViewModel) { if (viewModel.includeAutoReloading) autoReloadScript(viewModel) - if (viewModel.customStylesheet.includeCustomStylesheet){ - when (viewModel.customStylesheet.type) { - "FILE" -> link(rel = "stylesheet", href = "./" + viewModel.customStylesheet.url) - "URI" -> link(rel = "stylesheet", href = viewModel.customStylesheet.url) - } - } - + if (viewModel.customStylesheet.includeCustomStylesheet) + link(rel = "stylesheet", href = "./" + viewModel.customStylesheet.resourceURI) } } From 716d591dd7f166563b0a5c228ad411ef48ed8014 Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Wed, 11 Oct 2023 13:56:30 -0400 Subject: [PATCH 8/9] Added tests and fixed example property in the workspace.dsl --- docs/example/workspace.dsl | 4 +-- .../model/CustomStylesheetViewModelTest.kt | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModelTest.kt diff --git a/docs/example/workspace.dsl b/docs/example/workspace.dsl index ba59ae79..8082bb3a 100644 --- a/docs/example/workspace.dsl +++ b/docs/example/workspace.dsl @@ -161,8 +161,8 @@ workspace "Big Bank plc" "This is an example workspace to illustrate the key fea "generatr.style.colors.secondary" "#ffffff" "generatr.style.faviconPath" "site/favicon.ico" "generatr.style.logoPath" "site/logo.png" - "generatr.style.customCSS" "site/custom.css" - //"generatr.style.customCSS" "https://example.com/custom.css" + "generatr.style.customStylesheet" "site/custom.css" + //"generatr.style.customStylesheet" "https://example.com/custom.css" "generatr.svglink.target" "_self" // full list of available "generatr.markdown.flexmark.extensions" diff --git a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModelTest.kt b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModelTest.kt new file mode 100644 index 00000000..55578472 --- /dev/null +++ b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/CustomStylesheetViewModelTest.kt @@ -0,0 +1,29 @@ +package nl.avisi.structurizr.site.generatr.site.model + +import assertk.assertThat +import assertk.assertions.isEqualTo +import org.junit.jupiter.api.Test + +class CustomStylesheetViewModelTest : ViewModelTest() { + private val generatorContext = generatorContext() + + @Test + fun `Configuration Property Missing`() { + val customStylesheetViewModel = CustomStylesheetViewModel(generatorContext) + assertThat(customStylesheetViewModel.resourceURI).isEqualTo(null) + } + + @Test + fun `Configuration Property Set To URL`() { + generatorContext.workspace.views.configuration.addProperty("generatr.style.customStylesheet","http://example.uri/custom.css") + val customStylesheetViewModel = CustomStylesheetViewModel(generatorContext) + assertThat(customStylesheetViewModel.resourceURI).isEqualTo("http://example.uri/custom.css") + } + + @Test + fun `Configuration Property Set To Local File`() { + generatorContext.workspace.views.configuration.addProperty("generatr.style.customStylesheet","custom.css") + val customStylesheetViewModel = CustomStylesheetViewModel(generatorContext) + assertThat(customStylesheetViewModel.resourceURI).isEqualTo("./custom.css") + } +} From 66dea3d453ba8ae3029b96e6b505be1304b3407b Mon Sep 17 00:00:00 2001 From: Declan Lynch Date: Wed, 11 Oct 2023 13:59:35 -0400 Subject: [PATCH 9/9] removed obsolete './' --- .../nl/avisi/structurizr/site/generatr/site/views/Page.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt index c78ac257..a84f25fc 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Page.kt @@ -38,7 +38,7 @@ private fun HTML.headFragment(viewModel: PageViewModel) { autoReloadScript(viewModel) if (viewModel.customStylesheet.includeCustomStylesheet) - link(rel = "stylesheet", href = "./" + viewModel.customStylesheet.resourceURI) + link(rel = "stylesheet", href = viewModel.customStylesheet.resourceURI) } }