Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helium: new configuration options for including script or style resources. #511

Merged
merged 7 commits into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import laika.markdown.github.GitHubFlavor
import laika.parse.code.SyntaxHighlighting
import sbt.Keys.{ artifactPath, crossScalaVersions }
import sbt.Keys.crossScalaVersions
import org.scalajs.linker.interface.ESVersion
import com.typesafe.tools.mima.core.{ ProblemFilters, DirectMissingMethodProblem }
import Dependencies._

lazy val basicSettings = Seq(
version := "0.19.3",
version := "0.19.4-SNAPSHOT",
homepage := Some(new URL("https://typelevel.org/Laika/")),
organization := "org.planet42",
organizationHomepage := Some(new URL("http://typelevel.org")),
Expand Down Expand Up @@ -143,7 +144,12 @@ lazy val io = project.in(file("io"))
.settings(publishSettings)
.settings(
name := "laika-io",
libraryDependencies ++= Seq(catsEffect, fs2IO, munit, munitCE3)
libraryDependencies ++= Seq(catsEffect, fs2IO, munit, munitCE3),
mimaBinaryIssueFilters ++= Seq(
ProblemFilters.exclude[DirectMissingMethodProblem](
"laika.helium.builder.HeliumThemeBuilder#directives.this"
)
)
)

lazy val pdf = project.in(file("pdf"))
Expand Down
16 changes: 13 additions & 3 deletions core/shared/src/main/scala/laika/config/LaikaKeys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,23 @@ object LaikaKeys {
val apiPath: Key = root.child(Key("site", "downloadPath"))
val downloadPath: Key = root.child(Key("site", "apiPath"))
val metadata: Key = root.child(Key("site", "metadata"))
val css: Key = root.child(Key("site", "css"))
val js: Key = root.child(Key("site", "js"))

@deprecated("0.19.4", "use Helium configuration for CSS includes")
val css: Key = root.child(Key("site", "css"))

@deprecated("0.19.4", "use Helium configuration for JS includes")
val js: Key = root.child(Key("site", "js"))

}

object epub {

@deprecated("0.19.4", "use Helium configuration for CSS includes")
val css: Key = root.child(Key("epub", "css"))
val js: Key = root.child(Key("epub", "js"))

@deprecated("0.19.4", "use Helium configuration for JS includes")
val js: Key = root.child(Key("epub", "js"))

}

object preview {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import laika.rewrite.nav.TargetFormats
import laika.rewrite.{ DefaultTemplatePath, OutputContext }
import munit.FunSuite
import RewriteSetup._
import laika.config.{ ConfigBuilder, LaikaKeys }
import laika.config.{ ConfigBuilder, Key, LaikaKeys }
import laika.format.HTML

class HTMLHeadDirectiveSpec extends FunSuite {
Expand Down Expand Up @@ -111,8 +111,11 @@ class HTMLHeadDirectiveSpec extends FunSuite {
private val separator = TemplateString("\n ")
private def rawLink(url: String): TemplateElement = TemplateElement(RawLink.internal(url))

private val globalSearchPathsKey = LaikaKeys.site.css.child("globalSearchPaths")
private val localSearchPathsKey = LaikaKeys.site.css.child("searchPaths")
// TODO - 1.0 - remove deprecated values
val siteCSS: Key = LaikaKeys.root.child(Key("site", "css"))

private val globalSearchPathsKey = siteCSS.child("globalSearchPaths")
private val localSearchPathsKey = siteCSS.child("searchPaths")

private val linkCSSInput =
"""aaa
Expand Down
71 changes: 49 additions & 22 deletions docs/src/03-preparing-content/03-theme-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -940,43 +940,70 @@ Auto-Linking CSS & JS Files
If all the configuration options shown above don't give you enough flexibility, you can always include
additional CSS and JavaScript files to tweak the site's look & feel.

You can examine the CSS generated by Helium and override individual style declarations by placing them
anywhere in a CSS file inside one of your input directories.
You can examine the CSS generated by Helium and override individual style declarations.
They will always be included in a way that they have higher precedence than the theme's styles.

If you want to prevent Helium from scanning all input directories for CSS files,
you can alternatively specify one or more directories explicitly:
For internal resources you can specify search paths (entire directories) to be scanned and all
documents with a matching suffix (either `.css` or `.js`) will be included.
You can alternatively also specify a path pointing to an individual document.

```scala mdoc:silent
import laika.ast.Path.Root

Helium.defaults
.site.autoLinkCSS(Root / "my-css")
.site.autoLinkJS(Root / "my-js")
.site.internalCSS(Root / "my-css")
.site.internalJS(Root / "my-js")
```

If you use these methods with an empty parameter list, scanning for files will effectively be disabled
and only Helium's own CSS and JavaScript will be included.
Like everything in Laika, the paths are virtual and not file system paths, so they must point to somewhere
within the configured inputs.

The global scanning will skip files which have the suffix `.page.css` or `.page.js`.
With this naming scheme you can add files which are not meant to be included in every generated page.
If you want to explicitly add one of these files to an individual document,
you can do that with a HOCON configuration header in the corresponding markup document:
There are also corresponding methods for external resources (`.site.externalCSS` and `.site.externalJS`) and
for inline scripts and styles (`.site.inlineCSS` and `.site.inlineJS`).

```laika-md
{%
laika.site.css.searchPaths = ["/styles/custom.page.css"]
%}
Equivalent methods are also available for EPUB output via the `.epub` selector, except for the inclusion
of external resources.

The use of JavaScript in EPUB templates might need additional configuration, in particular with customized templates.
See [JavaScript for EPUB] for details.


### Conditional Inclusions

In cases where you want to link styles or scripts only for some documents, you can specify an optional
condition to be checked for each document.
It is a simple filter function of type `Document => Boolean` which enables inspection of both,
the document's AST and its configuration.
This can be useful when integrating larger libraries like renderers for diagrams or math,
where you might want to inspect the content of the page to verify it contains any nodes that need that functionality.

```scala mdoc:silent
import laika.ast.Path.Root

Helium.defaults
.site.externalJS(
url = "https://foo.com/lib.js",
condition = _.path.name == "special-doc.md"
)
```

You can also use paths of directories, in which case those will be scanned in the same way
as with the global search paths configured via the Helium API.

Like everything in Laika, the paths are virtual and not file system paths, so they must point to somewhere
within the configured inputs. @:todo(maybe better to include just one section at the top about virtual paths).
### Setting Common Tag Attributes

The use of JavaScript in EPUB templates might need additional configuration, in particular with customized templates.
See [JavaScript for EPUB] for details.
The API for inclusions also allows to set some of the most common attributes for script and link
tags. The following example sets the `defer` attribute as well as an `integrity` value.

```scala mdoc:silent
import laika.ast.Path.Root

Helium.defaults
.site.externalJS(
url = "https://foo.com/lib.js",
attributes = ScriptAttributes.defaults
.defer
.withIntegrity("xzy-abc")
)
```


Custom Templates
Expand Down
36 changes: 6 additions & 30 deletions docs/src/07-reference/01-standard-directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -486,41 +486,17 @@ as described in [Auto-Linking CSS & JS Files].

### `@:linkCSS`

Causes the automatic inclusion of `<link>` tags for CSS files found in the input tree.

```laika-html
@:linkCSS
```

It will simply link any CSS file found in the input tree, unless the suffix is `.page.css`.
Those files are excluded from global scanning so that they can be explicitly included for individual pages.

The search paths can be constrained via the Helium config API - see [Auto-Linking CSS & JS Files].

When not using Helium the paths can be controlled via the configuration key `laika.site.css.searchPaths`
and `laika.epub.css.searchPaths` which are both arrays of path strings.
Note that the paths, like everything in Laika, are within the virtual path of the input tree you configured.
See [Virtual Tree Abstraction] for details.
Deprecated since 0.19.4.
Use the Helium configuration API for specifying CSS documents to be linked in the HTML head section.

See [Auto-Linking CSS & JS Files] for details.

### `@:linkJS`

Causes the automatic inclusion of `<script>` tags for JavaScript files found in the input tree.

```laika-html
@:linkJS
```

It will simply link any JavaScript file found in the input tree, unless the suffix is `.page.js`.
Those files are excluded from global scanning so that they can be explicitly included for individual pages.

The search paths can be constrained via the Helium config API - see [Auto-Linking CSS & JS Files].

When not using Helium the paths can be controlled via the configuration key `laika.site.js.searchPaths`
and `laika.epub.js.searchPaths` which are both arrays of path strings.
Note that the paths, like everything in Laika, are within the virtual path of the input tree you configured.
See [Virtual Tree Abstraction] for details.
Deprecated since 0.19.4.
Use the Helium configuration API for specifying JavaScript documents to be linked in the HTML head section.

See [Auto-Linking CSS & JS Files] for details.

### `@:attribute`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
<meta name="description" content="${_}"/>
@:@
@:linkCSS
@:includeCSS
@:linkJS
@:includeJS
</head>

<body epub:type="bodymatter">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
<link rel="stylesheet" href="${_}">
@:@
@:linkCSS
@:includeCSS
@:linkJS
@:includeJS
@:heliumInitVersions
@:heliumInitPreview(container)
<script> /* for avoiding page load transitions */ </script>
Expand Down
15 changes: 14 additions & 1 deletion io/src/main/scala/laika/helium/builder/HeliumDirectives.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import cats.syntax.all._
import laika.ast.{ TemplateSpanSequence, TemplateString }
import laika.config.LaikaKeys
import laika.directive.Templates
import laika.helium.Helium
import laika.rewrite.Versions
import laika.rewrite.nav.PathTranslator

Expand Down Expand Up @@ -65,6 +66,18 @@ private[helium] object HeliumDirectives {
}
}

val all: Seq[Templates.Directive] = Seq(initVersions, initPreview)
def all(helium: Helium): Seq[Templates.Directive] =
Seq(
initVersions,
initPreview,
HeliumHeadDirectives.includeCSS(
helium.siteSettings.content.styleIncludes,
helium.epubSettings.styleIncludes
),
HeliumHeadDirectives.includeJS(
helium.siteSettings.content.scriptIncludes,
helium.epubSettings.scriptIncludes
)
)

}
Loading
Loading