Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProcessWire > 2.6.4: issues with PageLinkAbstractor in multilanguage environment #1283

Closed
processwired opened this issue Jul 6, 2015 · 8 comments

Comments

@processwired
Copy link

Test case:

  • Install "Page Link Abstractor" module (https://github.com/ryancramerdesign/PW2-PageLinkAbstractor)
  • Set up two languages
  • Set up a multilanguage textarea field (TextareaLanguage), configure it to use CKEditor, assign it to a template
  • Create a new page with this template
    Problem: If an image is added to the first language textarea field, the content of the second language textarea field vanishes after saving. Issue came up with commit 690821d (ProcessWire > 2.6.4); before that, everything was fine.
@ryancramerdesign
Copy link
Owner

PageLinkAbstractor has been deprecated (and no longer in the modules directory) since 2.5, as the functionality is now built into the Textarea field (by choosing one of the Content Type options: Markup or Markup with Images, on the details tab). If possible, unininstall PageLinkAbstractor and use the core built-in functionality. But this might be a pain if you've got a lot of links that were managed by it, as the markup would need to be adjusted. If that's the case, let me know and I can suggest a way to convert them from the API side.

@tbba
Copy link

tbba commented Jul 19, 2015

Interesting to read that PageLinkAbstractor is depreceated. Maybe I overlooked some information there - can't remember having read about this.

PageLinkAbstractor is one of the modules I always installed. I like what it does and it shows it's importance that the functionality somehow became now part of the core. I am pretty sure a lot of people used this module.

Can I simply de-install PageLinkAbstractor without loosing information? From what you write, not.
I would love to see a way to do a conversion via API to have a proper update path.

(And also I would like to receive information right in time in case a module like this is deprecated so suddenly and replaced so I have a chance to wait with a core update or take other precautions.)

@processwired
Copy link
Author

Dear Ryan, I use this module in quite a lot of projects and would be very glad if you could advise how to convert the links from API side. I can't say if too often: big thanks for this great framework and your support efforts.

@ryancramerdesign
Copy link
Owner

I don't have a site to test this on, so am just writing in the browser, and if you try this, make sure to try it on a test scenario before a production one. But the process is to take the abstracted URLs and convert them back to the original URLs, for any fields where you've used it. Then when you save the page, it should update them to use the new abstraction automatically.

  1. Enable the Content type: 'HTML Markup' or 'HTML Markup with images' option in your textarea field you want to apply this to.
  2. Uninstall the PageLinkAbstractor module.
  3. Paste the code into a template file (may have typos and/or require adjustments). Update the value of $fieldName to be the same as the field name you want to update.
echo "<pre>";
$fieldName = 'body';
// replace {~root_url} references
$items = $pages->find("$fieldName%=root_url, limit=300"); 
foreach($items as $item) {
  $item->of(false);
  $value = $item->get($fieldName); 
  if(strpos($value, '{~root_url}') === false) continue; 
  $value = str_replace('{~root_url}', $config->urls->root, $value);
  $item->set($fieldName, $value);
  $item->save($fieldName); 
  echo "\nUpdated root_url reference on page $item->path";
}
// replace {~page_123_url} references
$items = $pages->find("$fieldName%='page_', limit=300");
foreach($items as $item) {
  $item->of(false);
  $value = $item->get($fieldName); 
  if(!preg_match_all('/\{~page_(\d+)_url\}/', $value, $matches)) continue;
  foreach($matches[1] as $key => $pageID) {
    $linkedPage = $pages->get((int) $pageID);
    if(!$linkedPage->id) {
      echo "\nUnable to find page: $pageID";
      continue; 
    }
    $value = str_replace($matches[0][$key], $linkedPage->url(), $value);
    $page->set($fieldName, $value);
    $page->save($fieldName);
    echo "\nUpdated link for page $item->path linking to $linkedPage->path";
  }
}
echo "</pre>";
  1. View a page using that template. It only operates on 300 pages at a time, so keep reloading the page until it no longer reports any updates.

@ryancramerdesign
Copy link
Owner

Btw, I also recommend enabling the PagePathHistory module, which is what handles the situation where linked page URLs change. This is preferable to what PageLinkAbstractor did because it also accounts for the situation of external URLs linking into your site.

@tbba
Copy link

tbba commented Jul 25, 2015

Thanks a lot for the migration code!! Playing with it gave me this:

  • It needs to be as the last thing in the template code, right at the bottom, or I can have a fatal error (page not completely loaded)
  • It seems not to save anything when visiting the page as logged-in superuser in frontend, since when I reload the page I expect the log list to be empty (links fixed) but I see an unchanged list.
  • The broken links checker does not show less errors after running this code against a field.

Cache is off

By the way: I put this code around it so that guests cannot see what I am doing:
if ( ( $user->id) && ( $user->isSuperuser() ) ) { }

@processwired
Copy link
Author

Dear Ryan, thanks a lot! I tried out the code as well. The last loop needs a small correction:

$page->set($fieldName, $value);
$page->save($fieldName);

has to be:

$item->set($fieldName, $value);
$item->save($fieldName);

With that fix it's working great! I slightly modified the code so I can use it from the command line by bootstrapping ProcessWire. My entire code:

<?php

include './index.php';

$pages = wire()->pages;
$config = wire()->config;

$fieldName = 'body';

// replace {~root_url} references
$items = $pages->find("$fieldName%=root_url, include=all");
foreach ($items as $item) {
    $item->of(false);
    $value = $item->get($fieldName);
    if (strpos($value, '{~root_url}') === false) {
        continue;
    }

    $value = str_replace('{~root_url}', $config->urls->root, $value);

    $item->set($fieldName, $value);
    $item->save($fieldName);

    echo "\nUpdated root_url reference on page $item->path";
}


// replace {~page_123_url} references
$items = $pages->find("$fieldName%='page_', include=all");
foreach ($items as $item) {
    $item->of(false);
    $value = $item->get($fieldName);

    if (!preg_match_all('/\{~page_(\d+)_url\}/', $value, $matches)) {
        continue;
    }

    foreach ($matches[1] as $key => $pageID) {
        $linkedPage = $pages->get((int)$pageID);
        if (!$linkedPage->id) {
            echo "\nUnable to find page: $pageID";
            continue;
        }

        $value = str_replace($matches[0][$key], $linkedPage->url(), $value);

        $item->set($fieldName, $value);
        $item->save($fieldName);

        echo "\nUpdated link for page $item->path linking to $linkedPage->path";
    }
}

@tbba
Copy link

tbba commented Jul 25, 2015

The fix worked....somehow. - I could restore some of the links easily.
Some remained links appear urlencoded, example:
<a href="%7B~page_1223_url%7D">
Not sure this to do with this script or maybe because of some other plugin...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants