Ένας πρακτικός οδηγός για τη σύνταξη εκφράσεων CEL στο CMS.
Ένας πρακτικός οδηγός για τη σύνταξη εκφράσεων CEL στο CMS.
Η CEL (Common Expression Language) είναι μια ελαφριά γλώσσα scripting ενσωματωμένη στο CMS μας. Σας επιτρέπει να γράφετε δυναμικές εκφράσεις που αντλούν δεδομένα από έγγραφα, διαβάζουν παραμέτρους URL και υπολογίζουν τιμές κατά την εκτέλεση.
Τι συμβαίνει όταν εκτελείται ένα script CEL:
Η CEL λειτουργεί σαν γλώσσα ερωτημάτων μόνο για ανάγνωση. Δεν μπορεί να τροποποιήσει τίποτα στη βάση δεδομένων· απλώς διαβάζει δεδομένα και επιστρέφει ένα υπολογισμένο αποτέλεσμα. Αυτό την καθιστά ασφαλή για χρήση οπουδήποτε στο CMS.
Κάθε έκφραση CEL έχει πρόσβαση σε τρία πράγματα:
| Αντικείμενο | Τι είναι | Παράδειγμα |
|---|---|---|
documents | Ανάκτηση οποιουδήποτε εγγράφου από το CMS | documents.get("country", "us") |
meta | Πληροφορίες για το τρέχον αίτημα (τοπικές ρυθμίσεις, παράμετροι URL) | meta.locale, meta.params.slug |
schema | Οι ορισμοί πεδίων του τρέχοντος εγγράφου | schema.fields |
docΌταν γράφετε εκφράσεις CEL μέσα σε έναν επεξεργαστή εγγράφων, μπορείτε να αποκτήσετε πρόσβαση στις τιμές των πεδίων του τρέχοντος εγγράφου χρησιμοποιώντας το αντικείμενο doc. Αυτό επιτρέπει υπολογιζόμενα πεδία και αναφορές μεταξύ πεδίων.
Το αντικείμενο doc περιέχει όλες τις τιμές πεδίων του εγγράφου που επεξεργάζεστε. Είναι χρήσιμο για:
doc.price * doc.quantity)Η ισχυρότερη δυνατότητα της CEL είναι η ανάκτηση εγγράφων από οπουδήποτε στο CMS.
Σύνταξη: documents.get(schemaName, identifier)
Αν έχετε ένα έγγραφο article αποθηκευμένο με αναγνωριστικό "welcome-post", μπορείτε να το ανακτήσετε ως εξής:
Για ανάκτηση ολόκληρου του εγγράφου:
documents.get("article", "welcome-post")
Για ανάκτηση μόνο του τίτλου:
documents.get("article", "welcome-post").headline
Όταν η σελίδα σας διαθέτει δυναμικές διαδρομές, όπως /articles/[slug], μπορείτε να χρησιμοποιήσετε το meta.params για να λάβετε την παράμετρο URL και να ανακτήσετε το σωστό έγγραφο.
documents.get("article", meta.params.slug).headline
Έτσι δημιουργείτε δυναμικές σελίδες: το ίδιο script CEL λειτουργεί για κάθε άρθρο, χρησιμοποιώντας το slug που υπάρχει στη διεύθυνση URL.
Σύνταξη: documents.find(schemaName) ή documents.find(schemaName, filter)
// Λήψη όλων των χωρών
documents.find("country")
// Λήψη χωρών με φίλτρο
documents.find("country", { "where": { "code": "us" } })
Η CEL υποστηρίζει την ανάκτηση μεταφρασμένου περιεχομένου εγγράφων με δύο τρόπους: αυτόματη μετάφραση βάσει τοπικών ρυθμίσεων και ρητή αναζήτηση μετάφρασης.
Όταν έχει οριστεί το meta.locale (για παράδειγμα από παραμέτρους διαδρομής ή προτιμήσεις χρήστη), η documents.get() συγχωνεύει αυτόματα το μεταφρασμένο περιεχόμενο:
// Αν το meta.locale είναι "fr", επιστρέφει τη γαλλική μετάφραση συγχωνευμένη με το βασικό έγγραφο
documents.get("greeting", "welcome").headline
Πώς λειτουργεί:
meta.locale δεν είναι "en" ή "en-US", αναζητά τη μετάφραση στον πίνακα translationsΤα μεταφρασμένα πεδία αντικαθιστούν τα βασικά πεδία, ενώ τα πεδία χωρίς μετάφραση χρησιμοποιούν το βασικό έγγραφο.
Όταν χρειάζεται να ανακτήσετε μια συγκεκριμένη μετάφραση ανεξάρτητα από την τρέχουσα τοπική ρύθμιση:
Σύνταξη: documents.translated(schemaName, identifier, locale)
// Πάντα ανάκτηση της ισπανικής μετάφρασης
documents.translated("greeting", "welcome", "es").headline
// Ανάκτηση μετάφρασης βάσει παραμέτρου URL
documents.translated("product", meta.params.id, meta.params.lang).description
// Σύγκριση μεταφράσεων
documents.translated("article", "intro", "en").title + " / " + documents.translated("article", "intro", "fr").title
Έχετε ένα hero-block που πρέπει να εμφανίζει έναν τίτλο από ένα έγγραφο article.
Το script CEL στο πεδίο τίτλου του hero block είναι:
documents.get("article", "homepage-hero").headline
Αποτέλεσμα: Το hero εμφανίζει τον αντίστοιχο τίτλο.
Δημιουργείτε μια σελίδα στη διεύθυνση /countries/[code] και θέλετε να εμφανίσετε το πλήρες όνομα της χώρας.
documents.get("country", meta.params.code).name
Όταν κάποιος επισκέπτεται το /countries/us, το meta.params.code είναι "us" και το αποτέλεσμα είναι το όνομα της χώρας.
Εμφανίστε διαφορετικούς τίτλους ανάλογα με την τοπική ρύθμιση του χρήστη:
meta.locale == "ar-SA" ? "Welcome, everyone" : "Welcome"
Αν το article διαθέτει πεδίο countryCode και θέλετε να λάβετε το πλήρες όνομα της χώρας:
documents.get("country", documents.get("article", "us-news").countryCode).name
Οι αναζητήσεις μπορούν να συνδυάζονται, ώστε το αποτέλεσμα ενός εγγράφου να χρησιμοποιείται ως αναγνωριστικό για την ανάκτηση του επόμενου.
Αν ένα έγγραφο μπορεί να μην υπάρχει, μπορείτε να παρέχετε εφεδρική τιμή:
documents.get("article", meta.params.slug) != null
? documents.get("article", meta.params.slug).headline
: "Article Not Found"
Μπορείτε επίσης να ελέγξετε αν υπάρχει ένα συγκεκριμένο πεδίο:
documents.get("article", "intro").author != null
? documents.get("article", "intro").author
: "Unknown Author"
Για να ελέγξετε αν υπάρχει μια συγκεκριμένη ετικέτα:
"featured" in documents.get("article", "welcome-post").tags
Επιστρέφει true αν το άρθρο έχει την ετικέτα.
Για να λάβετε την πρώτη ετικέτα:
documents.get("article", "welcome-post").tags[0]
Για να μετρήσετε τις ετικέτες:
size(documents.get("article", "welcome-post").tags)
Οι παραμετρικές διαδρομές είναι το κλειδί για τη δημιουργία δυναμικών, πολυγλωσσικών σελίδων. Όταν ορίζετε ένα μοτίβο διαδρομής όπως /{lang}/landingPage, το CMS εξάγει τις παραμέτρους από τη διεύθυνση URL και τις διαθέτει μέσω του meta.params.
Οι διαδρομές χρησιμοποιούν τη σύνταξη :paramName ή {paramName} για τον ορισμό δυναμικών τμημάτων. Κάθε παράμετρος μπορεί να συνδεθεί με ένα schema εγγράφου για επικύρωση.
Η σύνδεση ενημερώνει το CMS να εξαγάγει το τμήμα από το URL, να το επικυρώσει στο αντίστοιχο schema και, αν είναι έγκυρο, να διαθέσει ολόκληρο το έγγραφο στις επιλυμένες παραμέτρους.
Διαμόρφωση διαδρομής:
/{lang}/landingPage/{lang}/landingPage{ "lang": "language" }Script CEL για ανάκτηση τοπικοποιημένου περιεχομένου:
documents.get("greeting", meta.params.lang).headline
Το meta.segments παρέχει τη μη επεξεργασμένη διαδρομή URL ως πίνακα και είναι χρήσιμο όταν χρειάζεστε πρόσβαση βάσει θέσης χωρίς ονομασμένες παραμέτρους.
| Περίπτωση χρήσης | Καλύτερη προσέγγιση |
|---|---|
| Ονομασμένες παράμετροι από το μοτίβο διαδρομής | meta.params.lang |
| Πρόσβαση βάσει θέσης | meta.segments[0] |
| Λήψη του βάθους της διαδρομής | size(meta.segments) |
| Έλεγχος αν η διαδρομή περιέχει ένα τμήμα | "admin" in meta.segments |
// Λήψη του πρώτου τμήματος
meta.segments[0]
// Έλεγχος βάθους διαδρομής
size(meta.segments) > 2 ? "deep" : "shallow"
// Έλεγχος αν βρισκόμαστε στην ενότητα διαχείρισης
"admin" in meta.segments ? "admin mode" : "public mode"
// Εφεδρική λύση: χρήση τμήματος αν η παράμετρος δεν είναι συνδεδεμένη
has(meta.params.lang) ? meta.params.lang : meta.segments[0]
Το αντικείμενο meta περιέχει όλο το περιβάλλον του τρέχοντος αιτήματος:
| Ιδιότητα | Τύπος | Περιγραφή |
|---|---|---|
meta.locale | string | Κωδικός τρέχουσας τοπικής ρύθμισης |
meta.params | Record<string, string> | Παράμετροι διαδρομής που εξάγονται από το URL |
meta.segments | string[] | Η διαδρομή URL χωρισμένη σε τμήματα |
meta.docId | string | null | UUID του τρέχοντος εγγράφου |
meta.title | string | Τίτλος του τρέχοντος εγγράφου |
Ο κωδικός τοπικής ρύθμισης ακολουθεί τη μορφή BCP 47:
// Έλεγχος τοπικών ρυθμίσεων για γλώσσες RTL
meta.locale == "ar-SA" || meta.locale == "he-IL" ? "rtl" : "ltr"
Οι παράμετροι διαδρομής είναι πάντα συμβολοσειρές. Το CMS τις επικυρώνει έναντι των συνδεδεμένων schema πριν από την αξιολόγηση:
// Πρόσβαση σε ονομασμένη παράμετρο
meta.params.lang
meta.params.country
meta.params.slug
// Έλεγχος αν υπάρχει παράμετρος
has(meta.params.category)
// Χρήση σε ανάκτηση εγγράφου
documents.get("greeting", meta.params.lang)
documents.ref("airports").get(meta.params.code)
Το UUID του τρέχοντος εγγράφου, χρήσιμο για scripts που αναφέρονται στο ίδιο το έγγραφο:
meta.docId != null ? "editing" : "creating new"
meta.docId != null ? documents.get("article", meta.docId).status : "draft"
Ο τίτλος του τρέχοντος εγγράφου:
"Editing: " + meta.title
meta.title.contains("Draft") ? "work in progress" : "published"
Για καθαρότερη σύνταξη όταν το schema είναι γνωστό αλλά το αναγνωριστικό είναι δυναμικό:
// Παραδοσιακή προσέγγιση
documents.get("airports", meta.params.code).name
// Χρήση ref()
documents.ref("airports").get(meta.params.code).name
Και οι δύο τρόποι είναι ισοδύναμοι, αλλά το ref() κάνει το δυναμικό μέρος πιο σαφές.
documents.get("schema", "identifier")
documents.get("schema", "id").fieldName
documents.find("schema")
documents.find("schema", { "where": {...}})
documents.ref("schema").get(identifier)
documents.translated("schema", "id", "fr")
meta.locale
meta.params.xyz
meta.segments
meta.segments[0]
meta.docId
a.meta.title
doc.fieldName
== != < <= > >=
&& || !
condition ? valueIfTrue : valueIfFalse
"value" in listOrMap
size(list)
size(string)
"text".startsWith("te")
"text".endsWith("xt")
"text".contains("ex")
has(object.property)
hasProperty(obj, "key")
Αν κάτι πάει στραβά, θα δείτε ένα από τα εξής:
| Σφάλμα | Τι σημαίνει |
|---|---|
SYNTAX_ERROR | Τυπογραφικό λάθος στο script σας |
TYPE_ERROR | Συνδυάζετε τύπους που δεν είναι συμβατοί |
RUNTIME_ERROR | Το script εκτελέστηκε αλλά αντιμετώπισε πρόβλημα |
FETCH_LIMIT_EXCEEDED | Ανακτάτε πάρα πολλά έγγραφα (μέγιστο 50) |
TIMEOUT | Το script χρειάστηκε υπερβολικά πολύ χρόνο (μέγιστο 5 δευτερόλεπτα) |
AST_DEPTH_EXCEEDED | Η έκφραση είναι υπερβολικά ένθετη |
SCRIPT_TOO_LONG | Το script υπερβαίνει το όριο των 5.000 χαρακτήρων |
Η μηχανή CEL έχει σχεδιαστεί για επεκτασιμότητα. Οι μελλοντικές δυνατότητες περιλαμβάνουν:
mcp.translate(meta.params.text, "en", meta.params.lang)
mcp.analyze(documents.get("article", meta.params.id).body)
ai.summarize(documents.get("article", meta.params.id).body, 100)
ai.translate(meta.params.text, meta.params.targetLang)
ai.classify(meta.params.input, ["positive", "negative", "neutral"])
Οι δυνατότητες αυτές θα προστεθούν μέσω του συστήματος καταχωρισμένων συναρτήσεων, διατηρώντας τη συμβατότητα με τα υπάρχοντα scripts.
documents. ή meta. για να δείτε τις διαθέσιμες επιλογέςdocuments.get("schema", "id") και έπειτα προσθέστε .fieldNamedocuments.get() ή documents.find() μετρά στο όριο των 50 ανακτήσεωνΑυτή η ενότητα καλύπτει προηγμένα μοτίβα σύνδεσης εγγράφων και δημιουργίας σχεσιακών δομών περιεχομένου.
Η απλούστερη μορφή είναι ένα έγγραφο να αναφέρεται σε άλλο μέσω αναγνωριστικού:
documents.get("author", documents.get("article", "intro").authorId).name
Όταν το αναγνωριστικό είναι δυναμικό:
documents.ref("country").get(documents.get("airport", meta.params.code).countryCode).name
Μπορείτε να δημιουργήσετε βαθιές σχέσεις συνδυάζοντας πολλές αναζητήσεις. Να λαμβάνετε υπόψη την καθυστέρηση και το όριο των 50 ανακτήσεων.
documents.translated("country",
documents.get("airport", meta.params.code).countryCode,
meta.params.lang
).name
Κάθε κλήση documents.get(), documents.find() και documents.ref().get() παρακολουθείται για ακύρωση της cache. Όταν αλλάζει ένα έγγραφο που αναφέρεται, το CMS γνωρίζει ποιες εκφράσεις CEL πρέπει να αξιολογηθούν ξανά.
Αυτός ο οδηγός δημιουργεί μια πολύγλωσση σελίδα προορισμού διαθέσιμη στη διεύθυνση /{lang}/landingPage.
Στη διαχείριση του CMS δημιουργήστε ένα προσαρμοσμένο schema με το όνομα greeting, με πεδία code, headline, subheadline, ctaText και ctaUrl.
Δημιουργήστε ένα έγγραφο για κάθε γλώσσα, όπως greeting/ko, greeting/en και greeting/ja.
Δημιουργήστε μια σελίδα με τη διαμόρφωση:
/{lang}/landingPagelang στο στοιχείο languageΠροσθέστε ένα hero block στη διαδρομή με τα ακόλουθα scripts CEL:
documents.get("greeting", meta.params.lang).headline
documents.get("greeting", meta.params.lang).subheadline
documents.get("greeting", meta.params.lang).ctaText
documents.get("greeting", meta.params.lang).ctaUrl
Προσθέστε μια catch-all διαδρομή. Το ParametricRoutePage επιλύει τη σελίδα, εξάγει το meta.params από το URL, αξιολογεί τις συνδέσεις CEL στην πλευρά του διακομιστή και αποδίδει κάθε block μέσω του registry.
Επισκεφθείτε τις διευθύνσεις URL για να δείτε το τοπικοποιημένο περιεχόμενο:
| URL | Αναμενόμενος τίτλος |
|---|---|
/ko/landingPage | 환영 |
/en/landingPage | Καλώς ήρθατε |
/ja/landingPage | いらっしゃいませ |
Όταν ένας χρήστης επισκέπτεται το /ko/landingPage:
/{lang}/landingPagemeta.params.lang = "ko""ko" υπάρχει στο schema languageΗ διεπαφή περιλαμβάνει τις ιδιότητες locale, params, segments, docId και title, οι οποίες αντιστοιχούν στο περιβάλλον της τρέχουσας αίτησης.
Η συνάρτηση extractParams επεξεργάζεται τις διαδρομές URL: κανονικοποιεί τις διαδρομές, τις χωρίζει σε τμήματα, συγκρίνει τον αριθμό τμημάτων, εξάγει τα δυναμικά τμήματα ως παραμέτρους και επιστρέφει το αποτέλεσμα.
{ "lang": "language" }
{
"lang": {
"schemaName": "language",
"slugField": "code"
},
"slug": {
"schemaName": "article",
"slugField": "slug"
}
}
Κατά την ανάκτηση μέσω documents.get(schema, identifier):
idcontent.codecontent.slugtitleΑυτό επιτρέπει ευέλικτες αναφορές σε έγγραφα μέσω οποιουδήποτε μοναδικού αναγνωριστικού.