Skip to the content
Documentation

Help center

Help for Developers

Build on it: extensions, templates, settings, the APIs, the command line and upgrades.

5997 pages

Start here

Read these pages in this order.

  1. Develop with Git: grow from user to developer The recommended way to build websites with Exponential. Install the kernel and every se7enxweb extension as...
  2. Extension development: the book (start here) A complete book on growing from user to builder, extension developer and theme developer with Exponential:...
  3. Add a database table A migration that creates a table of the site's own on every engine from a share/db_schema.dba definition, w...
  4. AI, agents and agentic: start here The landing page for people who use AI with Exponential and for people who build agents and agentic workflo...
  5. Ecosystem: start here The landing page for the Exponential Ecosystem - the greater Exponential world within the PHP stack, its us...
  6. Integrators: start here The landing page for system integrators and integration developers who connect Exponential with CRM, ERP, P...

Good to know

  • Migrations

    The start of everything about migrations in Exponential 6.0.15 - schema and content changes written once as files under version control and applied to every installation of a site in the same order, with a caption…

  • Migrations: a first PHP migration, step by step

    In this tutorial you write two PHP migrations for a site: one creates a table exp_news_note with a first row, the other publishes a folder "News" below the content root and notes it in the table. You check them, look at…

  • Add a database table

    A migration that creates a table of the site's own on every engine from a share/db_schema.dba definition, writes a first row, and drops it again in down() - with the dry run, the run, the checks and the rollback.

  • Testing migrations: check, simulate, diff and CI

    Four layers of tests for migrations - the lint without a database, the dry run, the simulation with a diff on PostgreSQL or SQLite, and a PHPUnit test on a throwaway SQLite database - and how to run them in CI.

  • Deploying with migrations: CI/CD and GitHub Actions

    Run migrations as part of every deploy - the order of the steps, a complete GitHub Actions workflow that checks pull requests and deploys over SSH, the exit codes a pipeline acts on, the installation lock, and runs…

  • Team workflow with git: branches, conflicts and order

    How several developers write migrations on branches without stepping on each other - timestamps and order, requires for real dependencies, two migrations with the same timestamp, rebasing, renaming only before a merge…

Search by topic

Each button lists the pages of one topic for Developers.

What changed in the source code most recently: the main branch of se7enxweb/exponential, read from its public feed by this server.

