Added more composition info fields and supporting components.
This commit is contained in:
parent
d884d8587a
commit
16032b6587
@ -0,0 +1,17 @@
|
|||||||
|
package com.jessebrault.site.icon
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.view.SkipTemplate
|
||||||
|
import groowt.view.View
|
||||||
|
import groowt.view.component.web.lib.DelegatingWebViewComponent
|
||||||
|
|
||||||
|
@SkipTemplate
|
||||||
|
class ExternalIcon extends DelegatingWebViewComponent {
|
||||||
|
|
||||||
|
private static final String externalText = ExternalIcon.getResource('External.txt').text
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected View getDelegate() {
|
||||||
|
return { Writer w -> w << externalText }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.jessebrault.site.util
|
||||||
|
|
||||||
|
import groowt.view.component.web.BaseWebViewComponent
|
||||||
|
|
||||||
|
class MaybeExternalLink extends BaseWebViewComponent {
|
||||||
|
|
||||||
|
final String href
|
||||||
|
|
||||||
|
MaybeExternalLink(Map attr) {
|
||||||
|
href = attr.href
|
||||||
|
}
|
||||||
|
|
||||||
|
Object getLinkChildren() {
|
||||||
|
children
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean getIsExternal() {
|
||||||
|
href.startsWith('https://')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.jessebrault.site.util
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.view.SkipTemplate
|
||||||
|
import groowt.view.View
|
||||||
|
import groowt.view.component.runtime.DefaultComponentWriter
|
||||||
|
import groowt.view.component.web.lib.DelegatingWebViewComponent
|
||||||
|
|
||||||
|
@SkipTemplate
|
||||||
|
class WhenExternal extends DelegatingWebViewComponent {
|
||||||
|
|
||||||
|
private final String href
|
||||||
|
private final Closure render
|
||||||
|
|
||||||
|
WhenExternal(Map attr) {
|
||||||
|
href = attr.href
|
||||||
|
render = attr.render
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected View getDelegate() {
|
||||||
|
return { Writer w ->
|
||||||
|
if (href.startsWith('https://')) {
|
||||||
|
def cw = new DefaultComponentWriter(w, context.renderContext, context)
|
||||||
|
cw << render.call()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
<!--! Font Awesome Free 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/></svg>
|
After Width: | Height: | Size: 705 B |
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
package com.jessebrault.site.util
|
||||||
|
|
||||||
|
import com.jessebrault.site.icon.ExternalIcon
|
||||||
|
---
|
||||||
|
<a href={href} target={isExternal ? '_blank' : '_self'}>
|
||||||
|
<span>
|
||||||
|
<% children -> children.addAll(linkChildren) %>
|
||||||
|
<WhenExternal href={href} render={<ExternalIcon />} />
|
||||||
|
</span>
|
||||||
|
</a>
|
@ -2,6 +2,7 @@
|
|||||||
package com.jessebrault.site.composition
|
package com.jessebrault.site.composition
|
||||||
|
|
||||||
import com.jessebrault.site.StandardPage
|
import com.jessebrault.site.StandardPage
|
||||||
|
import com.jessebrault.site.util.MaybeExternalLink
|
||||||
---
|
---
|
||||||
<StandardPage title={title}>
|
<StandardPage title={title}>
|
||||||
<div class="article-container">
|
<div class="article-container">
|
||||||
@ -17,11 +18,37 @@ import com.jessebrault.site.StandardPage
|
|||||||
</div>
|
</div>
|
||||||
<WhenNotNull item={composition.version} render={<p class="version">$it</p>} />
|
<WhenNotNull item={composition.version} render={<p class="version">$it</p>} />
|
||||||
<p class="instrumentation">$composition.instrumentation</p>
|
<p class="instrumentation">$composition.instrumentation</p>
|
||||||
|
<WhenNotNull item={composition.premiere} render={<p class="premiere">Premiere: $it</p>} />
|
||||||
|
<WhenNotEmpty items={composition.recordings.entrySet()}>
|
||||||
|
<div class="recordings">
|
||||||
|
<span>Recordings:</span>
|
||||||
|
<ul>
|
||||||
|
<Each
|
||||||
|
items={composition.recordings.entrySet()}
|
||||||
|
transform={<li><MaybeExternalLink href={it.value}>$it.key</MaybeExternalLink></li>}
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</WhenNotEmpty>
|
||||||
|
<WhenNotEmpty items={composition.externalLinks.entrySet()}>
|
||||||
|
<div class="external-links">
|
||||||
|
<span>External links:</span>
|
||||||
|
<ul>
|
||||||
|
<Each
|
||||||
|
items={composition.externalLinks.entrySet()}
|
||||||
|
transform={<li><MaybeExternalLink href={it.value}>$it.key</MaybeExternalLink></li>}
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</WhenNotEmpty>
|
||||||
<WhenNotEmpty items={alternateVersions}>
|
<WhenNotEmpty items={alternateVersions}>
|
||||||
<div class="alternate-versions">
|
<div class="alternate-versions">
|
||||||
<p>Alternate versions:</p>
|
<span>Alternate versions:</span>
|
||||||
<ul>
|
<ul>
|
||||||
<Each items={alternateVersions} transform={<li><a href={it.path}>${it.versionName}</a></li>} />
|
<Each
|
||||||
|
items={alternateVersions}
|
||||||
|
transform={<li><a href={it.path}>${it.versionName}</a></li>}
|
||||||
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</WhenNotEmpty>
|
</WhenNotEmpty>
|
||||||
|
@ -16,6 +16,10 @@ class Composition {
|
|||||||
@Nullable String subTitle
|
@Nullable String subTitle
|
||||||
@Nullable String version
|
@Nullable String version
|
||||||
String instrumentation
|
String instrumentation
|
||||||
|
@Nullable String premiere
|
||||||
|
@Nullable String pdfUrl
|
||||||
|
Map<String, String> recordings
|
||||||
|
Map<String, String> externalLinks
|
||||||
@Nullable String shortInfo
|
@Nullable String shortInfo
|
||||||
LocalDate date
|
LocalDate date
|
||||||
Set<String> categories
|
Set<String> categories
|
||||||
|
@ -20,6 +20,10 @@ class CompositionContainer {
|
|||||||
subTitle: text.frontMatter.subTitle,
|
subTitle: text.frontMatter.subTitle,
|
||||||
version: text.frontMatter.version,
|
version: text.frontMatter.version,
|
||||||
instrumentation: text.frontMatter.instrumentation,
|
instrumentation: text.frontMatter.instrumentation,
|
||||||
|
premiere: text.frontMatter.premiere,
|
||||||
|
pdfUrl: text.frontMatter.pdfUrl,
|
||||||
|
recordings: text.frontMatter.recordings ?: [:],
|
||||||
|
externalLinks: text.frontMatter.externalLinks ?: [:],
|
||||||
shortInfo: text.frontMatter.shortInfo,
|
shortInfo: text.frontMatter.shortInfo,
|
||||||
date: LocalDate.parse(text.frontMatter.date),
|
date: LocalDate.parse(text.frontMatter.date),
|
||||||
categories: text.frontMatter.categories as Set<String>
|
categories: text.frontMatter.categories as Set<String>
|
||||||
|
@ -306,16 +306,28 @@ article.compositions {
|
|||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.composition-info .alternate-versions {
|
.composition-info :is(.recordings, .external-links, .alternate-versions) {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
row-gap: 10px;
|
row-gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.composition-info .alternate-versions ul {
|
.composition-info :is(.recordings, .external-links, .alternate-versions) ul {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.composition-info :is(.recordings, .external-links, .alternate-versions) a span {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.composition-info :is(.recordings, .external-links, .alternate-versions) span svg {
|
||||||
|
pointer-events: none;
|
||||||
|
height: 0.8em;
|
||||||
|
fill: var(--petrol);
|
||||||
|
}
|
||||||
|
|
||||||
.composition-text p:first-child {
|
.composition-text p:first-child {
|
||||||
margin-block-start: 2em;
|
margin-block-start: 2em;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,13 @@
|
|||||||
title: Arcadia
|
title: Arcadia
|
||||||
slug: arcadia
|
slug: arcadia
|
||||||
instrumentation: For violin and piano.
|
instrumentation: For violin and piano.
|
||||||
|
premiere: November 2, 2020. (Online)
|
||||||
|
recordings:
|
||||||
|
Premiere: https://www.youtube.com/watch?v=pUx57krZ41E
|
||||||
|
Audio: /compositions/arcadia/arcadia.mp3
|
||||||
|
externalLinks:
|
||||||
|
'Musaics of the Bay': https://www.musaics.org/stayathomesymposium/20-arcadia
|
||||||
|
Discussion: https://www.youtube.com/watch?v=y52TU2u1BnU
|
||||||
shortInfo: 'Commissioned by <em>Musaics of the Bay</em>.'
|
shortInfo: 'Commissioned by <em>Musaics of the Bay</em>.'
|
||||||
date: 2020-10-01
|
date: 2020-10-01
|
||||||
categories:
|
categories:
|
||||||
|
Loading…
Reference in New Issue
Block a user