Skip to content
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
8 changes: 6 additions & 2 deletions cms/contents/page/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# this is the page base configuration
content:
revision: 2
revision: 3
entity_class: 'Softspring\CmsBundle\Entity\Page'
default_layout: 'default'
version_seo:
Expand All @@ -10,6 +10,10 @@ content:
type: translation
metaKeywords:
type: translation
canonicalContent:
type: translatable
type_options:
type: content
indexing:
noIndex:
type: checkbox
Expand Down Expand Up @@ -41,7 +45,7 @@ content:
admin_page.form.indexing.sitemapChangefreq.values.weekly: weekly
admin_page.form.indexing.sitemapChangefreq.values.monthly: monthly
admin_page.form.indexing.sitemapChangefreq.values.yearly: yearly
admin_page.form.indexing.sitemapChangefreq.values.never: never
admin_page.form.indexing.sitemapChangefreq.values.never: never
sitemapPriority:
type: number
type_options:
Expand Down
9 changes: 9 additions & 0 deletions cms/contents/page/seo-migrate.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,14 @@
}
}

// canonicalContent became translatable in revision 3.
// Migrate previous scalar/entity value to a translatable structure.
if ($originVersion < 3 && $targetVersion >= 3 && isset($seo['canonicalContent']) && !is_array($seo['canonicalContent'])) {
$seo['canonicalContent'] = \Softspring\TranslatableBundle\Model\Translation::createFromArray([
'en' => $seo['canonicalContent'],
'_default' => 'en',
]);
}

return $seo;
};
3 changes: 3 additions & 0 deletions cms/contents/page/translations/sfs_cms_contents.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ admin_page:
metaTitle.label: "Title (browser title and meta tags)"
metaDescription.label: "Description (meta tag)"
metaKeywords.label: "Keywords (meta tag)"
canonicalContent.label: "Canonical URL source"
canonicalContent.placeholder: "Use this page as canonical (default)"
canonicalContent.help: "If selected, this page will output a canonical URL pointing to the selected page."

version_form:
note.label: "Note"
Expand Down
3 changes: 3 additions & 0 deletions cms/contents/page/translations/sfs_cms_contents.es.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ admin_page:
metaTitle.label: "Título (título del navegador y etiquetas meta)"
metaDescription.label: "Descripción (etiqueta meta)"
metaKeywords.label: "Palabras clave (etiqueta meta)"
canonicalContent.label: "Fuente de URL canónica"
canonicalContent.placeholder: "Usar esta página como canónica (por defecto)"
canonicalContent.help: "Si se selecciona, esta página generará la URL canónica apuntando a la página seleccionada."

version_form:
note.label: "Nota"
Expand Down
17 changes: 13 additions & 4 deletions cms/layouts/default/render.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@
<meta property="og:title" content="{{ version.seo.metaTitle|default|sfs_cms_trans }}">
<meta property="og:description" content="{{ version.seo.metaDescription|default|sfs_cms_trans }}">
<meta property="og:locale" content="{{ app.request.locale }}">
{% for locale, url in sfs_cms_alternate_urls() %}
<link rel="alternate" hreflang="{{ locale }}" href="{{ url }}" />
{% endfor %}
{% set canonical_content = version.seo.canonicalContent|default(null) %}
{% if canonical_content is iterable %}
{% set canonical_content = canonical_content[app.request.locale]|default(null) %}
{% endif %}
{% if canonical_content and canonical_content != version.content %}
<link rel="canonical" href="{{ sfs_cms_url_for_content(canonical_content, app.request.locale) }}" />
{% else %}
<link rel="canonical" href="{{ sfs_cms_url_for_content(version.content, app.request.locale) }}" />
{% for locale, url in sfs_cms_alternate_urls() %}
<link rel="alternate" hreflang="{{ locale }}" href="{{ url }}" />
{% endfor %}
{% endif %}
{% endblock seo %}

{% block body %}
Expand Down Expand Up @@ -93,4 +102,4 @@
});
</script>
{% endif %}
{% endblock javascripts %}
{% endblock javascripts %}
16 changes: 9 additions & 7 deletions src/EntityTransformer/ContentVersionTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,16 @@ public function untransform(object $entity, ObjectManager $em): void
}

if ($contentVersion->getSeo()) {
$seo = $contentVersion->getSeo();

$config = $this->cmsConfig->getContent($contentVersion->getContent());
$seo = DataMigrator::migrate($config['seo_revision_migration_scripts'], $seo, $config['revision'], $this->cmsConfig);
foreach ($seo as $field => $value) {
$seo[$field] = $this->untransformEntityValues($value, $em);
}
$contentVersion->setSeo($seo);

$contentVersion->_setSeoCallback(function (array $seo) use ($em, $config): array {
$seo = DataMigrator::migrate($config['seo_revision_migration_scripts'], $seo, $config['revision'], $this->cmsConfig);
foreach ($seo as $field => $value) {
$seo[$field] = $this->untransformEntityValues($value, $em);
}

return $seo;
});
}
}

Expand Down
38 changes: 38 additions & 0 deletions src/Form/Type/ContentType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Softspring\CmsBundle\Form\Type;

use Doctrine\ORM\EntityManagerInterface;
use Softspring\CmsBundle\Manager\ContentManager;
use Softspring\CmsBundle\Model\ContentInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;

