Jump to content

Search and Replace


Pete
 Share

Recommended Posts

I just had to do a site-wide replacement on a word this morning, so this may be of use to others in a similar situation (in my case a product name had to have a capital letter in the middle instead of lowercase).

Stick at the top of your homepage template and be careful with this - always take a database backup before playing with anything that's potentially destructive.

function searchReplace($page) {
        foreach ($page->children('include=all') as $child) {
            // Skip admin page
            if ($child->id != 2) {
                foreach ($child->template->fields as $field) {
                    $child->{$field} = str_replace('search_word', 'replacement_word', $child->{$field});
                }
                foreach ($child->children as $grandchild) {
                      searchReplace($grandchild);
                }
                $child->setOutputFormatting(false);
                $child->save();
            }
        }
    }
    searchReplace($pages->get('/');
    exit;

It essentially iterates every page under the homepage, goes through every field and replaces the search term with the replacement. It is case sensitive too.

Comment out the code when you are done and see the changes live on your site.

This might be a nice one for a quick module that only targets things like text, textarea and image/file descriptions as that's pretty much the only fieldtypes that are relevant I think. Settings could be added to skip certain pages (and therefore their children) entirely, but I don't have time for building a module at the moment.

  • Like 7
Link to comment
Share on other sites

Thanks, this can come in handy sometimes.

Perhaps modifying hte searchReplace function to accept the search-replace words would be beneficial, like this:

searchReplace($pages->get('/'), 'search_word', 'replacement_word');

Btw, your orignial searchReplace is missing one extra closing brackets I guess:

searchReplace($pages->get('/'));

  • Like 1
Link to comment
Share on other sites

Hey Pete - nice one!

I know your code is meant as a quick snippet to get the job done, so no offense intended, but the concerns I have with this is:

  • On a site with a LOT of pages, that could be very slow.
  • I don't like the fact that it re-saves every page, regardless of whether there is a change or not, which will affect the modified date and modified user.

I have actually already made a start on a feature rich search and replace module which I will get around to finishing up sometime soon. It provides the ability for searching and then showing the search term in context for each match. You can then choose which matches get replaced, or replace all.

Stay tuned!

  • Like 7
Link to comment
Share on other sites

Replace in DB is not a way to go? Either with a query or using a dump.

Absolutely and I have done that several times in the past, but I want to create a tool that can be used by your clients for site maintenance.

  • Like 1
Link to comment
Share on other sites

This was the quickest way for me to search over an unknown number of fields in an unknown number of tables (the code took 1 minute after searching for the correct way to do it in mySQL for over 5 and time is at a premium (so why am replying ;)), so yes a replace in mySQL would almost certainly be better if someone knows the best query for that (preferably search the fields table for all fields of a certain type, then update all of the tables for those fields to replace the word).

Yep - don't use this for big sites. mySQL is the way to go there but this works for smaller sites < a few hundred pages.

As for modified date and user, I can see how that might be an issue in some workflows but I've never used either myself in selectors - very much worth you mentioning it though of course. If you simply wanted to maintain the order if your pages were sorted by modified date then simply sort the child pages by modified date first before replacing your search term though if you need to maintain the same modified date and user then the replace is best done directly in SQL to bypass those being updated.

Link to comment
Share on other sites

Well the SQL command for basic replaces of the "body" field would go something like this:

UPDATE field_body SET data = REPLACE( data, 'search_word','replacement_word' )

The key thing for me when using the PW API is to limit it to just the fields and pages with matching results, rather than iterating and saving every field on every page on the site.

  • Like 1
Link to comment
Share on other sites

  • 7 months later...
  • 7 months later...
On 3/17/2015 at 0:22 AM, adrian said:

I have actually already made a start on a feature rich search and replace module which I will get around to finishing up sometime soon. It provides the ability for searching and then showing the search term in context for each match. You can then choose which matches get replaced, or replace all.

Stay tuned!

Hi Adrian,

Did your search/replace module ever see the light of day?

Link to comment
Share on other sites

13 hours ago, Marty Walker said:

Hi Adrian,

Did your search/replace module ever see the light of day?

Hey Marty,

Unfortunately I never got around to finishing it - I just took a quick look at what I have and I think that rather than being a dedicated module, it might be better to convert it to an Action for ListerPro. I know that will obviously mean that you'll need a ListerPro license, but leveraging LP's ability to perform actions on just matched pages and its built-in batching will make for a more powerful and performant tool.

  • Like 4
Link to comment
Share on other sites

  • 2 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...