Προτεραιότητα του resolver
Κάθε τελική τιμή SEO — τίτλος, περιγραφή, canonical, robots, εικόνες — παράγεται από το SEOResolver με συγχώνευση έξι επιπέδων. Τα ανώτερα επίπεδα υπερισχύουν και το null δεν αντικαθιστά ποτέ μια τιμή κατώτερου επιπέδου, ώστε κάθε σελίδα να αποδίδει πάντα εύλογα δεδομένα.
Τα έξι επίπεδα
Από το χαμηλότερο (υπάρχει πάντα) στο υψηλότερο (υπερισχύει πάντα):
| # | Επίπεδο | Πηγή | Συνήθης χρήση |
|---|---|---|---|
| 1 | Ρυθμίσεις ιστοτόπου | config/seo.php (site_name, title_suffix, default_og_image, default_robots, …) | Προεπιλογές για όλη την επωνυμία |
| 2 | Καθολικές προεπιλογές βάσης δεδομένων | Εγγραφές seo_defaults χωρίς τύπο μοντέλου | Επεξεργάσιμες προεπιλογές για όλο τον ιστότοπο, χωρίς νέα ανάπτυξη κώδικα |
| 3 | Προεπιλογές ανά τύπο μοντέλου | Εγγραφές seo_defaults για συγκεκριμένη κλάση μοντέλου | «Όλα τα προϊόντα παίρνουν αυτή την εικόνα OG» |
| 4 | Προεπιλογές διαδρομής | Εγγραφές seo_defaults για συγκεκριμένο όνομα διαδρομής | Στατικές σελίδες (home, contact) χωρίς μοντέλο |
| 5 | Υπολογιζόμενες τιμές | Προκύπτουν από τα χαρακτηριστικά του ίδιου του μοντέλου | Εναλλακτικός τίτλος από το title, περιγραφή από τα excerpt/body, … |
| 6 | Ρητές τιμές | Η εγγραφή seo_meta του μοντέλου (saveSEO()) | Όσα ορίζουν χειροκίνητα οι συντάκτες |
use Rankbeam\Seo\Facades\SEO;
$seo = SEO::resolve($post); // model page: layers 1-3 + 5-6
$seo = SEO::forRoute('contact'); // route page: layers 1-2 + 4Το αποτέλεσμα είναι ένα αμετάβλητο αντικείμενο τιμών SEOData που χρησιμοποιείται από κάθε renderer (Blade, πίνακας, Inertia).
Υπολογιζόμενες εναλλακτικές τιμές (επίπεδο 5)
Όταν δεν υπάρχει ρητή τιμή, ο resolver παράγει μία από το μοντέλο:
- Τίτλος — το χαρακτηριστικό
title/nameτου μοντέλου. - Περιγραφή — το πρώτο χαρακτηριστικό στο
seo.computed.description_fields(προεπιλεγμένη αλυσίδα:excerpt,summary,description,intro,lead,teaser,content,body,text,article) που περιέχει ουσιαστικό κείμενο. Το HTML αφαιρείται, οι οντότητες αποκωδικοποιούνται και το κείμενο περικόπτεται σε όριο λέξης (seo.computed.description_max_length, προεπιλογή 160 — χωρίς αποσιωπητικά). - Robots — από ένα hook
getSEORobots()του μοντέλου ή ένα χαρακτηριστικόis_indexable(δείτε τον Έλεγχο robots και δυνατότητας ευρετηρίασης). - Τιμές που προκύπτουν από την URL — canonical και
og:urlαπό τοgetUrlForSEO().
Έλεγχος robots και δυνατότητας ευρετηρίασης
Το noindex ανά μοντέλο είναι ενσωματωμένο — χωρίς επιπλέον πακέτο ή ειδική διαδικασία για στήλες. Το trait HasSEO δεν δηλώνει μέθοδο robots (είναι προαιρετική), οπότε είναι εύκολο να την παραβλέψετε, αλλά ο resolver ήδη λαμβάνει υπόψη τρεις πηγές, με πρώτη την υψηλότερη προτεραιότητα:
| Προτεραιότητα | Πηγή | Παράδειγμα |
|---|---|---|
| 1 | Ρητό seo_meta.robots | $page->saveSEO(['robots' => 'noindex,follow']) |
| 2 | Hook getSEORobots(): ?string στο μοντέλο | Επιστρέψτε 'noindex, nofollow', ή null για να συνεχιστεί η αναζήτηση τιμής |
| 3 | Χαρακτηριστικό is_indexable (στήλη ή accessor) | falsy ⇒ noindex, nofollow· truthy ⇒ index, follow |
class Page extends Model
{
use HasSEO;
// Option A: let the resolver derive robots from a boolean flag.
// Schema::table('pages', fn ($t) => $t->boolean('is_indexable')->default(true));
// Option B: compute it from your own state.
public function getSEORobots(): ?string
{
return $this->status === 'draft' ? 'noindex, nofollow' : null;
}
}
// Option C: set it explicitly per page (wins over A and B).
$page->saveSEO(['robots' => 'noindex, follow']);Τι αποδίδεται τελικά
Η επιλυμένη οδηγία φιλτράρεται από την πολιτική παραγωγής πριν φτάσει στο <head>: η ετικέτα <meta name="robots"> παράγεται μόνο όταν η οδηγία διαφέρει από το default_robots (προεπιλογή index,follow). Επομένως:
- Μια ευρετηριάσιμη σελίδα (επιλύεται σε
index, follow) δεν παράγει ετικέτα robots — η απουσία της είναι ακριβώς αυτό που ο ανιχνευτής ερμηνεύει ως index,follow. - Μια μη ευρετηριάσιμη σελίδα παράγει
<meta name="robots" content="noindex, nofollow">. - Κάθε οδηγία που διαφέρει (
noindex,max-snippet:-1,unavailable_after, …) παράγεται αυτούσια, διατηρώντας τα κενά που πληκτρολογήσατε.
Ορίστε το seo.robots.emit_default = true για να αποδίδεται πάντα η ετικέτα. Πλήρεις λεπτομέρειες στην πολιτική απόδοσης robots.
Πολιτικές που εφαρμόζονται μετά την επίλυση
Αυτές εκτελούνται ανεξάρτητα από το επίπεδο που παρήγαγε την τιμή:
- Επίθημα τίτλου — το
title_suffixπροστίθεται, εκτός αν ο επιλυμένος τίτλος τελειώνει ήδη με αυτό. Αν ένα πρότυπο προεπιλογής διαδρομής περιέχει ήδη την επωνυμία σας, τερματίστε το πρότυπο με το επίθημα για να αποφύγετε το «Brand — X | Brand». - Αφαίρεση query από την κανονική URL — από τις κανονικές URL που παράγονται (URL μοντέλου / τρέχουσα URL) αφαιρείται το query string, εκτός από τα κλειδιά που ορίζονται στο
canonical.query_whitelist(π.χ.pageγια σελιδοποιημένα αρχεία), τα οποία διατηρούνται· οι κανονικές URL που ορίζονται ρητά διατηρούνται αυτούσιες. - Απόλυτες URL κοινωνικών εικόνων — τα
og:imageκαιtwitter:imageπαράγονται πάντα ως απόλυτες URL (το απαιτεί η προδιαγραφή Open Graph), ακόμη και όταν η αποθηκευμένη τιμή είναι σχετική διαδρομή.
Εξέταση του επιπέδου που υπερίσχυσε
Το πακέτο Filament εμφανίζει αυτή την πληροφορία ανά πεδίο (Χειροκίνητα / Εναλλακτικά από το περιεχόμενο / Προεπιλογή τύπου μοντέλου / Καθολική προεπιλογή / Ρυθμίσεις ιστότοπου / Προκύπτει από το URL). Στον κώδικα, το SEOWarningEvaluator εκθέτει την ίδια διάκριση μεταξύ χειροκίνητης και εναλλακτικής τιμής για να δημιουργήσετε δικές σας ενδείξεις διαχείρισης.