class ContentType extends AbstractType
{
public function __construct(protected EntityManagerInterface $sfsContentEm, protected ContentManager $contentManager, protected TranslatorInterface $translator)
{
}

public function getParent(): ?string
{
return EntityType::class;
}

public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'class' => ContentInterface::class,
'em' => $this->sfsContentEm,
'required' => false,
'choice_label' => function (ContentInterface $content) {
return $content->getName();
},
'group_by' => function (ContentInterface $content) {
return $this->translator->trans("{$this->contentManager->getType($content)}.name", [], 'sfs_cms_contents');
},
]);
}
}
39 changes: 24 additions & 15 deletions src/Helper/RoutingHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,34 +91,43 @@ public function generatePath($route, ?string $locale = null, $site = null): stri
return $this->generateUrl($route, $locale, $site, UrlGeneratorInterface::ABSOLUTE_PATH);
}

public function generateUrlForContent($content, string $locale, $site = null): string
{
foreach ($content->getRoutes() as $route) {
if ($route->getPathForLocale($locale)) {
return $this->generateUrl($route, $locale, $site);
}
}

return '#';
}

public function generateUrl($route, ?string $locale = null, $site = null, int $referenceType = UrlGeneratorInterface::ABSOLUTE_URL): string
{
if (is_null($route)) {
return '#';
}

if (is_array($route)) {
if (is_null($route['route_name'])) {
return '#';
}
$params = [];
$params['_locale'] = $locale ?: ($this->requestStack->getCurrentRequest()?->getLocale() ?: 'en');

$params = $route['route_params'] ?? [];
if ($site) {
$params['_site'] = $site;
}

$params['_locale'] = $locale ?: ($this->requestStack->getCurrentRequest()?->getLocale() ?: 'en');
$routeName = $route;

if ($site) {
$params['_site'] = $site;
if (is_array($route)) {
if (is_null($route['route_name'])) {
return '#';
}

return $this->router->generate($route['route_name'], $params, $referenceType);
$params = array_merge($params, $route['route_params'] ?? []);
$routeName = $route['route_name'];
} elseif ($route instanceof RouteInterface) {
return $this->router->generate($route->getId(), [], $referenceType);
$routeName = $route->getId();
}

$params = [
'_locale' => $locale ?: ($this->requestStack->getCurrentRequest()?->getLocale() ?: 'en'),
];

return $this->router->generate($route, $params, $referenceType);
return $this->router->generate($routeName, $params, $referenceType);
}
}
20 changes: 20 additions & 0 deletions src/Model/ContentVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ abstract class ContentVersion implements ContentVersionInterface

protected ?array $seo = null;

protected mixed $_getSeoCallback = null;

protected mixed $_rawSeo = null;

public function getContent(): ?ContentInterface
{
return $this->content;
Expand Down Expand Up @@ -49,13 +53,29 @@ public function setLayout(?string $layout): void
$this->layout = $layout;
}

public function _setSeoCallback(callable $getSeoCallback): void
{
$this->_getSeoCallback = $getSeoCallback;
}

public function getSeo(): ?array
{
if ($this->_getSeoCallback) {
$this->_rawSeo = $this->seo;
$this->seo = call_user_func($this->_getSeoCallback, $this->seo);
$this->_getSeoCallback = null;
}

return $this->seo;
}

public function setSeo(?array $seo): void
{
$this->seo = $seo;
}

public function getRawSeo(): ?array
{
return $this->_rawSeo ?? $this->seo;
}
}
2 changes: 1 addition & 1 deletion src/Routing/UrlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function getUrl($routeOrName, ?string $locale = null, $site = null, array
}

if ($route->getContent() && !$route->getContent()->getPublishedVersion()) {
return '#';
return '#not-published';
}

$queryString = !empty($routeParams) ? '?'.http_build_query($routeParams) : '';
Expand Down
1 change: 1 addition & 0 deletions src/Twig/Extension/RouterExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public function getFunctions(): array
new TwigFunction('sfs_cms_link_attr', [$this, 'generateLinkAttributes'], ['is_safe' => ['html']]),
new TwigFunction('sfs_cms_resolve_request_from_url', [$this->routingHelper, 'resolveRequestFromUrl']),
new TwigFunction('sfs_cms_url', [$this->routingHelper, 'generateUrl']),
new TwigFunction('sfs_cms_url_for_content', [$this->routingHelper, 'generateUrlForContent']),
new TwigFunction('sfs_cms_path', [$this->routingHelper, 'generatePath']),
new TwigFunction('sfs_cms_route_path_url', [$this->urlGenerator, 'getUrlFixed']), // TODO REVIEW THIS, check if it works with symfony native routes
new TwigFunction('sfs_cms_route_path_path', [$this->urlGenerator, 'getPathFixed']), // TODO REVIEW THIS, check if it works with symfony native routes
Expand Down
1 change: 1 addition & 0 deletions src/Twig/Extension/TranslateExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,5 @@ public function getLocalePaths(?string $defaultRoute = null): array

return $localePaths;
}

}
2 changes: 1 addition & 1 deletion templates/admin/content/_read_indexing.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@
</dd>
</dl>
{% endblock %}
{% endembed %}
{% endembed %}
2 changes: 1 addition & 1 deletion templates/admin/content/_version_info_seo.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{% block content %}
<code class="text-muted">
<pre class="overflow-auto"
style="max-height: 300px">{{ version_entity.seo|json_encode(constant('JSON_PRETTY_PRINT')) }}</pre>
style="max-height: 300px">{{ version_entity.rawSeo()|json_encode(constant('JSON_PRETTY_PRINT')) }}</pre>
</code>
{% endblock content %}
{% endembed %}
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/Entity/PageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,4 @@ public function testLastVersionNumber(): void
$page->setLastVersionNumber(1);
$this->assertEquals(1, $page->getLastVersionNumber());
}
}
}
Loading