diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66b25583..090515de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. The format
### Added
+- Improved title in entities (e.g. automated " - lernen mit Serlo" suffix) ([#678](https://github.com/serlo-org/athene2/pull/678))
- Add `package.json` so that we can use `yarn` as task runner
- Add yarn script `start` that executes `docker-compose up`
- Add yarn script `format:prettier` that executes prettier (formats Markdown, YAML, JSON, etc.)
@@ -16,6 +17,8 @@ All notable changes to this project will be documented in this file. The format
- Make list of unrevised revisions (e.g. https://de.serlo.org/mathe/entity/unrevised) faster ([#790](https://github.com/serlo-org/athene2/pull/790), [#780](https://github.com/serlo-org/athene2/pull/780))
- Show all unrevised revisions of an entity (and not only the newest one) ([#790](https://github.com/serlo-org/athene2/pull/790))
+- Show a subject-specific Open Graph meta image (e.g. for Facebook previews) ([#678](https://github.com/serlo-org/athene2/pull/678))
+- Expose a tenant-spefiic Open Search description file ([#678](https://github.com/serlo-org/athene2/pull/678))
## [Build 2] - 2017-10-30
diff --git a/src/config/autoload/local.php.dist b/src/config/autoload/local.php.dist
index d4077f8f..1787cc17 100644
--- a/src/config/autoload/local.php.dist
+++ b/src/config/autoload/local.php.dist
@@ -58,14 +58,14 @@ return [
'slogan' => 'Freie Bildung.',
'description' => 'Serlo ist eine kostenlose Plattform mit freien Lernmaterialien, die alle mitgestalten können.',
'logo' => 'V',
- 'head_title' => 'Serlo.org'
+ 'head_title' => 'lernen mit Serlo!'
],
'english' => [
'name' => '
Serlo
',
'slogan' => 'Open Education.',
'description' => 'Serlo is a free service with open educational resources, which anyone can contribute to.',
'logo' => 'V',
- 'head_title' => 'Serlo.org'
+ 'head_title' => 'lernen mit Serlo!'
]
]
],
diff --git a/src/config/autoload/serlo.config.local.php.dist b/src/config/autoload/serlo.config.local.php.dist
index 2cd6cc6e..7b12d00c 100644
--- a/src/config/autoload/serlo.config.local.php.dist
+++ b/src/config/autoload/serlo.config.local.php.dist
@@ -28,14 +28,14 @@ return [
'slogan' => 'Die freie Lernplattform',
'description' => 'Serlo ist eine kostenlose Plattform mit freien Lernmaterialien, die alle mitgestalten können.',
'logo' => 'V',
- 'head_title' => 'Serlo.org'
+ 'head_title' => 'lernen mit Serlo!'
],
'english' => [
'name' => 'Serlo
',
'slogan' => 'The Open Learning Platform',
'description' => 'Serlo is a free service with open educational resources, which anyone can contribute to.',
'logo' => 'V',
- 'head_title' => 'Serlo.org'
+ 'head_title' => 'lernen mit Serlo!'
]
]
],
diff --git a/src/module/Normalizer/src/Normalizer/Adapter/AbstractAdapter.php b/src/module/Normalizer/src/Normalizer/Adapter/AbstractAdapter.php
index 794beb76..d8b6cd3f 100644
--- a/src/module/Normalizer/src/Normalizer/Adapter/AbstractAdapter.php
+++ b/src/module/Normalizer/src/Normalizer/Adapter/AbstractAdapter.php
@@ -25,9 +25,11 @@
use Normalizer\Entity\Normalized;
use DateTime;
use Normalizer\Exception\RuntimeException;
+use Zend\I18n\Translator\TranslatorAwareTrait;
abstract class AbstractAdapter implements AdapterInterface
{
+ use TranslatorAwareTrait;
protected $object;
public function getObject()
@@ -60,11 +62,13 @@ public function normalize($object)
'routeParams' => $this->getRouteParams(),
'id' => $this->getId(),
'metadata' => [
- 'creationDate' => $this->getCreationDate() ? $this->getCreationDate() : new DateTime(),
- 'description' => $this->getDescription(),
- 'keywords' => $this->getKeywords(),
- 'lastModified' => $this->getLastModified() ? $this->getLastModified() : new DateTime(),
- 'robots' => $this->isTrashed() ? 'noindex' : 'all',
+ 'title' => $this->getHeadTitle(),
+ 'creationDate' => $this->getCreationDate() ? $this->getCreationDate() : new DateTime(),
+ 'description' => $this->getDescription(),
+ 'metaDescription' => $this->getMetaDescription(),
+ 'keywords' => $this->getKeywords(),
+ 'lastModified' => $this->getLastModified() ? $this->getLastModified() : new DateTime(),
+ 'robots' => $this->isTrashed() ? 'noindex' : 'all',
],
]);
@@ -89,6 +93,14 @@ protected function getDescription()
return $this->getContent();
}
+ /**
+ * @return string
+ */
+ protected function getMetaDescription()
+ {
+ return $this->getDescription();
+ }
+
/**
* @return DateTime
*/
@@ -136,4 +148,12 @@ abstract protected function getType();
* @return boolean
*/
abstract protected function isTrashed();
+
+ /**
+ * @return string
+ */
+ protected function getHeadTitle()
+ {
+ return $this->getTitle();
+ }
}
diff --git a/src/module/Normalizer/src/Normalizer/Adapter/AdapterInterface.php b/src/module/Normalizer/src/Normalizer/Adapter/AdapterInterface.php
index 403d3b7a..1892a4bd 100644
--- a/src/module/Normalizer/src/Normalizer/Adapter/AdapterInterface.php
+++ b/src/module/Normalizer/src/Normalizer/Adapter/AdapterInterface.php
@@ -23,8 +23,9 @@
namespace Normalizer\Adapter;
use Normalizer\Entity\NormalizedInterface;
+use Zend\I18n\Translator\TranslatorAwareInterface;
-interface AdapterInterface
+interface AdapterInterface extends TranslatorAwareInterface
{
/**
* @param object $object
diff --git a/src/module/Normalizer/src/Normalizer/Adapter/EntityAdapter.php b/src/module/Normalizer/src/Normalizer/Adapter/EntityAdapter.php
index a841e0dd..988fc40c 100644
--- a/src/module/Normalizer/src/Normalizer/Adapter/EntityAdapter.php
+++ b/src/module/Normalizer/src/Normalizer/Adapter/EntityAdapter.php
@@ -160,4 +160,45 @@ protected function isTrashed()
{
return $this->getObject()->isTrashed();
}
+
+ protected function getHeadTitle()
+ {
+ $maxStringLen = 65;
+
+ $type = $this->getType();
+ $typeName = $this->getTranslator()->translate($type);
+
+ $titleFallback = $this->getTitle();
+ $title = $this->getField('meta_title');
+ if ($title === $this->getId()) {
+ $title = $titleFallback;
+ }
+
+ if ($type === 'course-page') {
+ $parent = $this->getObject()->getParents('link')->first();
+ $parentAdapter = new EntityAdapter();
+ $parentAdapter->setTranslator($this->translator);
+ $normalizedParent = $parentAdapter->normalize($parent);
+ $parentTitle = $normalizedParent->getMetadata()->getTitle();
+ $title = $parentTitle . " | " .$title;
+ }
+
+ //add "(Kurs)" etc
+ if ($type !== 'article') {
+ if (strlen($title) < ($maxStringLen-strlen($typeName))) {
+ $title .= ' (' . $typeName . ')';
+ }
+ }
+
+ return $title;
+ }
+
+ protected function getMetaDescription()
+ {
+ $description = $this->getField('meta_description');
+ if ($description === $this->getId()) {
+ $description = $this->getDescription();
+ }
+ return $description;
+ }
}
diff --git a/src/module/Normalizer/src/Normalizer/Adapter/TaxonomyTermAdapter.php b/src/module/Normalizer/src/Normalizer/Adapter/TaxonomyTermAdapter.php
index ca34fa6e..778d5dbd 100644
--- a/src/module/Normalizer/src/Normalizer/Adapter/TaxonomyTermAdapter.php
+++ b/src/module/Normalizer/src/Normalizer/Adapter/TaxonomyTermAdapter.php
@@ -126,6 +126,25 @@ protected function getTitle()
return $this->getObject()->getName();
}
+ protected function getHeadTitle()
+ {
+ $maxStringLen = 65;
+
+ $type = $this->getType();
+ $typeName = $this->getTranslator()->translate($type);
+
+ $title = $this->getTitle();
+
+ //add "(Lehrplan)" etc
+ if ($type !== 'topic-folder') {
+ if (strlen($title) < ($maxStringLen-strlen($typeName))) {
+ $title .= ' (' . $typeName . ')';
+ }
+ }
+
+ return $title;
+ }
+
protected function getType()
{
return $this->getObject()->getTaxonomy()->getName();
diff --git a/src/module/Normalizer/src/Normalizer/Entity/Metadata.php b/src/module/Normalizer/src/Normalizer/Entity/Metadata.php
index 030725ba..9b7c1e18 100644
--- a/src/module/Normalizer/src/Normalizer/Entity/Metadata.php
+++ b/src/module/Normalizer/src/Normalizer/Entity/Metadata.php
@@ -45,6 +45,12 @@ class Metadata extends AbstractOptions implements MetadataInterface
* @var string
*/
protected $description;
+
+ /**
+ * @var string
+ */
+ protected $metaDescription;
+
/**
* @var DateTime
*/
@@ -143,6 +149,22 @@ public function setDescription($description)
$this->description = $description;
}
+ /**
+ * @return string
+ */
+ public function getMetaDescription()
+ {
+ return $this->metaDescription;
+ }
+
+ /**
+ * @param string $metaDescription
+ */
+ public function setMetaDescription($metaDescription)
+ {
+ $this->metaDescription = $metaDescription;
+ }
+
/**
* @return array|\string[]
*/
diff --git a/src/module/Normalizer/src/Normalizer/Entity/MetadataInterface.php b/src/module/Normalizer/src/Normalizer/Entity/MetadataInterface.php
index 8c506ec5..445f4055 100644
--- a/src/module/Normalizer/src/Normalizer/Entity/MetadataInterface.php
+++ b/src/module/Normalizer/src/Normalizer/Entity/MetadataInterface.php
@@ -42,6 +42,11 @@ public function getContext();
*/
public function getDescription();
+ /**
+ * @return string
+ */
+ public function getMetaDescription();
+
/**
* @return DateTime
*/
diff --git a/src/module/Normalizer/src/Normalizer/Factory/NormalizeHelperFactory.php b/src/module/Normalizer/src/Normalizer/Factory/NormalizeHelperFactory.php
index 1c09411d..7fc95a65 100644
--- a/src/module/Normalizer/src/Normalizer/Factory/NormalizeHelperFactory.php
+++ b/src/module/Normalizer/src/Normalizer/Factory/NormalizeHelperFactory.php
@@ -38,7 +38,10 @@ public function createService(ServiceLocatorInterface $serviceLocator)
{
$normalize = new Normalize();
$normalizer = $serviceLocator->getServiceLocator()->get('Normalizer\Normalizer');
+ $instanceManager = $serviceLocator->getServiceLocator()->get('Instance\Manager\InstanceManager');
+
$normalize->setNormalizer($normalizer);
+ $normalize->setInstanceManager($instanceManager);
return $normalize;
}
diff --git a/src/module/Normalizer/src/Normalizer/Factory/NormalizerFactory.php b/src/module/Normalizer/src/Normalizer/Factory/NormalizerFactory.php
index 1688b8b6..f1a82baa 100644
--- a/src/module/Normalizer/src/Normalizer/Factory/NormalizerFactory.php
+++ b/src/module/Normalizer/src/Normalizer/Factory/NormalizerFactory.php
@@ -37,6 +37,9 @@ class NormalizerFactory implements FactoryInterface
public function createService(ServiceLocatorInterface $serviceLocator)
{
$storage = $serviceLocator->get('Normalizer\Storage\Storage');
- return new Normalizer($storage);
+ $translator = $serviceLocator->get('MvcTranslator');
+ $normalizer = new Normalizer($storage);
+ $normalizer->setTranslator($translator);
+ return $normalizer;
}
}
diff --git a/src/module/Normalizer/src/Normalizer/Normalizer.php b/src/module/Normalizer/src/Normalizer/Normalizer.php
index 4cf6048f..5c2a3fcf 100644
--- a/src/module/Normalizer/src/Normalizer/Normalizer.php
+++ b/src/module/Normalizer/src/Normalizer/Normalizer.php
@@ -24,10 +24,12 @@
use Normalizer\Adapter\AdapterPluginManager;
use Zend\Cache\Storage\StorageInterface;
+use Zend\I18n\Translator\TranslatorAwareTrait;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
class Normalizer implements NormalizerInterface
{
+ use TranslatorAwareTrait;
/**
* @var Adapter\AdapterPluginManager
@@ -39,6 +41,7 @@ class Normalizer implements NormalizerInterface
*/
protected $storage;
+
/**
* @var array
*/
@@ -79,6 +82,7 @@ public function normalize($object)
if ($object instanceof $class) {
/* @var $adapterClass Adapter\AdapterInterface */
$adapter = $this->pluginManager->get($adapterClass);
+ $adapter->setTranslator($this->translator);
$normalized = $adapter->normalize($object);
// $this->storage->setItem($key, $normalized);
return $normalized;
diff --git a/src/module/Normalizer/src/Normalizer/View/Helper/Normalize.php b/src/module/Normalizer/src/Normalizer/View/Helper/Normalize.php
index 6cb8454b..7ad8edb5 100644
--- a/src/module/Normalizer/src/Normalizer/View/Helper/Normalize.php
+++ b/src/module/Normalizer/src/Normalizer/View/Helper/Normalize.php
@@ -23,14 +23,19 @@
namespace Normalizer\View\Helper;
use Common\Filter\PreviewFilter;
+use Instance\Manager\InstanceManagerAwareTrait;
+use Markdown\Service\OryRenderService;
use Markdown\View\Helper\MarkdownHelper;
+use Markdown\View\Helper\OryFormatHelper;
use Normalizer\NormalizerAwareTrait;
+use Ui\View\Helper\Brand;
use Zend\View\Helper\AbstractHelper;
use Zend\View\Helper\HeadMeta;
use Zend\View\Helper\HeadTitle;
class Normalize extends AbstractHelper
{
+ use InstanceManagerAwareTrait;
use NormalizerAwareTrait;
public function __invoke($object = null)
@@ -43,43 +48,151 @@ public function __invoke($object = null)
public function headMeta($object)
{
- /* @var $meta HeadMeta */
- $meta = $this->getView()->plugin('headMeta');
+ $meta = $this->getView()->plugin('headMeta');
$normalized = $this->normalize($object);
- $title = $normalized->getTitle();
- $type = $normalized->getType();
- $metadata = $normalized->getMetadata();
- $keywords = $metadata->getKeywords();
- $robots = $metadata->getRobots();
- $preview = $this->toPreview($object);
- $image = $this->getMetaImage($object);
- $meta->setProperty('og:title', $title);
- $meta->setProperty('og:image', $image);
+
+ $type = $normalized->getType();
+ $metadata = $normalized->getMetadata();
+
+ $keywords = $metadata->getKeywords();
+ $robots = $metadata->getRobots();
+
$meta->appendName('content_type', $type);
- $meta->appendName('description', $preview);
+ $meta->appendName('description', $this->getMetaDescription($object));
$meta->appendName('keywords', implode(', ', $keywords));
$meta->appendName('robots', $robots);
+ $this->appendOpenSearchMeta($object);
+ $this->appendOpenGraphMeta($object);
+ $this->appendFacebookMeta($object);
+
return $this;
}
- public function getMetaImage($object)
+ private function appendOpenSearchMeta($object)
+ {
+ $lang = $this->getSubdomain();
+
+ if ($lang === 'de' || $lang === 'en') {
+ $this->getView()->headLink(
+ [
+ 'rel' => 'search',
+ 'href' => '/opensearch.' . $lang . '.xml',
+ 'title' => 'Serlo (' . $lang . ')',
+ 'type' => 'application/opensearchdescription+xml',
+ ]
+ );
+ }
+ }
+
+ private function appendOpenGraphMeta($object)
+ {
+ $meta = $this->getMeta();
+
+ $meta->setProperty('og:title', $this->normalize($object)->getTitle());
+ $meta->setProperty('og:type', 'website');
+ $meta->setProperty('og:image', $this->getMetaImage($object));
+ $meta->setProperty('og:description', $this->getMetaDescription($object));
+ $meta->setProperty('og:site_name', $this->getView()->brand()->getBrand(true));
+ }
+
+ private function appendFacebookMeta($object)
+ {
+ $meta = $this->getMeta();
+
+ $meta->setProperty('fb:pages', '155020041197918');
+ $meta->setProperty('fb:profile_id', '155020041197918');
+ }
+
+
+ private function getMetaDescription($object)
{
- //TODO: Change path depending ob subject
- return 'https://de.serlo.org/assets/images/meta_serlo.jpg';
+ $metadata = $this->normalize($object)->getMetadata();
+ return $this->renderPreview($metadata->getMetaDescription());
}
- public function headTitle($object)
+ private function getMetaImage($object)
+ {
+ $fileName = 'serlo.jpg';
+
+ $subject = trim(strtolower(strip_tags(
+ $this->getView()->navigation('default_navigation')
+ ->menu()
+ ->setPartial('layout/navigation/partial/active-subject')
+ ->setOnlyActiveBranch(true)
+ ->setMinDepth(0)
+ ->setMaxDepth(0)
+ ->render()
+ )));
+
+ switch ($subject) {
+ case 'mathematik':
+ $fileName = 'de/mathematik.jpg';
+ break;
+
+ case 'angewandte nachhaltigkeit':
+ $fileName = 'de/angewandte-nachhaltigkeit.jpg';
+ break;
+
+ case 'biologie':
+ $fileName = 'de/biologie.jpg';
+ break;
+ }
+
+ return 'https://assets.serlo.org/meta/' . $fileName;
+ }
+
+ private function getSubdomain()
+ {
+ return $this->getInstanceManager()->getInstanceFromRequest()->getSubdomain();
+ }
+
+ /**
+ * @return HeadMeta
+ */
+ private function getMeta()
+ {
+ return $this->getView()->plugin('headMeta');
+ }
+
+ public function headTitle($object = null)
{
/* @var $headTitle HeadTitle */
$headTitle = $this->getView()->plugin('headTitle');
- $normalized = $this->normalize($object);
- $title = $normalized->getTitle();
+ if ($object == null) {
+ /** @var Brand $brand */
+ $brand = $this->getView()->brand();
+ $title = $brand->getBrand(true) . " – " . $brand->getSlogan();
+ } elseif (is_string($object)) {
+ $title = $this->appendBrand($object);
+ } else {
+ $normalized = $this->normalize($object);
+ $title = $this->appendBrand($normalized->getMetadata()->getTitle());
+ }
$headTitle($title);
-
return $this;
}
+ private function appendBrand($title)
+ {
+ /** @var Brand $brand */
+ $brand = $this->getView()->brand();
+ $maxStringLen = 65;
+
+ //add "– lernen mit Serlo"
+ $titlePostfix = ' – ' . $brand->getHeadTitle(true);
+ if (strlen($title) < ($maxStringLen-strlen($titlePostfix))) {
+ return $title . $titlePostfix;
+ }
+
+ $titlePostfixFallback = ' – ' . $brand->getBrand(true);
+ if (strlen($title) < ($maxStringLen-strlen($titlePostfixFallback))) {
+ return $title . $titlePostfixFallback;
+ }
+
+ return $title;
+ }
+
public function possible($object)
{
try {
@@ -114,12 +227,20 @@ public function toLastModified($object)
public function toPreview($object)
{
- /* @var $markdown MarkdownHelper */
- $markdown = $this->getView()->plugin('markdown');
$normalized = $this->normalize($object);
+ $content = $normalized->getMetadata()->getDescription();
+ return $this->renderPreview($content);
+ }
+
+ private function renderPreview($string)
+ {
+ $isOryEditorFormat = $this->getView()->plugin('isOryEditorFormat');
+ /** @var MarkdownHelper $renderer */
+ $renderer = $isOryEditorFormat($string)
+ ? $this->getView()->plugin('oryRenderer')
+ : $this->getView()->plugin('markdown');
+ $content = $renderer->toHtml($string);
$filter = new PreviewFilter(152);
- $content = $normalized->getContent();
- $content = $markdown->toHtml($content);
$preview = $filter->filter($content);
return $preview;
}
diff --git a/src/module/Ui/templates/entity/page/applet.twig b/src/module/Ui/templates/entity/page/applet.twig
index 924c9318..4c7b8900 100644
--- a/src/module/Ui/templates/entity/page/applet.twig
+++ b/src/module/Ui/templates/entity/page/applet.twig
@@ -19,26 +19,9 @@
# @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
# @link https://github.com/serlo-org/athene2 for the canonical source repository
#}
-{% set metaDescriptionFallback = normalize().toPreview(entity) %}
-{% set metaTitleFallback = normalize().toTitle(entity) ~ ' - ' ~ entity().findSubject(entity) ~ ' ' ~ (entity.getType().getName() | trans) %}
-{% set metaDescription = entity.getCurrentRevision().get('meta_description') %}
-{% set metaTitle = entity.getCurrentRevision().get('meta_title') %}
-
+{% do normalize().headTitle(entity) %}
{% do normalize().headMeta(entity) %}
-{% if metaDescription %}
- {% do headMeta().setName('description', metaDescription) %}
-{% else %}
- {% do headMeta().setName('description', metaDescriptionFallback) %}
-{% endif %}
-
-{% if metaTitle %}
- {% do headTitle(metaTitle) %}
- {% do headMeta().setProperty('og:title', metaTitle) %}
-{% else %}
- {% do headTitle(metaTitleFallback) %}
-{% endif %}
-
{% set title = entity.getCurrentRevision().get('title') %}
{% include 'entity/page/partials/placeholders' %}
diff --git a/src/module/Ui/templates/entity/page/article.twig b/src/module/Ui/templates/entity/page/article.twig
index 31c3ffa6..97c54a21 100644
--- a/src/module/Ui/templates/entity/page/article.twig
+++ b/src/module/Ui/templates/entity/page/article.twig
@@ -19,26 +19,9 @@
# @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
# @link https://github.com/serlo-org/athene2 for the canonical source repository
#}
-{% set metaDescriptionFallback = normalize().toPreview(entity) %}
-{% set metaTitleFallback = normalize().toTitle(entity) ~ ' - ' ~ entity().findSubject(entity) ~ ' ' ~ (entity.getType().getName() | trans) %}
-{% set metaDescription = entity.getCurrentRevision().get('meta_description') %}
-{% set metaTitle = entity.getCurrentRevision().get('meta_title') %}
-
+{% do normalize().headTitle(entity) %}
{% do normalize().headMeta(entity) %}
-{% if metaDescription %}
- {% do headMeta().setName('description', metaDescription) %}
-{% else %}
- {% do headMeta().setName('description', metaDescriptionFallback) %}
-{% endif %}
-
-{% if metaTitle %}
- {% do headTitle(metaTitle) %}
- {% do headMeta().setProperty('og:title', metaTitle) %}
-{% else %}
- {% do headTitle(metaTitleFallback) %}
-{% endif %}
-
{% set title = entity.getCurrentRevision().get('title') %}
{% include 'entity/page/partials/placeholders' %}
diff --git a/src/module/Ui/templates/entity/page/course-page.twig b/src/module/Ui/templates/entity/page/course-page.twig
index 6b54881d..05dbe6ae 100644
--- a/src/module/Ui/templates/entity/page/course-page.twig
+++ b/src/module/Ui/templates/entity/page/course-page.twig
@@ -19,11 +19,10 @@
# @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
# @link https://github.com/serlo-org/athene2 for the canonical source repository
#}
-{% set title = entity.getCurrentRevision().get('title') %}
{% set parent = entity.getParents('link').first() %}
{% set title = normalize().toTitle(entity) %}
-{% do headTitle(title ~ ' - ' ~ entity().findSubject(parent) ~ ' ' ~ (entity.getType().getName() | trans)) %}
{% do normalize().headMeta(entity) %}
+{% do normalize().headTitle(entity) %}
{% set controls = include('entity/view/partials/actions/course/course-controls-wrapper', {'entity': entity, 'parent': parent}) %}
{% do placeholder('controls').set(controls) %}
@@ -35,4 +34,4 @@
{% set courseNav = include('entity/page/course-navigation', {'entity': parent, 'activePage': entity}) %}
{% set temp = registry().add('rnav', courseNav) %}
-{% set temp = registry().add('rnav-is-course', true) %}
\ No newline at end of file
+{% set temp = registry().add('rnav-is-course', true) %}
diff --git a/src/module/Ui/templates/entity/page/course.twig b/src/module/Ui/templates/entity/page/course.twig
index f19bd332..ac383770 100644
--- a/src/module/Ui/templates/entity/page/course.twig
+++ b/src/module/Ui/templates/entity/page/course.twig
@@ -19,9 +19,7 @@
# @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
# @link https://github.com/serlo-org/athene2 for the canonical source repository
#}
-{% do normalize().headMeta(entity) %}
{% set title = normalize().toTitle(entity) %}
-{% do headTitle(title ~ ' - ' ~ entity().findSubject(entity) ~ ' ' ~ (entity.getType().getName() | trans)) %}
{% set title = entity.getCurrentRevision().get('title') %}
{% include 'entity/page/partials/placeholders' %}
diff --git a/src/module/Ui/templates/entity/page/video.twig b/src/module/Ui/templates/entity/page/video.twig
index 0cb2bc72..a9611d1d 100644
--- a/src/module/Ui/templates/entity/page/video.twig
+++ b/src/module/Ui/templates/entity/page/video.twig
@@ -21,7 +21,7 @@
#}
{% do normalize().headMeta(entity) %}
{% set title = normalize().toTitle(entity) %}
-{% do headTitle(title ~ ' - ' ~ entity().findSubject(entity) ~ ' ' ~ (entity.getType().getName() | trans)) %}
+{% do normalize().headTitle(entity) %}
{% include 'entity/page/partials/placeholders' %}
{% endif %}
@@ -129,7 +125,7 @@
{% endif %}
-
+
{% endfor %}
diff --git a/src/public/opensearch.de.xml b/src/public/opensearch.de.xml
new file mode 100644
index 00000000..89371fe7
--- /dev/null
+++ b/src/public/opensearch.de.xml
@@ -0,0 +1,32 @@
+
+
+ Serlo (de)
+
+Serlo.org – Die freie Lernplattform
+
+ UTF-8
+ https://de.serlo.org/favicon.ico
+
+ https://de.serlo.org/search
+
diff --git a/src/public/opensearch.en.xml b/src/public/opensearch.en.xml
new file mode 100644
index 00000000..3aa27918
--- /dev/null
+++ b/src/public/opensearch.en.xml
@@ -0,0 +1,32 @@
+
+
+ Serlo (en)
+
+Serlo.org – The Open Learning Platform
+
+ UTF-8
+ https://en.serlo.org/favicon.ico
+
+ https://en.serlo.org/search
+
diff --git a/src/public/opensearch.xml b/src/public/opensearch.xml
deleted file mode 100644
index 5b95feae..00000000
--- a/src/public/opensearch.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-Serlo (de)
-
-Serlo.org – Die freie Lernplattform
-
-UTF-8
-https://de.serlo.org/favicon.ico
-
-https://de.serlo.org/search
-