Jump to content

How do we auto increment our title and name fields?


Zahari M.
 Share

Recommended Posts

Hi Guys!

Hopefully someone can offer me some assistance with this as it involves, I suspect, hooks and I have no idea how to use them :huh: .

This will be the first time I have come across the need!

So, what I have done is I created a parent page called Videos. This Video parent will have children and each of these children will hold 1 video.

So what I want to do is make the title and name for each child page an automatically incrementing number when you create and save a page.

So the first few child pages for the Videos parent will be titled and named 1, then 2, then 3 and so it goes...

Doing a search first before asking, I came across these 2 code snippet in a thread here by fellow member Macrura who offered this code:

public function init() {
       $this->pages->addHookAfter('saveReady', $this, 'autoIncrememt');
    }

 

public function autoIncrement(HookEvent $event) {
 $page = $event->arguments[0];
  if($page->template != 'someTemplate') return; 

  // some logic here to count the existing pages of this template and then add 1 and set the value of your auto increment field to that value, if it is empty.

}

As I am not at all familiar with how to achieve what I am trying to do, I am not sure if the above sample code is the way to go towards solving my need.

I also have no idea where the above code goes and what the variable $this is supposed to be!!

Any help would be greatly appreciated.

Cheers guys and thanks for looking!!

Link to comment
Share on other sites

Sorry I don't answer this, but have these questions:

What if number 3 is gets deleted ? You end up with 1, 2, 4, 5. 

And upon creation of the new one, will it have the number 3 or does it gets the number 6 ?

Or when you decide rename 4 and 5 to 3 and 4, then the new one will be 5.

( SEO problems and loads of overhead )

Link to comment
Share on other sites

Hi Martijn!

Thanks for the reply. And looking!

All good questions that you ask Martijn!

Well, I did not intend for them to get deleted. But if they did, I would like it to work kind of like how an auto increment works in mysql. So if we go by your example above, the new one will get number 6.

In this case Martijn, these pages hold one video. The idea is that you do not view the video page directly, although you could if you went to www.mysitecom/videos/3. The idea is that an article will use the page reference field to retrieve video pages and display them within articles.

Whilst it is not that hard to see what the last video page was numered and mentaly add one to our new page, it would be nice if the creation of a new video page would take care of this for us as I have enough seo fields to fill in already ;)

Hee hee!

So thats why I was asking.

If anything, I would just unpublish a video page but not delete it.

So any suggestions most appreciated.

And congrats on the new iMac!

Cheers!

Link to comment
Share on other sites

Hi Renobird

Thanks for the reply and looking. Much appreciated!

I was replying to Martijn when your reply came in, so things are a lil out of time sync!

Anyhows, the gist of it is, I want to create a video child page whose url portion or in Wordpress speak, "slug", has a number.

If it is done this way, someone can look at a very specific video by going to mysite.com/videos/33.

The name and title of the child page also become the video id and part of the address.

Thats one way to watch the video. But its not the way I want to steer things. The main idea is to create aricles that use a page reference field to select a video and pull them in to my articles and get people to watch the video from within the article.

Makes sense?

Cheers!

Link to comment
Share on other sites

Hi Zahari,

I think there are ways to do this without incrementing the page names though, which as Martijn mentioned can get you into trouble.

My first thought is to go with URL segments (make sure they are enabled in your /videos/ template).

In the template for your /videos/ page

$pg = $pages->get("/videos/")->children("start={$input->urlSegment1}, limit=1");

// I think $pg will still be a pageArray with just one page

if ($pg){
    foreach ($pg as $p){
       echo $p->video; // assuming the video field is named "video"  
    }
}

untested, and off the top of my head. The idea is you get the child page by whatever number is in the URL.

from there you output the video for that page. Page names aren't even involved.

Edit (I guess you still get into trouble with this method if any pages are ever deleted or reordered.)

Link to comment
Share on other sites

You could add a "video ID" to the template:

$pg = $pages->get("video_ID={$input->urlSegment1}");

if ($pg->id){
    echo $p->video; // assuming the video field is named "video"  
}

I'm certain there is a way to do this without relying on incremental page names. :)

You can still use your page field to select video pages and display them in other pages this way too.

Link to comment
Share on other sites

Hi renobird

I have no intention of deleting any of these video pages once they are created, so I am not too worried about that aspect. All that I foresee is unpublishing them or not ever calling on them via the page reference field. If anything, it makes me extend the question now, how do we auto increment and disable deleting!

But thanks so much for your great suggestions. I have just about zero experience with URL segments.

So I will have to ponder on this and work at it for a while and read up on them. Once I have done that I will try and implement your suggestions.

Thanks renobird!

  • Like 2
Link to comment
Share on other sites

Zahari,

URL segments are pretty simple. Essentially you can add "segments" to your URL that don't actually resolve to a page.

From the docs

Given a page that exists at the URL /page/to/page/, a URL of /path/to/page/aaa/ will return a 404 Page Not Found error by default. But if you enable URL segments for the page's template, then it will instead render the page and populate $input->urlSegment1 with "aaa".

So for your needs, we are talking about anything after /videos/ in the URL.

The more I think about it, what I suggested about adding a video_id field and using URL segments should accomplish exact what you are after.

Link to comment
Share on other sites

Just a small point, unless you are absolutely wedded to the idea of having a number as a title (which does not seem very SEO friendly to me), don't forget that each page also has an ID number. Now, although they may not be sequential, (if you have created another page in another section of site) they will be in numerical order.

