ProcessWire 3.x is a friendly and powerful open source CMS with a strong API.

Related tags

CMS php cms processwire cmf

Welcome to ProcessWire 3.x

This document is in Markdown. An HTML formatted version of this document can be read at:

Table of Contents

  1. About
  2. Installation
  3. Upgrading
  4. Troubleshooting
  5. Support

About ProcessWire

ProcessWire is a friendly and powerful open source CMS with an API that is a joy to use at any scale. It is both a content management system (CMS) and framework (CMF) built to save you time and work the way you do. With all custom fields, a secure foundation, proven scalability and performance, ProcessWire connects all of your content seamlessly, making your job fast, easy and fun.

ProcessWire gives you more control over your fields, templates and markup than other platforms, while ProcessWire’s API makes working with your content easy and enjoyable. Managing and developing a site in ProcessWire is shockingly simple compared to what you may be used to.

ProcessWire is widely trusted by web professionals for its exceptional consistency, stability and security; revered by web developers for its API that saves time and makes work fun; valued by web designers for its adaptability and flexibility with modern website/application content management needs; and loved by clients for its no-nonsense interface and ease-of-use in adding, updating and maintaining content. New versions of ProcessWire are released just about every week on the development branch.


ProcessWire is a timeless tool for web professionals that has always been committed to the long term. It started in 2003, gained the name ProcessWire in 2006, and has been in active development as an open source project since 2010. Now more than a decade later (2020), we're just getting started, as ProcessWire continues to grow and develop into the next 10 years and beyond.

While ProcessWire has been around for a long time, don’t feel bad if you haven’t heard of it till today. We are fundamentally different from other projects in that we don’t make a lot of noise, we’re not into promotion, we value quality over quantity, sustainability over growth, and a friendly community over popularity. ProcessWire is designed to be a silent partner, not easily identified from the front-end of any website. We don’t aim to be big, we are instead focused on being best-in-class.

Web developers find ProcessWire when the time is right, after they’ve tried some other platforms. And once they start using ProcessWire, they tend to stay—ProcessWire is addictive, easy to maintain for the long term, and doesn’t have the security and upgrade woes of other platforms. But don’t take our word for it; unless your livelihood depends on some other platform, find out for yourself.


ProcessWire is more than just software, it is also a friendly community of web professionals dedicated to building great sites and applications, and helping others do so too. Please visit and join our friendly community in the ProcessWire forums, subscribe to our weekly newsletter for the latest ProcessWire news, check out our website showcase to see what others are building with ProcessWire, and read our blog to stay up-to-date with the latest ProcessWire versions.

Learn more

Installing ProcessWire

Simply extract the ProcessWire files to an http accessible location and load the URL in your web browser. This will start the installer. See our Installation Guide for more details and instructions. If you run into any trouble, please see our Troubleshooting Guide.

Upgrading ProcessWire

Before proceeding with any version upgrade, please see the Upgrading ProcessWire guide and keep it open during your upgrade in case you need to refer back to it.

Upgrading from ProcessWire 3.x (earlier version)

When upgrading from one 3.x version to another, please use the General Upgrade Process. This consists primarily of making sure you've got everything backed up and then just replacing your /wire/ directory with the one from the newest version.

In addition, if you are currently running any 3.x version prior to 3.0.135, you will also want to upgrade your root .htaccess file to the newest version:

Upgrading your .htaccess file

  • If you haven't made any custom modifications to your .htaccess file then you can simply replace the old one with the new one. The new one is in a file named htaccess.txt so you'll rename it to .htaccess after removing your old one (all in the same directory as this README file).

  • If your .htaccess file does have custom modifications, you know what they are, and are comfortable applying them to the new one — go ahead and follow the step above and then make those same modifications to the new .htaccess file.

  • If you aren't sure what custom modifications your .htaccess file might have, or how to apply them to the new one, please see this post which will quickly guide you through it: How to upgrade an existing .htaccess file

If you are curious what's new in this latest .htaccess file version, please see this post for all the details.

Upgrading from ProcessWire 2.x

If upgrading from ProcessWire 2.5 or older, we recommend that you upgrade to ProcessWire 2.7 first. This version includes details in the README file on how to upgrade from that older version of ProcessWire. To upgrade from ProcessWire 2.6 (or newer) to ProcessWire 3.x, please follow the instructions below.

  1. Login to the admin of your site.

  2. Edit your /site/config.php file and set $config->debug = true; to ensure you can see error messages. This is optional but recommended.

  3. Replace your /wire/ directory and /index.php file with the new ones from here.

  4. Click a navigation link in your admin, such as "Pages". You may notice a delay. This is ProcessWire compiling 3rd party modules into a format that is compatible with version 3.x. Keep an eye out for any error messages. If you see any issues, it's possible you may need to upgrade one or more 3rd party modules. If you see messages about it applying updates, keep hitting reload in your browser until you no longer see any update messages.

  5. Once you've resolved error messages in your admin, you'll want to test out the front end of your site. Again, expect a delay while ProcessWire compiles any files to make them compatible with 3.x. Depending on your template file strategy, updates may or may not be necessary. If you run into any pages that aren't working, see the section further down on troubleshooting. Thoroughly test every aspect if your site to ensure that everything is working as you expect.

  6. When you've confirmed a successful upgrade, remember to restore the $config->debug setting back to false in your /site/config.php file.

Troubleshooting a 3.x upgrade If you run into any trouble upgrading, please see our troubleshooting upgrades guide.

Pro module upgrade notes

  • If using FormBuilder, we recommend using only v0.3.0 or newer, but v0.4.0 or newer if possible.
  • If using ProCache, we recommend using only v3.1.4 or newer.
  • If using ListerPro, we recommend using only v1.0.9 or newer.
  • If using ProFields, we recommend grabbing the latest versions in the ProFields support board.
  • If using ProCache and you upgraded your .htaccess file, you should go to your ProCache settings after the upgrade to have it update your .htaccess file again. If no upgrades to your .htaccess file are necessary, then the ProCache settings page won't mention it.

Debug Mode

Debug mode causes all errors to be reported to the screen, which can be helpful during development or troubleshooting. When in the admin, it also enables reporting of extra information in the footer. Debug mode is not intended for live or production sites, as the information reported could be a problem for security. So be sure not to leave debug mode on for any live/production sites. However, we think you'll find it very handy during development or when resolving issues.

  1. Edit this file: /site/config.php
  2. Find this line: $config->debug = false;
  3. Change the false to true, like below, and save.
$config->debug = true; 

This can be found near the bottom of the file, or you can add it if not already there. It will make PHP and ProcessWire report all errors, warnings, notices, etc. Of course, you'll want to set it back to false once you've resolved any issues.

Support and Links

Copyright 2020 by Ryan Cramer / Ryan Cramer Design, LLC

  • WebP Support for PW Core Engines

    WebP Support for PW Core Engines

    @ryancramerdesign Hi Ryan, here is the webP support for PW core image engines. Please refer to this forums post for some explanation:

    If you like, we can discuss it here or you can contact me via PM or email ([email protected]).

    opened by horst-n 28
  • Allow modules to add exclusions to FileCompiler

    Allow modules to add exclusions to FileCompiler

    This change allows you to add fileCompilerExclusions to a module's info array. This is useful for those who have vendor and lib directories in their modules that may break after being compiled.


    opened by mikerockett 28
  • Add a separate Save, Close & Add button to the

    Add a separate Save, Close & Add button to the "create a new field" link on the templates page.

    This allows for full configuration of fields that require more than two saves, such as FieldtypeOptions.

    opened by adrianbj 24
  • XXE Vulnerability

    XXE Vulnerability

    When getting an image file's information, the program does not care about XXE vulnerability, which could lead to sensitive information leakage or DoS attack. In Pageimage class(wire\core\Pageimage.php), function getImageInfoSVG parses file without any sanitation ,whose content may contain attack vectors.

    	protected function getImageInfoSVG($filename = '') {
    		$width = 0;
    		$height = 0;
    		if(!$filename) $filename = $this->filename;
    		$xml = @file_get_contents($filename);
    		if($xml) {
    			$a = @simplexml_load_string($xml)->attributes();
    opened by dahua966 18
  • Fix bug when cropping images

    Fix bug when cropping images

    opened by esl51 12
  • enable file metadata in repeater context

    enable file metadata in repeater context

    even when file/image was freshly created via Ajax call. fix

    opened by gerritvanaaken 11
  • Cross-Site Scripting v1.3.6

    Cross-Site Scripting v1.3.6

    Affected software : Processwire CMS

    Version : v.1.3.6

    Type of vulnerability : XSS (Cross-Site Scripting)

    Author : Noth

    Processwire CMS is susceptible to cross-site scripting attacks, allowing malicious users to inject code into web pages, and other users will be affected when viewing web pages

    PoC :

    Step 1 : login system 1

    Step 2 : Go to "/processwire/page/edit/?id=1" 2

    Step 3 : insert "XSS" test grammar in "Titile" and save it. XSS Payload : "> 3

    Step 4 : Go back to the login system page 4

    Test Video :

    opened by zxc7528064 11
  • fix inputfields not toggling on header clicks

    fix inputfields not toggling on header clicks

    This PR fixes an old and annoying bug:

    Before: bug

    Its a little hard to see, but the following happens:

    • opened inputfield: arrow blinks
    • collapsed inputfield: toggles correctly
    • ajax: opens correctly, blinks instead of closing

    This is really bad UX because the Inputfield behaves in 3 different ways to the same action (click header)!

    After: fix

    With this fix in place all inputfields toggle correctly on the first click on the header. It just does the click on the icon automatically instead of flashing it!

    opened by BernhardBaumrock 11
  • $page->setAndSave does not work with array as parameter

    $page->setAndSave does not work with array as parameter

    It seems like setAndSave shortcut method does not play well with an array of fields unput.

    This code does not work:

        'next_action' => 'JustTest',
        'next_action_time' => time() + 12 * 3600,

    This one does:

        'next_action' => 'JustTest',

    and this one too (of course):

    $of = $page->of();
    $page->next_action = 'JustTest';
    $page->next_action_time = time() + 12 * 3600;

    Or I messed something up)

    opened by ivangretsky 10
  • added support for CLI

    added support for CLI

    without that, PHP throws notices when try to access the $_SERVER['REMOTE_ADDR'], because it is not set in CLI-Environment.

    opened by horst-n 10
  • add $files->url() and $files->path()

    add $files->url() and $files->path()

    hey @ryancramerdesign

    What do you think of this addition to WireFileTools? It's an old request from 2019 and I keep stumbling over it again and again. Lately jens had a similar need that would also be obsolete if we had $files->url() and $files->path()

    My original request used $config->url() and $config->path() syntax but I had a look at the config class and it already has such methods. That's why I added the feature to the WireFileTools which have no similar methods and should therefore not add any problems or confusion!

    This is what I used for testing:

    echo "### url() ###";
    echo "### path() ###";


    ### url() ###
    ### path() ###
    opened by BernhardBaumrock 1
  • Fix: WireCache output buffer not closed

    Fix: WireCache output buffer not closed

    This PR fixes an issue with WireCache when you use a cache-function, that could throw exceptions.

    Here is a short example-code to explain the problem:

    class MyModule extends WireData implements Module
      private function getCache() {
        $this->log(__FUNCTION__ . ': ob-level (start): '. ob_get_level());
        try {
          $this->log(__FUNCTION__ .': ob-level (before-cache): '. ob_get_level());
          $items = $this->cache->getFor($this, 'my-cache',WireCache::expireHourly,
            function() {
              $this->log('Cache-Func: ob-level (in-callback): '. ob_get_level());
              // a function, that could throw exceptions
              $items = externalFunction();
              return $items;
          $this->log(__FUNCTION__ . ': ob-level (after-cache): '. ob_get_level());
        } catch (\RuntimeException $e) {
          // Catch and handle exceptions
          $this->log(__FUNCTION__ . ': ob-level (on error): '. ob_get_level());
        $this->log(__FUNCTION__ . ': ob-level (final): '. ob_get_level());
        return $items;

    Short description of the issue:

    When you run this code, getFor() will call ob_start() in function WireCache::renderCacheValue() before executing the function we passed into getFor.

    In normal cases, this output buffer will be closed after the function call, and the outputs will be returned.

    But in case the users-function throws an exception, the buffer closing is not called. That means each time I run this call one more buffer is opened and not closed, what causes strange effects in later code (specially, when you use it multiple times in a loop).

    Expected behavior

    ob Cache level before calling getFor() should show the same level like after calling getFor(). I mean, each output buffer that was opened, should be closed.

    Outputs that demonstrate the issue

    normal behavoir

    getCache: ob-level (start): 2
    getCache: ob-level (before-cache): 2
    Cache-Func: ob-level (in-callback): 3
    getCache: ob-level (after-cache): 2
    getCache: ob-level (final): 2

    with Exception

    getCache: ob-level (start): 2
    getCache: ob-level (before-cache): 2
    Cache-Func: ob-level (in-callback): 3
    getCache: ob-level (on error): 3
    getCache: ob-level (final): 3

    Suggestion for a possible fix (contents of this pull-request)

    • use finally to ensure that buffer is closed even in case of exceptions

    p.s. min. required php version in composer.json must be increased to 5.5 if we use finally

    opened by Radon8472 1
  • Modify parsing pattern for LanguageParser to include references preceeded by either a comma or an associative array

    Modify parsing pattern for LanguageParser to include references preceeded by either a comma or an associative array

    __('phrase') , _x('text', 'context', textdomain) and _n('singular text', 'plural text', $cnt, textdomain) now will also be parsed if they are preceeded either by a comma or an => as part of an associative array

    This would fix processwire/processwire-issues#1488

    opened by Tyde 0
  • Add links to quickly edit a file in other languages

    Add links to quickly edit a file in other languages

    When editing translations, this adds links to the other language versions of the file.

    Before: grafik

    After: grafik

    Without these links, the workflow to edit a translation in another language is very cumbersome and takes 4 clicks plus some searching:

    • click on Languages
    • choose your language
    • choose the file
    • click on edit
    opened by MrSnoozles 1
  •  In the last screen of the installer, show a warning if the site isn’t reachable

    In the last screen of the installer, show a warning if the site isn’t reachable

    Over the years there have been several forum threads from people unable to access anything but the frontpage after installing ProcessWire. Depending on the environment, some .htaccess settings may need to be adjusted, or, as in this most recent case, .htaccess does't run at all. I reproduced the latter problem to test this PR. Indeed a fresh install of Apache needs some config to get started with PW. In the thread the OP pointed to ProcessWire's installer finishing without errors and telling them they were good to go, although this wasn't the case. This PR is a suggestion to make the installer give a hint in cases like this.

    As I say in the commit message, perhaps it would be better to do this sort of check in Javascript. Using WireHttp might fail because fopen isn't available or something, so the error may end up being a false positive.

    In any case, I think something like this might help people. As I observe in the thread, it may also be worth considering to change some check marks to something else. They kind of give the impression that the item has already been done for you, although they are really things you should definitely do next.

    As always, thanks for your attention and for PW!

    opened by JanRomero 0
  • Update ProcessField.module

    Update ProcessField.module

    Spelling mistake

    opened by andy-scboy 0
  • add lang-edit permission during multi-lang installation

    add lang-edit permission during multi-lang installation

    When LanguageSupport/LanguageTranslator/ProcessLanguage are installed Processlanguage also install the 'page-edit' translation. This does not happen during multilang profile installaton despite the fact that ProcessLanguage is marked as installed. I am not sure about the correct, I used 1008 as there was a gap in the autoincrement.

    opened by pine3ree 0
  • Allow runtime accessors as language tab labels

    Allow runtime accessors as language tab labels

    Currently, the labels of language tabs can be configured from the LanguageTabs module screen. However, it only allows selecting existing fields. There's no way of using 'dynamic' fields defined as runtime accessors on a custom LanguagePage class.

    Modifying $config->LanguageTabs['tabField'] doesn't work since the label field is queried at runtime from the module config at $this->tabField. This PR changes that behavior to query the label field from the previously merged settings ($config->LanguageTabs + module config). The module will behave the same since the default value for the tabField setting is the module config value anyway. Only when $config->LanguageTabs is modified directly will this have precedence.


    Language pages have a runtime accessor label that outputs the language name, translated to the language itself: E.g. Deutsch, Français, Italiano, instead of German, French, Italian.

    // site/classes/LanguagePage.php
    class LanguagePage extends Language
        public function get($key)
            if ($key === 'label') {
                return $this->getLanguageValue($this, 'title');
            return parent::get($key);

    We cannot use that accessor as the tab label field since it's not an actual field. So we manually modify the module config. This will work with the code changes from this PR.

    // site/init.php
    // Use custom runtime-value language tab label
    // Setting this here instead of in site/config.php to overwrite the default AdminThemeUIkit config
    $config->set('LanguageTabs', [
        'tabField' => 'label'
    ] + ($config->LanguageTabs ?? []));

    Alternative solutions

    1. Add another config field like customTabField
    2. Make the tab label hookable

    I thought the one-line change makes more sense as long as it doesn't affect current setups (which from my testing it doesn't).

    opened by daun 1
  • add skip-label configuration option for inputfield wrappers

    add skip-label configuration option for inputfield wrappers

    This option let us group/wrap different fields without annoying and/or redundant headers/labels

    opened by pine3ree 5
ProcessWire is an open source API-driven CMS and web application framework aimed at the needs of designers, developers and their clients.
The simple, flexible and friendly ASP.NET CMS used by more than 500.000 websites

Umbraco CMS · Umbraco is the friendliest, most flexible and fastest growing ASP.NET CMS, and used by more than 500,000 websites worldwide. Our mission

Umbraco HQ 3.5k Jan 18, 2022
Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS

Grav Grav is a Fast, Simple, and Flexible, file-based Web-platform. There is Zero installation required. Just extract the ZIP archive, and you are alr

Grav 13.1k Jan 20, 2022
The most powerful headless CMS for Node.js — built with GraphQL and React

A scalable platform and CMS to build Node.js applications. schema => ({ GraphQL, AdminUI }) Keystone Next is a preview of the next major release of Ke

KeystoneJS 5.6k Jan 15, 2022
Simple and powerful Ruby on Rails CMS for developers

?? Simple and powerful Ruby on Rails CMS for developers ?? APIQ is a modern and flexible Ruby on Rails content management system with modular approach

APIQ 336 Oct 14, 2021
ComfortableMexicanSofa is a powerful Ruby on Rails 5.2+ CMS (Content Management System) Engine

ComfortableMexicanSofa ComfortableMexicanSofa is a powerful Ruby on Rails 5.2+ CMS (Content Management System) Engine Features Simple drop-in integrat

Comfy Projects 2.7k Jan 6, 2022
Add content management functionality to any site - plug & play / headless / api-first CMS

Cockpit Next Homepage: Twitter: @getcockpit Support Forum: Requirements PHP >= 7.3 PDO + SQLite

Agentejo 5.2k Jan 16, 2022
ApostropheCMS is a full-featured, open-source CMS built with Node.js that seeks to empower organizations by combining in-context editing and headless architecture in a full-stack JS environment.

ApostropheCMS ApostropheCMS is a full-featured, open source CMS built with Node.js that seeks to empower organizations by combining in-context editing

Apostrophe Technologies 3.8k Jan 19, 2022
🚀 Open source Node.js Headless CMS to easily build customisable APIs

API creation made simple, secure and fast. The most advanced open-source headless CMS to build powerful APIs with no effort. Try live demo Strapi is a

strapi 42.3k Jan 12, 2022
Free, open-source, self-hosted CMS platform based on the Laravel PHP Framework.

October is a Content Management System (CMS) and web platform whose sole purpose is to make your development workflow simple again. It was born out of

October CMS 10.8k Jan 14, 2022
Open Source Digital Experience Platform (DXP, MDM/PIM, CDP, DAM, CMS/UX & eCommerce

Pimcore - Open Source Digital Experience Platform: MDM/PIM, CDP, DAM, CMS/UX & eCommerce ?? Website - Learn more about Pimcore ?? Documentation ?? Hel

pimcore 2.4k Jan 22, 2022
Subrion CMS - open source php content management system.

Subrion CMS What is Subrion? Subrion is a Content Management System (CMS) which allows you to build websites for any purpose. Yes, from blog to corpor

Intelliants 267 Oct 15, 2021
Simple Open-Source CMS for designers

A simple open-source CMS for designers. No knowledge of PHP required at all. Take any HTML/CSS template and make it CMS enabled in minutes. Just drop

CouchCMS 298 Jan 5, 2022
Contao Open Source CMS

About Contao is a powerful open source CMS that allows you to create professional websites and scalable web applications. Visit the project website fo

Contao 219 Jan 21, 2022
Free, open-source, self-hosted CMS platform based on the Laravel PHP Framework.

Winter is a Content Management System (CMS) and web platform whose sole purpose is to make your development workflow simple again

Winter CMS 824 Jan 19, 2022
Open Source multi-language/multi-currency/multi-store E-commerce platform for Ruby on Rails with a modern UX, PWA frontend, REST API, GraphQL, several official extensions, and 3rd party integrations.

Spree Commerce Success Stories Documentation Integrations Spree is a complete open source e-commerce solution built with Ruby on Rails. It was started

Spree Commerce 11.6k Jan 22, 2022
Open-Source Data Platform 🐰 — Directus wraps any SQL database with a real-time GraphQL+REST API and an intuitive app for non-technical users.

?? Introduction Directus is a real-time API and App dashboard for managing SQL database content. Free & open-source. No artificial limitations, vendor

Directus 13.5k Jan 21, 2022
Yclas Self Hosted is a powerful script that can transform any domain into a fully customizable classifieds site within a few seconds.

Yclas 4.1.0. Description Yclas self-hosted is a powerful script that can transform any domain into a fully customizable classifieds site within a few

Yclas 289 Jan 7, 2022