Skip to content

Instantly share code, notes, and snippets.

@olafgleba
Last active November 26, 2025 20:03
Show Gist options
  • Select an option

  • Save olafgleba/1e1c33d8ad3fc22961dfba33a6ee2f36 to your computer and use it in GitHub Desktop.

Select an option

Save olafgleba/1e1c33d8ad3fc22961dfba33a6ee2f36 to your computer and use it in GitHub Desktop.
Swap multilanguage content when changing the default language in Processwire.
<?php namespace ProcessWire;
// bootstrap processwire
include("../index.php");
/****************************************************************
*
* Swap the content of multilingual fields between two languages
*
* Processwire Compatibility tested: v. 3.0.248
*
****************************************************************/
function swapMultiLanguageContent($pages, $langA = 'default', $langB = 'deutsch') {
$languages = wire('languages');
$lA = $languages->get($langA);
$lB = $languages->get($langB);
if(!$lA || !$lB) throw new WireException("Language not found");
foreach($pages as $page) {
if(!$page instanceof Page || !$page->id) continue;
$page->of(false);
/*********************
* 1) PAGE NAME SWAP
*********************/
try {
$nameA = $page->localName($lA);
$nameB = $page->localName($lB);
if($nameA !== $nameB) {
$page->set("status$langB", 1);
$page->set("name$langA", $nameB);
$page->set("name$langB", $nameA);
}
} catch(Exception $e) {
wire('log')->save('swap-lang', "Page {$page->id}: Name swap error: " . $e->getMessage());
}
/*******************************************************
* 2) ORDINARY FIELDS + REPEATER + REPEATERMATRIX SWAP
*******************************************************/
swapFieldValuesRecursive($page, $lA, $lB);
/***********
* 3) SAVE
***********/
try {
$page->save();
} catch(Exception $e) {
wire('log')->save('swap-lang', "Page {$page->id}: Save error: " . $e->getMessage());
}
$page->of(true);
}
return "Done.";
/******************************************************************
* LOGGING...
*
* Could be helpful to identify possible problems. The following
* uncommented lines are just one way to start...
*
******************************************************************/
// $logfile = fopen(wire("config")->paths->logs . "swap-multilingual-content-log.txt", "w") or die("Unable to open file!");
// $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($log));
// foreach($iterator as $key => $value) {
// fwrite($logfile, "$key => $value\n");
// }
// fclose($logfile);
}
/***********************************
* REKURSIVE Function:
* Swap multilingual values for:
*
* - ORDINARY FIELDS
* - REPEATER
* - REPEATERMATRIX
* -
***********************************/
function swapFieldValuesRecursive(Page $page, Language $lA, Language $lB) {
foreach($page->template->fieldgroup as $field) {
$fieldname = $field->name;
if(!$page->hasField($fieldname)) continue;
$value = $page->$fieldname;
// Avoid NULL
if($value === null) continue;
/******************************************
* CASE 1: MULTILINGUALES ORDINARY FIELD
******************************************/
$type = $field->type;
if($type instanceof FieldtypeLanguageInterface) {
try {
$valueA = $value->getLanguageValue($lA);
$valueB = $value->getLanguageValue($lB);
if($valueA != $valueB) {
$value->setLanguageValue($lA, $valueB);
$value->setLanguageValue($lB, $valueA);
}
} catch(Exception $e) {
wire('log')->save('swap-lang', "Field {$fieldname} error: " . $e->getMessage());
}
continue;
}
/*********************
* CASE 2: REPEATER
*********************/
if($type instanceof FieldtypeRepeater && $value->count()) {
foreach($value as $repItem) {
$repItem->of(false);
swapFieldValuesRecursive($repItem, $lA, $lB);
$repItem->save();
$repItem->of(true);
}
continue;
}
/****************************
* CASE 3: REPEATER MATRIX
****************************/
if($type instanceof FieldtypeRepeaterMatrix && $value->count()) {
foreach($value as $matrixItem) {
$matrixItem->of(false);
swapFieldValuesRecursive($matrixItem, $lA, $lB);
$matrixItem->save();
$matrixItem->of(true);
}
continue;
}
// Ignore all other field types...
}
}
/*****************************************************
* USAGE EXAMPLE
*
* 1. Collect pages array of every required template
* 2. Adapt the function arguments to your liking
*
*****************************************************/
/* 1 */
$_pages = wire('pages')->find("template=<your-template-name>");
/* 2 */
swapMultiLanguageContent($_pages, 'default', '<your-language-name>');
/**************************************************
* MANDATORY FOLLOWING STEPS
*
* After execute the function for all required pages you need to:
*
* 1. Assuming dutch is your new default language (and english was the previous one),
* download the dutch translation file, upload it to the default language and adapt the
* titles to your new default language on both languages.
*
* 2. Go to your Homepage ("/") and in the settings, adapt the url of your new default
* language and the url of your swapped language
*
**************************************************/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment