diff --git a/pages/article/ArticleHandler.php b/pages/article/ArticleHandler.php index 51d8a864488..189cad821c8 100644 --- a/pages/article/ArticleHandler.php +++ b/pages/article/ArticleHandler.php @@ -354,6 +354,8 @@ public function view($args, $request) $templateMgr->assign('purchaseArticleEnabled', true); } + $templateMgr->assign('pubLocData', $this->getPublicationLocaleData($publication, $context->getPrimaryLocale(), $article->getData('locale'), $templateMgr->getTemplateVars('activeTheme')->getOption('showMetadata') ?: [])); + if (!Hook::call('ArticleHandler::view', [&$request, &$issue, &$article, $publication])) { $templateMgr->display('frontend/pages/article.tpl'); event(new UsageEvent(Application::ASSOC_TYPE_SUBMISSION, $context, $article, null, null, $this->issue)); @@ -610,4 +612,43 @@ public function userCanViewGalley($request, $articleId, $galleyId = null) } return true; } + + /** + * For article details, format display data. + */ + protected function getPublicationLocaleData(\APP\publication\Publication $publication, string $contextPrimaryLocale, string $submissionLocale, array $metadataOpts): array + { + $titles = $publication->getTitles('html'); + $subtitles = $publication->getSubtitles('html'); + $primaryLocale = isset($titles[$contextPrimaryLocale]) ? $contextPrimaryLocale : $submissionLocale; + $uiLocale = $contextPrimaryLocale; + $getOtherTitles = fn ($tt) => in_array('titles', $metadataOpts) ? array_filter($tt, fn ($locale) => $locale !== $primaryLocale, ARRAY_FILTER_USE_KEY) : []; + $getMdata = fn ($opt) => empty(count($mdata = array_filter($publication->getData($opt) ?? []))) || in_array($opt, $metadataOpts) + ? $mdata + : (isset($mdata[$primaryLocale]) ? [$primaryLocale => $mdata[$primaryLocale]] : [$fk = array_key_first($mdata) => $mdata[$fk]]); + + $pubLocData = [ + 'title' => ['text' => $getOtherTitles($titles)], + 'subtitle' => ['text' => $getOtherTitles($subtitles)], + 'keywords' => ['text' => $getMdata('keywords')], + 'abstract' => ['text' => $getMdata('abstract')], + ]; + + foreach($pubLocData as $opt => &$item) { + uksort($item['text'], fn ($a, $b) => $a === $primaryLocale ? -1 : ($b === $primaryLocale ? 1 : ($a < $b ? -1 : 1))); + + $locales = array_keys($item['text']); + $hasSameHeaderLocale = in_array($opt, $metadataOpts); + $item['heading'] = []; + foreach($locales as $locale) { + $item['heading'][$locale] = $hasSameHeaderLocale ? $locale : $uiLocale; + } + } + + $pubLocData['primaryTitle'] = $titles[$primaryLocale]; + $pubLocData['primarySubtitle'] = $subtitles[$primaryLocale] ?? null; + $pubLocData['primaryLocale'] = $primaryLocale; + + return $pubLocData; + } } diff --git a/plugins/themes/default/DefaultThemePlugin.php b/plugins/themes/default/DefaultThemePlugin.php index 8e5719926ac..397b8992237 100644 --- a/plugins/themes/default/DefaultThemePlugin.php +++ b/plugins/themes/default/DefaultThemePlugin.php @@ -124,6 +124,26 @@ public function init() 'default' => 'none', ]); + $this->addOption('showMetadata', 'FieldOptions', [ + 'label' => __('plugins.themes.default.option.metadata.label'), + 'description' => __('plugins.themes.default.option.metadata.description'), + 'options' => [ + [ + 'value' => 'titles', + 'label' => __('plugins.themes.default.option.metadata.titleAndSubtitle'), + ], + [ + 'value' => 'keywords', + 'label' => __('article.subject'), + ], + [ + 'value' => 'abstract', + 'label' => __('article.abstract'), + ], + ], + 'default' => [], + ]); + // Load primary stylesheet $this->addStyle('stylesheet', 'styles/index.less'); diff --git a/plugins/themes/default/locale/en/locale.po b/plugins/themes/default/locale/en/locale.po index c783e630ff5..28ca7442646 100644 --- a/plugins/themes/default/locale/en/locale.po +++ b/plugins/themes/default/locale/en/locale.po @@ -98,3 +98,18 @@ msgstr "Next slide" msgid "plugins.themes.default.prevSlide" msgstr "Previous slide" + +msgid "plugins.themes.default.option.metadata.label" +msgstr "Show article metadata on the article landing page" + +msgid "plugins.themes.default.option.metadata.description" +msgstr "Select the article metadata to show in other languages." + +msgid "plugins.themes.default.option.metadata.titleAndSubtitle" +msgstr "Title and subtitle" + +msgid "plugins.themes.default.aria.multilingualSubmissionTitles" +msgstr "Article titles in other languages" + +msgid "plugins.themes.default.titleSubtitleSeparator" +msgstr " — " diff --git a/plugins/themes/default/styles/objects/article_details.less b/plugins/themes/default/styles/objects/article_details.less index d8c032b0a0d..fa649faee48 100644 --- a/plugins/themes/default/styles/objects/article_details.less +++ b/plugins/themes/default/styles/objects/article_details.less @@ -10,15 +10,30 @@ */ .obj_article_details { - > .page_title { + .page_titles { margin: 0; + + > .subtitle { + font-size: @font-base; + line-height: @line-lead; + font-weight: @normal; + } } - > .subtitle { - margin: 0; - font-size: @font-base; - line-height: @line-lead; - font-weight: @normal; + .page_locale_titles { + margin: @quadruple 0 @triple 0; + + > h2 { + font-size: @font-base; + line-height: @line-lead; + font-weight: @normal; + margin-top: 0; + margin-bottom: @base; + + &:last-of-type { + margin-bottom: 0; + } + } } .row { @@ -66,6 +81,22 @@ display: inline; font-size: @font-base; } + + &.keywords > section { + margin-bottom: @base; + + &:last-of-type { + margin-bottom: 0; + } + } + + &.abstracts .abstract { + margin-bottom: @quadruple; + + &:last-of-type { + margin-bottom: 0; + } + } } .sub_item { diff --git a/templates/frontend/objects/article_details.tpl b/templates/frontend/objects/article_details.tpl index e6159ce8f67..7192ded8d21 100755 --- a/templates/frontend/objects/article_details.tpl +++ b/templates/frontend/objects/article_details.tpl @@ -64,6 +64,7 @@ * @uses $licenseUrl string URL to license. Only assigned if license should be * included with published submissions. * @uses $ccLicenseBadge string An image and text with details about the license + * @uses $pubLocData array Array of formatted publication locale metadata: titles, abstracts, keywords, *} {if !$heading} {assign var="heading" value="h3"} @@ -87,14 +88,26 @@ {/if} -

- {$publication->getLocalizedTitle(null, 'html')|strip_unsafe_html} -

+
+

+ {$pubLocData.primaryTitle|strip_unsafe_html} +

+ {if $pubLocData.primarySubtitle} +

+ {$pubLocData.primarySubtitle|strip_unsafe_html} +

+ {/if} +
- {if $publication->getLocalizedData('subtitle')} -

- {$publication->getLocalizedSubTitle(null, 'html')|strip_unsafe_html} -

+ {if !empty(count($pubLocData.title.text))} +
+ {foreach from=$pubLocData.title.text key=locale item=title} +

+ {$title|strip_unsafe_html} + {if isset($pubLocData.subtitle.text[$locale])}{translate key="plugins.themes.default.titleSubtitleSeparator"}{$pubLocData.subtitle.text[$locale]|strip_unsafe_html}{/if} +

+ {/foreach} +
{/if}
@@ -158,25 +171,35 @@ {* Keywords *} - {if !empty($publication->getLocalizedData('keywords'))} -
-

- {capture assign=translatedKeywords}{translate key="article.subject"}{/capture} - {translate key="semicolon" label=$translatedKeywords} -

- - {foreach name="keywords" from=$publication->getLocalizedData('keywords') item="keyword"} - {$keyword|escape}{if !$smarty.foreach.keywords.last}{translate key="common.commaListSeparator"}{/if} - {/foreach} - -
+ {if !empty(count($pubLocData.keywords.text))} +
+ {foreach from=$pubLocData.keywords.text key=locale item=keywords} +
+

+ {capture assign=translatedKeywords}{translate key="article.subject" locale=$pubLocData.keywords.heading[$locale]}{/capture} + {translate key="semicolon" label=$translatedKeywords locale=$pubLocData.keywords.heading[$locale]} +

+ + {foreach name="keywords" from=$keywords item="keyword"} + {$keyword|escape}{if !$smarty.foreach.keywords.last}{translate key="common.commaListSeparator" locale=$pubLocData.keywords.heading[$locale]}{/if} + {/foreach} + +
+ {/foreach} +
{/if} {* Abstract *} - {if $publication->getLocalizedData('abstract')} -
-

{translate key="article.abstract"}

- {$publication->getLocalizedData('abstract')|strip_unsafe_html} + {if !empty(count($pubLocData.abstract.text))} +
+ {foreach from=$pubLocData.abstract.text key=locale item=abstract} +
+

+ {translate key="article.abstract" locale=$pubLocData.abstract.heading[$locale]} +

+ {$abstract|strip_unsafe_html} +
+ {/foreach}
{/if}