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

Refactor blueprint extension #153

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
64 changes: 53 additions & 11 deletions src/Actions/EvaluateModelLocale.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
use Statamic\Contracts\Entries\Collection;
use Statamic\Contracts\Entries\Entry;
use Statamic\Contracts\Taxonomies\Taxonomy;
use Statamic\Contracts\Taxonomies\Term;
use Statamic\Events\EntryBlueprintFound;
use Statamic\Events\TermBlueprintFound;
use Statamic\Facades\Entry as EntryFacade;
use Statamic\Facades\Site;
use Statamic\Statamic;
use Statamic\Tags\Context;
use Statamic\Taxonomies\LocalizedTerm;
use Statamic\Taxonomies\Term;

class EvaluateModelLocale
{
Expand All @@ -24,10 +25,11 @@ public static function handle(mixed $model): ?string
($model instanceof SeoDefaultSet) => self::seoDefaultSet($model),
($model instanceof Collection) => self::collection(),
($model instanceof Entry) => $model->locale(),
($model instanceof EntryBlueprintFound) => self::entryBlueprintFound(),
($model instanceof EntryBlueprintFound) => self::entryBlueprintFound($model),
($model instanceof Taxonomy) => self::taxonomy(),
($model instanceof Term) => self::term($model),
($model instanceof TermBlueprintFound) => self::termBlueprintFound(),
($model instanceof LocalizedTerm) => $model->locale(),
($model instanceof TermBlueprintFound) => self::termBlueprintFound($model),
($model instanceof Context) => $model->get('site')?->handle() ?? Site::current()->handle(),
($model instanceof DefaultsData) => $model->locale,
default => null
Expand Down Expand Up @@ -60,11 +62,29 @@ protected static function collection(): string
return Site::selected()->handle();
}

protected static function entryBlueprintFound(): string
protected static function entryBlueprintFound(EntryBlueprintFound $model): string
{
return Statamic::isCpRoute()
? basename(request()->path())
: Site::current()->handle();
// If we're not in the CP, simply return the current locale.
if (! Statamic::isCpRoute()) {
return Site::current()->handle();
}

$requestLocale = request()->get('site');

// If the request contains a valid site, use it.
if ($model->blueprint->parent()->sites()->contains($requestLocale)) {
return $requestLocale;
}

$pathLocale = basename(request()->path());

// If the request path is a valid site, use it.
if ($model->blueprint->parent()->sites()->contains($pathLocale)) {
return $pathLocale;
}

// Return the selected site if no locale has been evaluated so far.
return Site::selected()->handle();
}

protected static function taxonomy(): string
Expand All @@ -76,15 +96,37 @@ protected static function taxonomy(): string

protected static function term(Term $model): string
{
/**
* In the CP, a term always returns the default locale, no matter which locale is being viewed.
* As a workaround, we are getting the locale from the path instead.
*/
return Statamic::isCpRoute()
? basename(request()->path())
: $model->locale();
}

protected static function termBlueprintFound(): string
protected static function termBlueprintFound(TermBlueprintFound $model): string
{
return Statamic::isCpRoute()
? basename(request()->path())
: Site::current()->handle();
// If we're not in the CP, simply return the current locale.
if (! Statamic::isCpRoute()) {
return Site::current()->handle();
}

$requestLocale = request()->get('site');

// If the request contains a valid site, use it.
if ($model->blueprint->parent()->sites()->contains($requestLocale)) {
return $requestLocale;
}

$pathLocale = basename(request()->path());

// If the request path is a valid site, use it.
if ($model->blueprint->parent()->sites()->contains($pathLocale)) {
return $pathLocale;
}

// Return the selected site if no locale has been evaluated so far.
return Site::selected()->handle();
}
}
84 changes: 30 additions & 54 deletions src/Subscribers/OnPageSeoBlueprintSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@
use Illuminate\Events\Dispatcher;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Statamic\Events;
use Statamic\Events\Event;
use Statamic\Facades\Fieldset;
use Statamic\Facades\Site;
use Statamic\Statamic;

class OnPageSeoBlueprintSubscriber
{
Expand Down Expand Up @@ -59,6 +56,36 @@ public function extendBlueprint(Event $event): void
: $this->handleCustomizedBlueprint($event, $seoFields);
}

