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.

Hide merge commits

  1. Updated: The tutorial Migrating URLs, the feature page and the URL ma… (opens in a new window) ·
    Message
    Updated: The tutorial Migrating URLs, the feature page and the URL map examples use the migration helpers
    
    The steps of a migration now use the helpers of the import instead of shell
    commands, in English and German:
    
    - Collecting the old addresses: exp:url:from-sitemap and exp:url:from-404, and
      the tabs From the old sitemap and From the 404 log of the import screen; the
      404 log gives paths only, as it hides the values of a query
    - Building the map: exp:url:suggest and the tab Suggest targets, with
      --fill-above and the other suggestions in the note
    - Testing: exp:url:test and Test the old addresses after an import, with the
      states it reports and its exit code
    - The feature page has a section on the helpers and their commands; the
      examples show how to test a file after an import
    - Changelog 6.0.15
    43304f1d6b
  2. Updated: exp:url:test follows a redirect whose answer it stops readin… (opens in a new window) ·
    Message
    Updated: exp:url:test follows a redirect whose answer it stops reading early
    
    The test asks for no body and stops each transfer at its first bytes; curl
    then leaves the redirect address empty, so every 301 and 302 was reported as
    "not redirected" (found on alpha with pages of its own sitemap that move). The
    Location header is now read as the answer arrives and used when curl has none.
    9d746b1336
  3. Added: URL map helpers as tabs of the import screen, and a test of th… (opens in a new window) ·
    Message
    Added: URL map helpers as tabs of the import screen, and a test of the old addresses after an import
    
    The import screen of the administration gets the helpers of the console, so
    a site can be moved without a shell.
    
    - content/urlimport/(source)/sitemap: the old site's addresses from its
      sitemap (an address of a public host only: every address of the host is
      checked and the connection is pinned to it, so nothing on the server's own
      network is fetched), or an uploaded sitemap or list; /(source)/404: this
      site's 404 log, by hits, within the last days; /(source)/suggest: a map
      whose rows lack a target
    - Each with the targets suggested and filled in from a score; the map is
      downloaded as CSV to complete in a spreadsheet, or opened as an import to
      preview (rows without a target are not importable there)
    - After an import, Test requests its old addresses (the first 500) on the
      site of its siteaccess (its SiteURL), follows the redirects and lists the
      rows that did not land; the result stays with the import
    - The tabs are links with the view parameter source; forms post, nothing
      is read from the query string. Shared components and tokens only, in the
      admin4 and admin designs
    - The strings in every administration catalogue
    - The BC note in English and German, the changelog, the generated page of
      the view
    - Tests: the form of a helper, the tab addresses, the site address of the
      test and the kept results of an import, without a database
    b30c01fa63
  4. 4344c112c7
  5. 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
  6. 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
  7. 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
  8. deddf80d59
  9. 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
  10. 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

Showing 11–20 of 49 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