Jump to content
j00st

[SOLVED] Generate copy of Title Field (with content) for multiple pages?

Recommended Posts

Hi all! 

I've been searching/browsing a bit, but can't find what I'm looking for just yet...
Perhaps I'm searching in the wrong places, but I thought posting it here might work better/more efficient.

I need to do the following;

1. I have the TITLE field (the one set by ProcessWire as default).
2. There's already a whole lot of pages of the template 'project' set up.
3. Now I actually want to be able to add <i> and <br> tags to this title...which is possible if I turn off the specialchar encoder...
...but it also presents the opportunity for people to start typing, and generate the following kind of URLs:

TITLE: This is a really long title <br> which <i>needs</i> to be split in two
URL generated: this-is-a-really-long-title-br-which-i-needs-i-to-be-split-in-tow

Don't want that happening. So, I thought it might be wiser to do the following.

Next to the 'title' field, also set a 'display-title' field.
But, preferably I'd want to generate this for all the projects already in existance...including copying their content to this new display-title field.
Just adding the field means all the titles will need to be copied...not something I look forward to telling the editors of the site 🙂

I saw the Hook for on-save, but that's only for the single page...and I'm not an experienced MySQL-coder/user, otherwise I guess that would've been the way to go.
So I'm really curious to hear if you guys think there are other/better options (and what they are)

Thanks!

Share this post


Link to post
Share on other sites
2 hours ago, j00st said:

1. I have the TITLE field (the one set by ProcessWire as default).

I'd leave the title field as is. Names (urls) are generated from the title when you create a page. If your pages are live, then better leave the title as is.

2 hours ago, j00st said:

2. There's already a whole lot of pages of the template 'project' set up.

How many? This affects how you should run the script below

 

2 hours ago, j00st said:

3. Now I actually want to be able to add <i> and <br> tags to this title...which is possible if I turn off the specialchar encoder...
...but it also presents the opportunity for people to start typing, and generate the following kind of URLs:

Not a great idea! No need for html here.

 

2 hours ago, j00st said:

Next to the 'title' field, also set a 'display-title' field.

This is a better way IMO

2 hours ago, j00st said:

But, preferably I'd want to generate this for all the projects already in existance...including copying their content to this new display-title field.
Just adding the field means all the titles will need to be copied.

That's why we have the API :-). See script below.  TEST BEFORE USE IN PRODUCTION SITE!

  1. Log in as superuser
  2. Copy and paste the following code into a template file, maybe the one used by your home page. 
  3. Visit a page using the template in #2
  4. Check if things went OK
  5. Delete code from template file when done

 

If you have lots of project pages, make use of the start and limit parameters.

/**
 * Copy title field contents to a specified text field on the same page.
 *
 * @param string $fieldName Name of the field to edit.
 * @param string $templateName Name of the template file whose pages we are editing.
 * @param integer $start Start of $pages->find().
 * @param integer $limit Limit of $pages->find().
 * @return void
 */
function generateDisplayTitle($fieldName, $templateName, $start=0, $limit=10) {
    // only superusers allowed!
    if(!wire('user')->isSuperuser()) return;
    // fetch a limited number of pages
    $editPages = wire('pages')->find("template=$templateName,start=$start,limit=$limit");
    # we found pages
    if($editPages->count) {
        foreach ($editPages as $editPage) {
            $editPage->{$fieldName} = $editPage->title;
            $editPage->of(false);
            $editPage->save($fieldName);
            $editPage->of(true);
        }
    }
    
}

// call the function - here, we start at index 2 and limit to 3 pages
// the field we want to copy content to is called 'display_title'
// the template of the pages we want is 'projects'
generateDisplayTitle('display_title', 'projects', 2,3);
# not many pages use (i.e. do all)
#generateDisplayTitle('display_title', 'projects');

 

Edited by kongondo
typos
  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

 

1 hour ago, kongondo said:

I'd leave the title field as is.

Yup, that's what I was hoping to do 🙂 So thank you for this awesome solution!!

 

1 hour ago, kongondo said:

How many? This affects how you should run the script below

Actually not too many on the 'live' test-server...21 at the moment. So still pretty doable.
But in case it's going to fill up fast I want to be sure it's not going to be a lot of manual labour.

 

1 hour ago, kongondo said:

// call the function - here, we start at index 2 and limit to 3 pages 
// the field we want to copy content to is called 'display_title' 
// the template of the pages we want is 'projects' 
generateDisplayTitle('display_title', 'projects', 2,3); 
# not many pages use (i.e. do all) 
#generateDisplayTitle('display_title', 'projects');

 

So the first part of the code is all clear to me. This part (above) is an example right?
In the generateDisplayTitle you've set start=0 and limit=10, and here you start at 2 and limit to 3 pages? Correct?
And if I'd want to do all of them, I'd do the following:
 

generateDisplayTitle('display_title','projects', 0, 21);

And another double-check; as I'm not sure. Am I selecting the parent (projects) here? Or should it be the template, so 'project'?

Share this post


Link to post
Share on other sites
42 minutes ago, j00st said:

But in case it's going to fill up fast I want to be sure it's not going to be a lot of manual labour.

In future, will the editors, when they create a new project page, be inputting the display title themselves? 

42 minutes ago, j00st said:

This part (above) is an example right?

Yes 🙂

42 minutes ago, j00st said:

In the generateDisplayTitle you've set start=0 and limit=10, and here you start at 2 and limit to 3 pages? Correct?

Yes. The defaults are you start from the beginning (0) and you get everything (limit=0 aka, no limit). In my example, I wanted to start from 2 (not a good example, I know) A better example is, assuming I had done a batch before, say the first 100 pages. In the next batch, I'd start from start=101 and limit=100..meaning, I do 100 at a time.  There's a way to automate this, but that's a lot more code :-). 

 

42 minutes ago, j00st said:

And if I'd want to do all of them, I'd do the following:
 


generateDisplayTitle('display_title','projects', 0, 21);

Not quite. It would work though, but since you want to apply to all projects pages, there is no need to enter a start and limit. The following would do:

generateDisplayTitle('display_title','projects');

 

42 minutes ago, j00st said:

And another double-check; as I'm not sure. Am I selecting the parent (projects) here? Or should it be the template, so 'project'?

It should be the name of the template. In my example, it was 'projects'. Adapt to your needs, so yes, 'project' in your case. But it can be any template with a display_title (or whatever you've named the field) field whose pages you need to edit.

Test on a local install first 🙂

Edited by kongondo
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
4 hours ago, kongondo said:

In future, will the editors, when they create a new project page, be inputting the display title themselves? 

Yes! Definitely 🙂 It's just that the existing set needs to be converted/updated.

4 hours ago, kongondo said:

generateDisplayTitle('display_title','projects');

Super!

 

4 hours ago, kongondo said:

But it can be any template with a display_title

Awesome. And much better, as it can be implemented in a wider spectrum.

 

4 hours ago, kongondo said:

Test on a local install first 🙂

For sure 😄  but good to be reminded 😉

Thank you so much. Going to try it on the local server right now!!

Share this post


Link to post
Share on other sites

@kongondo it works like a charm! Thanks again 🙂

One last question...how do I add [SOLVED] to the title of this topic? 😳

Share this post


Link to post
Share on other sites

This basically does the same as kongondo's script, but has a nice GUI if you prefer. This is one the actions in the AdmimActions module.

image.thumb.png.3a60b06d69056c83ae3c7ce3a4648c6a.png

  • Like 4

Share this post


Link to post
Share on other sites

@adrian ooooh, that's very pretty 🙂 I'll keep it in mind for the next time.
The way it was fixed now taught me some extra ProcessWire though, which is also good (for me).

Didn't know about the AdminActions module...will have to study that a bit better. Looks useful!!

Share this post


Link to post
Share on other sites

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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By louisstephens
      So I ran into a strange error this morning when trying to publish a page. I went to publish a new page under "clients", but I get an error that says "Cannot be published until errors are corrected". I thought perhaps I had missed a required field so I checked, but none of the fields are marked as required. I then checked to see if I could just add a basic page (default basic-page.php template) under the homepage, but I get the exact same error when trying to publish. When looking at the template, I don't see any error messages being displayed above any fields.
      The odd thing I found though was if I got to "settings"  and uncheck "unpublished", I can then publish the page without errors. I did upgrade earlier today to the newest version to hopefully fix an issue I had yesterday (which it did). Has anyone run into this error before? 
      **EDIT**
      Well, after a lot of staring and pulling my hair out, I found the issues. I had installed multi-language support sometime ago (and due to the project changing, had to remove it). Apparently in my haste, I did not remove all the dependencies so it was still trying to check for the multi-language title (I am guessing) even though it actually wasnt on the page. I went through the database and removed it and can now save/publish pages without issues. 
    • By gebeer
      Hello all,
      wasn't sure where to put this, so it goes in General section.
      Ryan shows a hook that we can use to mirror files on demand from live server to development environment to be up to date with the files on the server without having to download complete site/assets/files folder.
      I just implemented this but had problems getting files to load from a site in development that is secured with user/password via htaccess.
      First I tried to use WireHttp setHeader method for basic authentication like this
      function mirrorFilesfromLiveServer(HookEvent $event) { $config = $event->wire('config'); $file = $event->return; if ($event->method == 'url') { // convert url to disk path $file = $config->paths->root . substr($file, strlen($config->urls->root)); } if (!file_exists($file)) { // download file from source if it doesn't exist here $src = 'http://mydomain.com/site/assets/files/'; $url = str_replace($config->paths->files, $src, $file); $http = new WireHttp(); // basic authentication $u = 'myuser'; $pw = 'mypassword'; $http->setHeader('Authorization: Basic', base64_encode("$u:$pw")); $http->download($url, $file); } } But, unfortunately this didn't work.
      So now I am using curl to do the download. My hook function now looks like this
      function mirrorFilesfromLiveServer(HookEvent $event) { $config = $event->wire('config'); $file = $event->return; if ($event->method == 'url') { // convert url to disk path $file = $config->paths->root . substr($file, strlen($config->urls->root)); } if (!file_exists($file)) { // download file from source if it doesn't exist here $src = 'http://mydomain.com/site/assets/files/'; $fp = fopen($file, 'w+'); // init file pointer $url = str_replace($config->paths->files, $src, $file); $u = 'myuser'; $pw = 'mypassword'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 50); // crazy high timeout just in case there are very large files curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERPWD, "$u:$pw"); // authentication curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // authentication curl_setopt($ch, CURLOPT_FILE, $fp); // give curl the file pointer so that it can write to it curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $data = curl_exec($ch); curl_close($ch); } } Now I can load files and images from the htaccess protected development server 🙂
      If anyone knows how to get this to work with WireHttp, please let me know. Thank you.
    • By NehaPillai
      Hello Everyone, I was trying to update SEO meta title, description and meta keywords for my website in Process Wire CMS but it saving in the backend but it is not reflecting on my website, Please help me regarding this error. Please find below attached screen shot for your ref. TIA.


    • By AndZyk
      Hello,
      when you add a page you can see the page name of the page under the page title field. But when you change the page title afterwards, you have to go to the settings tab to also change the page name.
      We have many clients that change the page title afterwards but forget to change the page name, because they don't look in the settings tab or forget it.
      Is it possible to show the page name on the content tab under the page title?
      I hate to say this, but I like how WordPress handles this better:

      Or should I open an GitHub request?
      Regards, Andreas
    • By Roberts R
      Can someone point me to the way how to fix title to name? so "ā" becomes "a" and so on. see attachment

×
×
  • Create New...