protected function shouldExtendBlueprint(Event $event): bool
{
// Don't add the fields if the collection/taxonomy is disabled.
if (Helpers::isDisabled($this->data->type, $this->data->handle)) {
return false;
}

// Ensure the collection/taxonomy defaults view doesn't break.
if (Helpers::isAddonCpRoute()) {
return false;
}

// Ensure the fields won't be saved to file when editing a blueprint.
if (Helpers::isBlueprintCpRoute()) {
return false;
}

/**
* TODO: This can be removed when the Statamic PR is merged that ensures a unique blueprint instance.
* The BlueprintFound event is called for every localization.
* But we only want to extend the blueprint for the current localization.
* Otherwise we will have issue evaluating conditional fields, e.g. the sitemap fields.
*/
if (Helpers::isEntryEditRoute()) {
return $event->entry?->id() === request()->route()->originalParameter('entry');
}

return true;
}

/**
* If the user didn't explicitly add any Advanced SEO fieldsets to the blueprint,
* we want to add all fields that are part of the 'advanced-seo::main' fieldset to the SEO section.
Expand Down Expand Up @@ -156,55 +183,4 @@ protected function ensureHiddenFields(Event $event, Collection $fieldsToHide): v
->map(fn ($config) => array_merge($config, ['if' => ['hide_me_and_do_not_save_data' => true]])) // Add condition to hide the field and save no data.
->each(fn ($config, $handle) => $event->blueprint->ensureField($handle, $config));
}

protected function shouldExtendBlueprint(Event $event): bool
{
// Don't add fields if the collection/taxonomy is excluded in the config.
if ($this->isDisabledType()) {
return false;
}

// Don't add fields in the blueprint builder.
if (Helpers::isBlueprintCpRoute()) {
return false;
}

// Don't add fields on any addon views in the CP.
if (Helpers::isAddonCpRoute()) {
return false;
}

// Don't add fields to any other CP route other than the entry/term view and when performing an action on the listing view (necesarry for the social images generator action to work).
if (Statamic::isCpRoute() && ! $this->isModelCpRoute($event) && ! $this->isActionCpRoute()) {
return false;
}

return true;
}

protected function isDisabledType(): bool
{
return in_array($this->data->handle, config("advanced-seo.disabled.{$this->data->type}", []));
}

protected function isModelCpRoute(Event $event): bool
{
// Has a value if editing or localizing an existing entry/term.
$id = $this->data->type === 'collections' ? $event->entry?->id() : $event->term?->slug();

// The locale a new entry is being created in.
$createLocale = Arr::get(Site::all()->map->handle(), basename(request()->path()));

/**
* The BlueprintFound event is called for every localization.
* But we only want to extend the blueprint for the current localization.
* Otherwise we will have issue evaluating conditional fields, e.g. the sitemap fields.
*/
return Statamic::isCpRoute() && Str::containsAll(request()->path(), [$this->data->type, $id ?? $createLocale]);
}

protected function isActionCpRoute(): bool
{
return Statamic::isCpRoute() && Str::containsAll(request()->path(), [$this->data->type, $this->data->handle, 'actions']);
}
}
24 changes: 14 additions & 10 deletions src/Support/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Aerni\AdvancedSeo\Support;

use Illuminate\Support\Str;
use Statamic\Statamic;

class Helpers
{
Expand All @@ -13,14 +14,24 @@ public static function parseLocale(string $locale): string
return \WhiteCube\Lingua\Service::create($parsed)->toW3C();
}

public static function isDisabled(string $type, string $handle): bool
{
return in_array($handle, config("advanced-seo.disabled.{$type}", []));
}

public static function isAddonCpRoute(): bool
{
return Str::containsAll(request()->path(), [config('statamic.cp.route', 'cp'), 'advanced-seo']);
return Statamic::isCpRoute() && Str::contains(request()->path(), 'advanced-seo');
}

public static function isBlueprintCpRoute(): bool
{
return Str::containsAll(request()->path(), [config('statamic.cp.route', 'cp'), 'blueprints']);
return Statamic::isCpRoute() && Str::contains(request()->path(), 'blueprints');
}

public static function isEntryEditRoute(): bool
{
return request()->route()?->getName() === 'statamic.cp.collections.entries.edit';
}

/**
Expand All @@ -29,13 +40,6 @@ public static function isBlueprintCpRoute(): bool
*/
public static function isCustomRoute(): bool
{
$allowedControllerActions = collect([
'Aerni\AdvancedSeo\Http\Controllers\Web\SocialImagesController@show',
'Statamic\Http\Controllers\FrontendController@index',
]);

$controllerAction = request()->route()?->getAction('controller');

return $allowedControllerActions->doesntContain($controllerAction);
return ! in_array(request()->route()?->getName(), ['statamic.site', 'social_images.show']);
}
}
Loading