Link to comment
Share on other sites

Hi Joss

Thanks so much for for looking and commenting. I did a search and the wiki pages you did on url segments are fantastic Joss! Awesome stuff! Using the page ID is a good idea too Joss.

As for the SEO aspect, as mentioned, the idea is that this video page isn't the page that is meant to be publicly consumed. The "flow" I desire Joss is that I do a video and store it on a page as an "assett". The videos are hosted externally, so all this page is really doing is holding all the various bits of data / metadata required to display the video and mark it up with schema.org properties for video objects.

The articles that are written on my site are the ones where seo will be considered and these articles will pull the video in along with it's markup via a page reference field.

The situation or need where these video pages would be deleted is extremely unlikely more like non-existent. I would just unpublish it.

Why I want numerical id's for these video pages titles is simple. For specific situations where specific people want or need to see just the video, I can just say to people over the phone, go to mysite.com/videos/33 or whatever the number/s is/are. I want to spend as little time on the phone as possible and avoid spelling ambiguities etc!

Hi renobird

I think your idea of using url segments here was a great idea renobird!

This way the title of the page can also be used as the name of the video, and one can get to it numerically via the number / url segment as you proposed. Yay!

I do have one question though... if we use a video_id field as you have suggested, is there a way to automate our video_id field such that we don't have to keep filling it in on each new video page? It's not a big deal, but it would be nice if we can get it automated :)

Cheers guys!

Link to comment
Share on other sites

Chiming in quite late here and to be honest haven't read things thoroughly, but my RedirectIds module might be of use for giving your clients an easy url over the phone:

http://modules.processwire.com/modules/process-redirect-ids/

It means you can give them: mysite.com/videos/1356

where that number is the PW ID of the page. You can choose to have that link redirect to the normal full PW url for the video, or stay on the numbered url and just load the page content - simple config setting in the module.

Not sure if this is your best approach, but thought I'd throw it in the mix.

  • Like 1
Link to comment
Share on other sites

Hi Adrian

Never too late to chime in. And you know I always appreciate your insights!

That module you mentioned does a very interesting thing. I have made a mental note to have a play with it later on when I have finished some other things. Indeed I was wondering to myself just 2 days ago how could we resolve a page by it's id. Looks like you've solved that one! Yay!

Ok guys... thanks to renobirds suggestions and Joss's sterling wiki pages on the url segments system along with a good cup of coffee, I created this snippet which I fully understand...

// URL SEGEMENTS SECTION:
// As we are only using 1 URL segment, let's display a 404 if there's more than 1 URL segment.
if($input->urlSegment2) throw new Wire404Exception();
 
// This enables video pages to be resolved by appending the video id to this url: www.site.com/videos/
if($input->urlSegment1){
$page = $pages->get("video_id={$input->urlSegment1}");
// In case there is no such video id, let's display a 404.
if(!$page->id) throw new Wire404Exception();
}

That and turning on URL segments is all I had to do. These URL segments are bloody brilliant!!!!

So, for now rainbird, i thank you for helping me make / discovering a fundamentaly large architectural change to the way I shall be adding videos in to the system.

I would however, be interested in knowing, if anyone could share, how we could get a field that we created to auto increment. In the case here, I could do what Joss suggested earlier, and use the page id as the video id. That could be done programatically and the more I think about it, the more I like the idea! Thanks Joss!

But for acedemic purposes, lets say i am starting from scratch, or that I have a field that is assigning all sorts of things and information to a "serial number" that increments. So there might be a need to have a field in a template that can likewise auto increment whenever we create a new page using that template.

Any suggestions anyone how to actually code this facility in?

Thanks again guys!!

  • Like 4
Link to comment
Share on other sites

Hi Zahari,

with $input->urlSegment you can only use type casting for integers, but that's easy and secure. If you have to use strings with it, you need to validate it. This depends on what you are uses, but possible could be:

  • strlen()        min / max / exact
  • in_array()    against array with valid values
  • ... and so on

It depends on what you need to send as urlSegment.

Link to comment
Share on other sites

Good call Horst on (int) horst.

Zahari, glad to help. My examples were a little slapdash, glad the work Joss did on the wiki pages came in handy.

URL Segments are indeed "bloody brilliant!" :)

A module to create an auto incremented field shouldn't be too difficult. I don't have the time now though.

Link to comment
Share on other sites

 A module to create an auto incremented field shouldn't be too difficult. I don't have the time now though.

This one I use for something other, so please modify to your needs (maybe 'saveReady' ):

public function init() {
    $this->addHookAfter('Pages::save', $this, 'hookAfterPagesSave');
}

Following code is not tested!

// in your function, first get the page with something like
    $p = $event->arguments('page');      // depends on hooked method

// check to avoid endless loop
    if($p->skipMe) return;

// validate if it is a page of the right type, maybe check template
    if('video'!=$p->template) return;

// don't do it for videos that have already their unique id
    if($p->video_id) return;

// get the last used number
    $data = wire('modules')->getModuleConfigData($this);     // get the modules data
    $id = intval($data['myIncrementalId']) + 1;              // get the last used number and add +1
    $data['myIncrementalId'] = $id;
    wire('modules')->saveModuleConfigData($this, $data);     // save back the data

// save this to the template field
    $p->video_id = $id;

// add this to avoid endless loop
    $p->skipMe = true;

// ready
    $event->return = $p;

  • Like 2
Link to comment
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
 Share

  • Recently Browsing   0 members

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