Search

Browsing all 840 documents · showing 51–100

Decide between a custom field and a layout area Areas are for content an author composes on a record that has a layout; custom fields are for structured attributes on records that do not. Pages and posts take areas; people, menus, categories, tags and SEO settings take fields. /how-to/custom-field-or-area Find out why a page is slow Cached or rendered, server or browser, then which part of the template: three measurements that find the cause of a slow page before anyone changes code. /how-to/find-out-why-a-page-is-slow Create your first layout and template, from the admin to the repo Deploy the template file first, create the layout that points at it in the admin, add the layout areas, then create a page that uses it. The admin only offers templates that already exist on the server. /how-to/first-layout-and-template Build a breadcrumb trail from a record's ancestors getAllParents() returns a page's ancestors from the root down. Label the root "Home" yourself, link the rest with getFullPath(), and build a post's or record's trail from its container instead. /how-to/breadcrumb-trail Add a layout area and render it in the template Add the layout area to the layout in the admin with a permanent name, an input type and an editor-facing label; it appears empty on every record using the layout. Then read it with the getter for its type. /how-to/add-a-layout-area Output a menu with the current item highlighted Read the admin's menu by its exact name, loop the root elements and their children, and mark the current item with _url.isCurrentPath() or a path prefix. Unpublished elements show to admins only. /how-to/menu-with-current-item Relate two custom entity records to each other A relationship definition is a typed link between definitions with a minimum and maximum. Read it forwards from the owning record's relationships, and backwards with a query on the owning side, never by walking inverse relationships. /how-to/relate-custom-entity-records Link to a record without hardcoding its URL Take a URL from the record with getFullPath(), never from a path typed into the template. Get the record from an author-picked area, from a query by a stable attribute, or from a route name for module pages. /how-to/link-to-a-record Build a nightly export as a CSV file A scheduled job that retrieves the records, renders them as properly escaped CSV from a template, saves the file with an expiry, and emails a link to it. /how-to/nightly-csv-export Build a parent and child record hierarchy A definition with a parent definition makes every record a child of one parent record: created from the parent, sharing its site, moving with it. Give the child its own record path, and walk getParent() and getChildren(). /how-to/parent-child-records Add a per-site feature flag and read it in a template Site data is a per-site store of values an administrator edits in the admin without a deploy. A flag is one key; read it with _siteData.get(), and read the field you mean when the value is a structure. /how-to/site-feature-flag Generate a PDF certificate from a template Render the certificate's HTML from a template, send it to an HTML-to-PDF service with an HTTP request, save the answer with Create file under an unguessable name, and email the link. /how-to/pdf-certificate-from-a-template Diagnose "my change is not showing up" The most common question on any project, answered in the order the causes usually turn out to be true, with a marker in the page that settles the first one in seconds. /how-to/diagnose-my-change-is-not-showing-up Give a record a second URL with a custom URL A custom URL is an extra address independent of the slug and the tree. Both addresses serve the record, links from the record switch to it, and it works as a prefix. Add a rewrite if the old address must go. /how-to/second-url-with-custom-url Stop a job from triggering itself Run it asynchronously where you can, guard it with a condition on Pre-Event data, write the watched field only when the write changes something, and cap chains of jobs with a depth. /how-to/stop-a-hook-triggering-itself Move jobs from staging to production safely Deploy the templates, export and import the jobs, then set what did not travel (site, schedule, site data), check what did (record ids, URLs, slugs), and publish one job at a time. /how-to/move-hooks-from-staging-to-production Call the REST API from the browser with the CSRF token A same-origin script sends the session cookie by itself; for a signed-in visitor the platform also wants the session's CSRF token on every write. Put _csrfToken in a meta tag, send it as X-Csrf-Token, and keep that page out of the cache. /how-to/call-the-rest-api-from-the-browser Debug a job run that failed halfway Read the batch log in order: the event, the first failed action and what it received, then what already happened. Fix the cause, and re-run only a job that is safe to run twice. /how-to/debug-a-hook-batch-that-failed-halfway Render a collection, handling both global and local components On the frontend, a collection element's getComponent() already returns the global component when the element points at one, so one loop serves both. Guard for blank, and pass only new variable names down. /how-to/render-a-collection Fetch three entity types in one request with GraphQL A headless home page needs its navigation pages, the latest posts and the header menu. One POST to /cdna-api/graphql from your server returns all three with only the fields you render; this wraps the endpoint's rules in one function. /how-to/graphql-three-entity-types Nest a component inside another and keep heading levels valid A component with a collection of its own can hold components; the heading level is the thing that breaks. Keep the current level in the template context: read it, print, raise it for children, restore it afterwards. /how-to/nest-components-heading-levels Share a partial between several page types Put the fragment in includes/, pass what it needs by name, and never let it read the page's record directly, because the record arrives under a different name on every page type. Document its inputs at the top. /how-to/share-a-partial Build a global header and footer an author can edit A global component is stored once, versioned, and edited by authors without a deploy. Give it a component layout, an identifier, and fetch it in the base template with _globalComponents.get(). Its template reads areas as any component does. /how-to/global-header-and-footer Add a filter or extension to a Twig site You cannot: a theme has no PHP and the platform registers no site extensions. What you can do is a library of macros imported under one name, plus the core filters, the string extension and the platform's own additions. /how-to/twig-filter-or-extension Rename or retire a layout area without losing author content Content is stored against the layout area, not its name, so a rename keeps content and breaks templates; retire by hiding, never deleting; and change a type across categories by adding a new area and moving the content. /how-to/rename-or-retire-an-area Add translation to a Twig site, which has no trans filter Twig has no trans filter here, but every render receives the translator as __. Call __.translate(key, params, domain), wrap it in a macro that fixes the domain, and keep the keys in XLIFF files under translations/. /how-to/translation-in-twig Create a person record from a form submission Find the person by lower-cased email, update them if found (Record index 0, groups merged, names filled only when empty), create them otherwise. The actions were run on a development site with answers passed in place of a real submission. /how-to/create-a-person-from-a-form-submission Render a responsive image with an author-supplied crop The author chooses the crop through an attached attribute; the template resizes with that strategy and lets the picture-tag setting offer the widths. Resize, then convert, then render. /how-to/responsive-image-with-crop Add a dynamic fragment to a page that is otherwise cached A cached page is served to everyone, so per-visitor content goes in a fragment: a small uncached page, fetched after the cached one has painted, replacing a safe default. One layout, one page per fragment, and one line that turns caching off. /how-to/dynamic-fragment-on-a-cached-page Port one template from Smarty to Twig Keep the file name, change the contents. Carry escaping across one for one, translate calls second, scope assignments third, then diff the rendered page before and after. Here is one template ported end to end. /how-to/port-smarty-to-twig Show a live cart count on a cached page A cart count in a cached header is wrong for almost everyone. Leave it empty in the template, read the visitor's cart from /cdna-api/cart after load (a 404 means no cart), and re-render from the cart your own add-to-cart calls return. /how-to/live-cart-count-on-a-cached-page Serve WebP without writing a picture tag yourself Turn on Generate picture tag and every getHtml() renders a picture element with a WebP source and fallbacks, no template change. Per image, toOptimizedFormat() converts to WebP; browsers that cannot show it get the original. /how-to/serve-webp Show logged-in state on a cached page A cached page cannot know who is looking. Render the signed-out links, fetch an uncached account fragment after load, swap it in, and take the CSRF token from it for your API calls. /how-to/logged-in-state-on-a-cached-page Turn on picture tags and understand what changed in your markup One setting, and every getHtml() and every richtext image becomes a picture element: a WebP source, an original-format source, an img fallback, 2x versions when the original is large enough. Your attributes land on the img. /how-to/turn-on-picture-tags Hand-write a picture tag when automatic art direction is not enough The automatic sources choose by viewport width. When the crop must change per breakpoint, build the picture element from resized paths, take each source's type from the converted image, and use getPath(), never getHtml(), inside it. /how-to/hand-write-a-picture-tag Stop a grey placeholder appearing on production The placeholder appears for signed-in users by default, and a site member counts as signed in. Either set Show image placeholders to Never on a site with member accounts, or use getAreaImage() with an isBlank() check in templates members see. /how-to/stop-grey-placeholder Reserve layout space with the aspect ratio to avoid layout shift A resized image rendered with getHtml() gets width and height attributes automatically, which is all a browser needs. For unresized images and for wrappers, use getWidth(), getHeight() and an aspect-ratio style. /how-to/reserve-space-aspect-ratio Import a legacy site's externally hosted images during a migration Turn on Import external images, re-save the migrated records, check the file manager, and turn it off again. Every image hotlinked in rich text is copied in at its source path and the content pointed at the copy. /how-to/import-external-images Read a page with its sections and images in one request One GET with properties returns a page's name, address, layout and every layout area, with the components and image paths inside them. Read it by path, walk the collection by component layout, and take each layout area's value from the key its input type uses. /how-to/read-a-page-in-one-request Send a long properties selector in a GET body When a selector is too long for a URL, send it as the raw body of the GET, braces and all, with the header X-Body-Has-Parameters: 1. Only properties travels this way: filters, limit and orderBy stay in the query string, and a browser's fetch cannot send a GET body at all. /how-to/properties-in-a-get-body Change one area of a page without touching the rest patchRevision copies the live revision and changes only the layout areas you name. Send originRevision, the layout area as areaContent(name), and activeRevision: true inside the patch: the change goes live in one request, and every other area, collections included, stays as it was. /how-to/change-one-area Schedule a page to go live, and to come down A published date in the future schedules the go-live, and unpublishAt schedules the take-down. Send ISO dates with their offset, expect them back in UTC, and check signed out: until the date, the page answers 404 to visitors. /how-to/schedule-a-page Upload an image and place it in an area POST the file to /cdna-api/files/upload-file as multipart form data, with a folder and type=image; the answer carries the image's id. Put that id in an image area, or an image custom field, and read the layout area back for the image's path. /how-to/upload-an-image-and-place-it Connect a server integration with OAuth and keep its token fresh Register an OAuth client, sign in once as a backend user made for the integration, and keep the refresh token on the server. Refresh shortly before the four-hour access token expires, or on the 403 that says it has, and store the refresh token from every answer. /how-to/server-integration-with-oauth Sync values from another system into custom fields Read the record type's field definitions from the input types, map the other system's attributes to field names, and send only the fields that changed as customFields on the record's edit route. Fields you do not name keep their values; read the record again to see what is stored. /how-to/set-custom-fields-through-the-api Import records so that running the import twice changes nothing Keep the source system's key in externalId, look each record up by it, update when it is found and create when it is not, and build the content from the source the same way every time. A rerun on unchanged data finds every record and adds no revisions. /how-to/idempotent-import-with-external-ids Submit a Core dna form from a React or Vue front end The front end posts the visitor's answers to a route on your own server, which sends them to the form's submission API, keeps the submission token in the visitor's session, and answers with done, the errors by field, or a payment to go to. A 207 means stored but not finished: the next attempt continues it. /how-to/submit-a-form-from-react-or-vue Add the platform's form scripts to a form layout Load js-forms.js and its stylesheet with the page's nonce, wrap the steps in a .coredna-js-form container, print the form's conditionals for js-forms-conditionals.js, add js-payment-element.js for a payment, and point the container at a result callback, so a failed submission shows its errors to the visitor. /how-to/add-the-form-scripts-to-a-layout Uptime, failover and maintenance /books/performance-and-deployment/after-launch/failover-and-maintenance Porting a template set /books/template-languages/side-by-side/porting-a-template-set