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

Localization Issues #172

Draft
wants to merge 4 commits into
base: master
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
14 changes: 13 additions & 1 deletion resources/js/components/fieldtypes/GooglePreviewFieldtype.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,33 @@

computed: {
previewParts() {

const state = this.$store.state.publish[this.storeName];

const {
meta_title,
meta_description,
slug,
title,
} = state.values;

const {
site_name,
site_url,
title_separator,
default_locale,
} = this.meta;

// Initialise pageTitle with meta_title if available, otherwise combine title with site name and separator.
let pageTitle = meta_title || `${title}${site_name ? ` ${title_separator} ${site_name}` : ''}`;

// Override pageTitle for non-default locales without a localised meta_title, using title and optionally site name and separator.
if (state && state.localizedFields && default_locale !== state.site && !state.localizedFields.includes('meta_title')) {
pageTitle = `${title}${site_name ? ` ${title_separator} ${site_name}` : ''}`;
}

return {
title: meta_title || `${title} ${title_separator} ${site_name}`,
title: pageTitle,
url: `${site_url}/${slug}`,
description: meta_description
}
Expand Down
89 changes: 87 additions & 2 deletions resources/js/components/fieldtypes/MetaTitleFieldtype.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="meta-field-validator__outer">
<div class="meta-field-validator__field-container">
<div class="input-group">
<input :value="value" @input="update($event.target.value)" @keyup="handleKeyUp" type="text" :name="name" :id="id" :placeholder="generatePlaceholder()" class="input-text" />
<input @focus="toggleFocus(true)" @blur="toggleFocus(false)" :value="generateTitle(value)" @input="update($event.target.value)" @keyup="handleKeyUp" type="text" :name="name" :id="id" :placeholder="generatePlaceholder()" class="input-text" />
</div>
<progress max="70" :value="contentLength" :class="'meta-field-validator__progress meta-field-validator__progress--' + validation.step" />
</div>
Expand All @@ -14,15 +14,100 @@
import MetaDataAnalyser from './mixins/MetaDataAnalyser';

export default {

mixins: [Fieldtype, MetaDataAnalyser],

inject: ['storeName'],

data() {
return {
isFocused: false,
hasSyncedJustChanged: false,
};
},

computed: {
/**
* Computes the synchronization state based on whether the current handle
* is included in the localizedFields array from the Vuex store state.
* @returns {Boolean} The sync state.
*/
isSynced() {
const state = this.$store.state.publish[this.storeName];
if (state && state.localizedFields) {
return !state.localizedFields.includes(this.config.handle);
}
return false;
},
},

watch: {
/**
* Watches for changes in the `isSynced` computed property to perform
* actions or log its changes.
*/
isSynced(newVal, oldVal) {
if (newVal !== oldVal) {
this.hasSyncedJustChanged = true;
}
},
},

methods: {
toggleFocus(focusState) {
this.isFocused = focusState;
},
generatePlaceholder() {
const state = this.$store.state.publish[this.storeName];
return `${state.values.title || ''} ${this.meta.title_separator} ${this.meta.site_name}`
return this.meta.site_name
? `${state.values.title || ''} ${this.meta.title_separator} ${this.meta.site_name}`
: state.values.title || '';
},
/**
* Generates the title based on localisation fields.
* If the current site is not the default locale and the 'meta_title' is not localised,
* it returns an empty string; otherwise, it returns the provided value. It also handles the sync logic by updating
* the meta title based on the fields current sync state.
*
* @param {string} value - The original title value to potentially return.
* @return {string} - The localised title based on the current site's locale and field's sync state, or an empty string.
*/
generateTitle(value) {
// Access the publish state from the Vuex store
const state = this.$store.state.publish[this.storeName];

// Check if state is defined, and if the current site has localizedFields and is not the default locale.
if(state && state.localizedFields && this.meta.default_locale !== state.site) {

// If the field is not synced and has just been changed and is not currently focused,
// reset the hasSyncedJustChanged flag and update the meta title to match the page title.
if (!this.isSynced && this.hasSyncedJustChanged && !this.isFocused) {
this.hasSyncedJustChanged = false;
// ToDo: Best practice: dispatch an action or commit a mutation instead
state.values.meta_title = state.values.title;
return state.values.title;
}

// If the field is synced and has just been changed and is not currently focused, clear the meta title.
if(this.isSynced && this.hasSyncedJustChanged && !this.isFocused) {
// ToDo: Best practice: dispatch an action or commit a mutation instead
state.values.meta_title = '';
}

// If the field is synced and has not just changed, ensure the meta title remains cleared.
if(this.isSynced && !this.hasSyncedJustChanged) {
// ToDo: Best practice: dispatch an action or commit a mutation instead
state.values.meta_title = '';
}

// Return the value only if 'meta_title' is a localised field
return state.localizedFields.includes('meta_title') ? value : '';
}

// Return the provided value as default
return value;
},

validateMeta(length) {
let validation;
switch (true) {
Expand Down
1 change: 1 addition & 0 deletions src/Fieldtypes/AardvarkSeoGooglePreviewFieldtype.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function preload()
'site_name' => $data->get('site_name', ''),
'site_url' => $site->absoluteUrl(),
'title_separator' => $data->get('title_separator', '|'),
'default_locale' => Site::default()->handle(),
];
}
}
4 changes: 3 additions & 1 deletion src/Fieldtypes/AardvarkSeoMetaTitleFieldtype.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ class AardvarkSeoMetaTitleFieldtype extends Fieldtype
/**
* Load the global seo settings from storage
*/
public function preload()
public function preload(): array
{
$site = Site::selected();
$data = AardvarkStorage::getYaml('general', $site, true);

return [
'site_name' => $data->get('site_name', ''),
'title_separator' => $data->get('title_separator', '|'),
'default_locale' => Site::default()->handle(),
];
}
}
72 changes: 66 additions & 6 deletions src/Parsers/PageDataParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use WithCandour\AardvarkSeo\Blueprints\CP\SocialSettingsBlueprint;
use WithCandour\AardvarkSeo\Blueprints\CP\OnPageSeoBlueprint;
use WithCandour\AardvarkSeo\Facades\AardvarkStorage;
use Statamic\Facades\Entry;

/**
* Helper class for parsing on-page data
Expand Down Expand Up @@ -158,21 +159,80 @@ public static function getSettingsBlueprintWithValues($ctx, $type, $blueprint_cl
*/
public static function generatePageTitle($data, $ctx)
{
if ($data->get('meta_title') && $data->get('meta_title')->raw()) {
// Check if an ID exists in the provided data.
if ($data->get('id')) {

// Retrieve the default site's configuration to compare locales.
$defaultSite = Site::default();
// Get the handle (identifier) of the default site.
$defaultLocale = $defaultSite->handle();
// Find the entry associated with the given ID.
$entry = Entry::find($data->get('id')->raw());

// Ensure the entry exists and its locale does not match the default site's locale.
if ($entry && method_exists($entry, 'locale') && $defaultLocale != $entry->locale()) {

// Check if the entry has a 'meta_title' set.
if ($entry->has('meta_title') && !empty ($entry->get('meta_title'))) {
// If 'meta_title' exists, parse it with context and return.
return Parse::template($entry->get('meta_title'), $ctx);
}

// If there's no 'meta_title', check for a regular 'title' field as a fallback.
if ($entry->has('title') && !empty ($entry->get('title'))) {

$title = self::constructPageTitle($ctx, $entry->get('title'));

// Parse and return the 'title' with context.
return Parse::template($title, $ctx);
}

// If the localized entry lacks a 'title' or 'meta_title', fall back to the 'title' from the original data.
if ($data->has('title') && !empty ($data->get('title'))) {

// Construct the page title by combining the entry title with the site name and title separator, only if the site name is set.
$title = self::constructPageTitle($ctx, $data->get('title'));

// Parse and return the 'title' with context.
return Parse::template($title, $ctx);
}
}
}

if ($data->has('meta_title') && !empty ($data->get('meta_title')->raw())) {
return Parse::template($data->get('meta_title'), $ctx);
}

if ($data->get('response_code') === 404) {
$data->put('title', '404');
}
$title = self::constructPageTitle($ctx, $data->get('title'));

return $title;
}

/**
* Constructs the page title by combining the entry title with the site name and title separator.
*
* @param string $title The primary title part.
* @param Illuminate\Support\Collection $storage The storage collection containing site configuration.
* @return string The constructed page title.
*/
protected static function constructPageTitle($ctx, $title): string {

$storage = self::getSettingsBlueprintWithValues($ctx, 'general', new GeneralSettingsBlueprint());
$titleParts = [$title];

$siteName = $storage->get('site_name');
if ($siteName !== null) {
$siteNameValue = $siteName->raw();
if (!empty($siteNameValue)) {
$titleParts[] = $storage->get('title_separator');
$titleParts[] = $siteNameValue;
}
}

return implode(' ', [
$data->get('title'),
$storage->get('title_separator'),
$storage->get('site_name'),
]);
return implode(' ', array_filter($titleParts));
}

/**
Expand Down