Show merge commits too

  1. Added: Documentation of the URL map helpers in the BC note, the chang… (opens in a new window) ·
    Message
    Added: Documentation of the URL map helpers in the BC note, the changelog and the generated command pages
    
    - The BC note "URL map import and export" has the section "Helpers for
      moving a site": what exp:url:from-sitemap, exp:url:suggest, exp:url:from-404
      and exp:url:test do, that the 404 source is the not-found log the kernel
      already writes (no new log or table), the limits of the requests, and the
      contract they follow; also in German
    - The changelog of 6.0.15 has the helpers and the PathPrefix fix of URL map
      targets
    - The generated pages of the four commands in English and German, the
      changed option help of the other exp:url commands, and the module view
      pages of the URL map screens generated again from their sources
    67868df148
  2. Added: URL map helpers: from an old sitemap, from the 404 log, sugges… (opens in a new window) ·
    Message
    Added: URL map helpers: from an old sitemap, from the 404 log, suggested targets, and a test against the site
    
    Four helpers around exp:url:import for moving a site: start a map from the old
    site's addresses, fill in the new ones, and check after the import that every
    old address lands where it should.
    
    - exp:url:from-sitemap and expUrlMapSitemapSource: a sitemap, a sitemap
      index with the sitemaps it names (relative ones too), gzip-compressed, or a
      crawl list with one address per line; only the sitemap's host unless
      --only-host or --any-host, every address once, --limit; XML read without
      the network and never with a DOCTYPE, malformed XML read for its 
      elements with a warning
    - exp:url:suggest and expUrlMapSuggester: for every row without a target,
      the visible pages of the siteaccess scored from 0 to 100 by their URL alias
      and name against the old address (decoded, camelCase split, transliterated,
      endings such as .html and index pages dropped, words that differ only in an
      ending count most of a match); --fill-above writes the best one into
      new_url (never a tie), the others go into the note or --report. Targets are
      written as visitors use them (without the PathPrefix). The pages are
      indexed once by word: 4,811 old addresses against 4,496 pages take seconds
    - exp:url:from-404 and expUrlMap404Source: the addresses of the not-found log
      (404.log and its rotated and gzip files) or of web server access logs, the
      most asked first, with --min-hits and --since; assets, bots and methods
      other than GET and HEAD left out; a query the log hides is dropped
    - exp:url:test and expUrlMapTester: every old address requested on --base,
      several at a time, the redirects followed hop by hop: landed, wrong-status
      (a permanent redirect where a temporary one is asked, or the other way),
      wrong-target, not-redirected, error (no answer, a loop, too many redirects);
      wildcards tested with a sample, node targets by the node's address, the
      PathPrefix taken as…
    c9118c9eeb
  3. Updated: Expiring the wildcard cache removes its index, so a new wild… (opens in a new window) ·
    Message
    Updated: Expiring the wildcard cache removes its index, so a new wildcard answers at once
    
    Expiring the wildcard cache only moved its expiry timestamp. An index
    built in the same second still counted as current, and a PHP-FPM worker
    whose OPcache held the previous expiry.php kept the old index for up to
    opcache.revalidate_freq seconds: right after an import made in the
    administration, a new wildcard answered 404 for a while. The index file
    is now removed as well, as the cache of the redirects already is, and
    the next request builds it again.
    7caccc0a69
  4. Updated: A wildcard or redirect added or removed answers at once inst… (opens in a new window) ·
    Message
    Updated: A wildcard or redirect added or removed answers at once instead of after a minute
    
    The wildcard cache and the cache of the redirects are PHP files written
    again under the same name. OPcache kept serving the old copy until
    opcache.revalidate_freq passed (60 seconds on alpha's PHP-FPM), so right
    after an import, an undo or a wildcard made by hand the old addresses
    still answered as before for up to a minute. Reading either cache now
    drops the cached copy when the file is newer than it (one stat per
    request, nothing when OPcache is off).
    9ce358c12c
  5. Added: Documentation of URL map import and export, a tutorial for mig… (opens in a new window) ·
    Message
    Added: Documentation of URL map import and export, a tutorial for migrating URLs and example files
    
    How to keep the old addresses of a site working after a move to Exponential,
    in English and German:
    
    - The feature page Importing and exporting URL maps: the formats, the kinds
      and statuses, query-string redirects, the preview and its states, undo,
      export, the administration screens, the policies and the console commands
    - The help-center tutorial Migrating URLs, step by step: collect the old
      addresses from the old sitemap or the web server's 404s, build a mapping
      file, import it with a preview and a dry run, test the old addresses, undo
      an import, and export for the web server or a backup
    - URL map examples: small mapping files in CSV, JSON, Apache and nginx
      format, one with query-string and temporary redirects and one with
      wildcards, each planned with exp:url:import --dry-run with every row new
    - Updated: the glossary has URL map, query-string redirect and temporary
      redirect; the URL translator and wildcards pages of the help and the user
      manual, the import and export tools table, the guides, the specification
      and the BC note link to the new pages; the indexes list them
    - Changelog 6.0.15
    7e95a4b2d7
  6. Updated: URL map targets resolve as the siteaccess serves them, below… (opens in a new window) ·
    Message
    Updated: URL map targets resolve as the siteaccess serves them, below its PathPrefix
    
    A target path of a URL map row is the address a visitor uses. On a siteaccess
    with a PathPrefix (site.ini [SiteAccessSettings]) the page /recipes is stored
    as /fit-healthy/recipes, so a row "/about-us.html,/recipes" was planned as a
    broken target although the page answers at /recipes.
    
    - The planner looks a target path up below the PathPrefix of the row's
      siteaccess first (not when its first element is one of PathPrefixExclude[],
      as storing an alias does), then as it is, so a path written with the prefix
      or one outside it still resolves; a row of every siteaccess has no prefix
    - The export writes a URL alias stored below the prefix of the siteaccess
      (the -s filter, else the default siteaccess) the way visitors use it,
      without the prefix and with that siteaccess in its column, so importing the
      file again stores it at the same place
    - expUrlMapKernelEnvironment::unprefixedPath() and pathPrefix()
    - Test: targets and the export form below a PathPrefix, without a database
    a95101d160
  7. Added: Import, export, history and undo of URL maps in the administra… (opens in a new window) ·
    Message
    Added: Import, export, history and undo of URL maps in the administration
    
    The URL translator and the wildcards get the screens for URL maps, in the
    admin4 and admin designs:
    
    - Import a URL map (content/urlimport): a file uploaded or pasted, its
      format found or chosen, the siteaccess and language of bare paths, the
      conflict policy and the old hosts. The preview lists every row with its
      state as a filter (new, changed, unchanged, duplicate, conflict, broken
      target, unknown host, not importable), a tick for each row that can be
      imported, unknown hosts mapped to a siteaccess and the file planned
      again, a dry run that writes nothing, the plan as CSV or JSON, and the
      import as one batch. The file and the plan stay on the server for the
      user who uploaded it, at most a day (expUrlMapImportSession); the forms
      post only the decisions of the rows shown, never the plan.
    - Import history (content/urlimporthistory): every import with who, when,
      the file, the counts and the state; one import's entries a page at a
      time, and Undo, which lists the entries changed since the import and
      keeps them unless ticked (expUrlMapImporter::changedSince()).
    - Export (content/urlexport) as a download in every format, and the list
      of redirects with a query or a status (content/urlredirects), with
      removing one or the ticked ones.
    - The policy function content/urltranslator_import for importing and
      undoing; the export and the redirects stay under content/urltranslator.
      Importing and undoing ask "Verify it's you" ([ReauthGroup_system]).
    - Buttons Import, Export, Import history and Redirects on the URL
      translator and the wildcards pages, shown by policy.
    - The wildcard pages show a temporary forward wildcard as "Temporary
      redirect (302)" instead of "Undefined", and the filter Redirecting
      lists both forward types (eZURLWildcard::fetchFilteredList() takes a
      list of types).
    - The strings in every administration catalogue, the context help, the
      guide "URL maps:…
    2d794ad83a
  8. Updated: Redirects of URL map imports answer for any old address, and… (opens in a new window) ·
    Message
    Updated: Redirects of URL map imports answer for any old address, and aliases follow the PathPrefix
    
    Found by importing a test map on a site whose siteaccess has a PathPrefix:
    
    - A redirect of exp_url_redirect runs the error module, as a moved URL alias
      or wildcard does, so an old address that is no module of the site (most of
      them) redirects instead of answering 404
    - A URL alias imported for a siteaccess with a PathPrefix is stored below the
      prefix, unless PathPrefixExclude[] names its first element, which is where
      the siteaccess looks it up; the page conflict check looks there too
      (expUrlMapEnvironment::aliasPath())
    - The BC note and the changelog say so; planner tests for the prefix
    aee5f8721a
  9. Updated: URL map commands and temporary folders follow the kernel rules (opens in a new window) ·
    Message
    Updated: URL map commands and temporary folders follow the kernel rules
    
    - The spreadsheet classes make their temporary folder with eZDir::mkdir(),
      so it gets the installation's directory mode
    - The exp:url commands' shared base has the run() every kernel command has
    - The wildcard pages keep their texts: the badge of the temporary forward
      wildcard comes with the administration's URL map screens, together with
      its translations in every admin catalogue; the changelog says so
    add21407bc
  10. Added: Import, export and undo of URL maps, and redirects checked on … (opens in a new window) ·
    Message
    Added: Import, export and undo of URL maps, and redirects checked on the full request
    
    The second part of importing and exporting the URL translator and the URL
    wildcards. A URL map is planned row by row, imported as one batch that can be
    undone, and exported again in every format; what a global URL alias cannot
    hold goes into a new table of redirects that is checked before the aliases.
    
    - exp_url_redirect and expUrlRedirect: redirects checked once per request on
      the address asked for, before the URL aliases and wildcards (in the kernel's
      request loop, so also under Velocity): an old address with a query (the
      order of its parameters ignored), a temporary status (302, 303, 307) or
      308, a target with a query or on another site; per siteaccess or for all;
      node targets follow the node; the old query is not carried over. Read from
      a cache file beside the wildcard cache, reset per request
    - expUrlMapPlanner and expUrlMapPlan: every row classified as new, unchanged,
      changed, duplicate, conflict (a page's own address, a module address, the
      front page), broken-target, unknown-host or not-importable, with where it
      goes, the siteaccess from the host through the siteaccess matching (or a
      mapped old host), the language, per-row decisions and a JSON or CSV report
    - expUrlMapImporter: applies a plan in one transaction with the conflict
      policy skip or overwrite, records every row it writes before and after in
      exp_urlmap_batch and exp_urlmap_batch_item, and undoes a batch exactly (rows
      changed since are kept unless forced); clears the caches; audit events
      content.urlalias.import and content.urlalias.import_undo
    - expUrlMapExporter: global URL aliases (optionally the aliases of nodes),
      wildcards and redirects as rows for every writer; an export imported again
      is unchanged
    - Commands exp:url:import, exp:url:export, exp:url:batches, exp:url:undo;
      the upgrade step 6.0.15-url-map with the tables in the kernel schemas and
      the 6.0.15 update files
    - A te…
    9abefc5714

Showing 11–20 of 40 commits

Recently updated

Free documentation: use it to help yourself and others

This help is free documentation, licensed under the GNU Free Documentation License 1.3 or later. You may use it, share it and improve it:

  • Study it Read any page as often as you like, for any purpose.
  • Copy it and share it Give pages to other users, on paper or as files. Keep the copyright notice, the license notice and a copy of the license with every copy.
  • Translate, adapt and improve it Share your version under the same license, with the original notices and a note of what you changed.
  • Cite it Refer to a page by its title and its address in the help, or its file in the doc directory.
  • Contribute fixes back Use "Edit on GitHub" on any page. Changes are accepted under the same license, so they stay free for everyone.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x