Community Forums › Forums › Archived Forums › General Discussion › Hooks Not Working On First Element Of Loop
Tagged: action hooks, add_action
- This topic has 15 replies, 4 voices, and was last updated 9 years ago by
Brad Dalton.
-
AuthorPosts
-
March 22, 2016 at 12:20 pm #182033
Porter
ParticipantFor reasons completely unknown to me, I have a clients site where the first element in a loop behaves differently than all of the others. I'm simply removing the post title, and adding it back to position it below a piece of content, typical use for a hook. For whatever reason, every other element in the loop works, but the first behaves differently.
//* Reposition the entry meta in the entry header on various pages. add_action('genesis_entry_header', 'beamery_reposition_header_meta', 1); function beamery_reposition_header_meta() { //FRONT PAGE if(is_front_page() || is_home() || is_archive()) { remove_action( 'genesis_entry_header', 'genesis_do_post_title'); add_action( 'genesis_entry_header', 'genesis_do_post_title', 14 ); } //SINGLE POSTS if(is_single()) { //Keep as is, no repositioning needed. } }
The above is the only code I've got working, but I have no idea idea why. I added priority 1 to the add_action, which I didn't even know was possible (I only add priority to individual hooks), and that seems to grab the attention of the first post. I was originally trying to remove the post info, but even with the priority one fix above, it wouldn't work, post 1 out of nth refused to behave the same way (title would show up before the category, rather than the other way around as every other post did).
So my questions are:
-Can you add priority to add_action, and how does this work?
-Why on earth does the above work, but the code below not work?
-How could a hook effect every element in a loop, but not the first? Or if it does effect it, how can it effect it differently?//* Reposition the entry meta in the entry header on various pages. add_action('genesis_entry_header', 'beamery_reposition_header_meta', 1); function beamery_reposition_header_meta() { //FRONT PAGE if(is_front_page() || is_home() || is_archive()) { echo('yep'); remove_action( 'genesis_entry_header', 'genesis_post_info', 12); add_action( 'genesis_entry_header', 'genesis_post_info', 7 ); } //SINGLE POSTS if(is_single()) { //Keep as is, no repositioning needed. } }
March 22, 2016 at 5:56 pm #182049carasmo
ParticipantThe same thing happened to me a few weeks ago, I was trying to just move the search results page thumbnail and all but the first were working, I used the
genesis_entry_header
(I think, so much has happened since then) but when I used thegenesis_before_entry
it worked. I figured that the earlier function might do the trick after reading something somewhere. I use priorities on actions all the time, to put things before or after the existing content, I look inside the Genesis framework to see where it was originally placed. https://developer.wordpress.org/reference/functions/add_action/ see the $priority section.The code to move the search page image FYI:
/** ==================================================================================== * Search Page move the image before the title ==================================================================================== **/ function move_search_image() { if ( is_search() && genesis_get_option( 'content_archive_thumbnail' ) ) { // remove the standard featured image output by Genesis per theme settings remove_action( 'genesis_entry_content', 'genesis_do_post_image', 8 ); // add custom featured image output add_action( 'genesis_entry_header', 'genesis_do_post_image', 2 ); } } add_action( 'genesis_before_entry', 'move_search_image' );
March 22, 2016 at 5:59 pm #182050carasmo
ParticipantI don't know why it didn't work, not there yet with my chops. Try asking on WP StackExchange and post your efforts, there are some amazing folks there!
March 22, 2016 at 7:27 pm #182056Tonya
MemberHello Porter,
I typed this up once, but then it disappeared. Oh well, I'll spend a little time and do it again, because I want to help you know how the events work.
Can you add priority to add_action, and how does this work?
Absolutely. Every single callback that is registered for an event has to have a priority. Why? Because that's how WordPress stores the calllbacks: first by the event name (such as genesis_before_entry) and then by the priority level. It takes that priority level, sorts them, and then calls each callback one-by-one in order starting with the lowest priority level (i.e. 0).When you don't specify a priority level, WordPress defaults to a priority of 10. If you want a different one, then you declare it like you did above.
Question 2: Why on earth does the above work, but the code below not work?
Question 3: How could a hook effect every element in a loop, but not the first? Or if it does effect it, how can it effect it differently?
Let me lump these two questions together to help you understand what is happening. You are using the same event name to trigger your callback which changes the priority level. Huh?add_action('genesis_entry_header', 'beamery_reposition_header_meta', 1);
Notice that you are using genesis_entry_header and trying to unregister a callback that also uses this same event genesis_entry_header. Here's the problem: In WordPress Core, it is already in the loop calling each of the callbacks in order one-by-one. It's too late for you unregister the first one. That's why you get that wonky behavior on the first blog article.
Here is my suggestion: use a different event to trigger your callback, such as genesis_meta.
add_action( 'genesis_meta', 'beamery_reposition_header_meta' );
To help you out, head over to my site and do the lab which walks you through registering events. I'm working on one tonight for unregistering them too.
Here's the lab: WordPress Plugin API – Introduction & Registering Events. There are links in there which take you to the Docx to give you full, thorough explanations on add_action, remove_action, add_filter and remove_filter.
Check back tomorrow and I'll have the one for unregistering too for you.
Cheers,
Tonya
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 22, 2016 at 7:33 pm #182059Tonya
MemberSee my post to Porter above. The reason why genesis_before_entry worked for you is because it occurs (fires) before genesis_entry_header. That means you are changing the event registry callbacks before the callback loop starts. That's what you want to do. You get wonky results when you try to do it using the same event name, i.e. genesis_entry_header is an event name.
Does that make sense?
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 22, 2016 at 7:37 pm #182060Tonya
MemberHey Porter,
Let me know if that doesn't make sense for you. Understanding the Event Registry System in the WordPress Plugin API is very important, as it's the thing that allows us to change and enhance WordPress. Actions and Filters are the events. And if you watch the first free video in the Lab above, it should help you to better understand. The ones that introduce you to add_action and remove_action will help you too.
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 22, 2016 at 7:51 pm #182063carasmo
ParticipantMarch 22, 2016 at 7:55 pm #182064carasmo
ParticipantHi Tonya!
Yep, it makes sense, after looking at the the search page and seeing my first image not on the top, I immediately used the action before it because it made sense and hey, I didn't have anything to lose.
I love what you do, thank you for visiting the forum here.
Thanks!
March 22, 2016 at 7:55 pm #182065Tonya
MemberWell I welcome you! April is Genesis Month. I'll be explaining the entire Genesis framework, instruction-by-instruction. Plus there will be lots of labs to help you master it.
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 22, 2016 at 7:56 pm #182066Tonya
MemberExcellent! Good job! Absolutely. I love Genesis. It's the only theming framework that I use.
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 22, 2016 at 8:13 pm #182067carasmo
ParticipantThanks again. I'm pretty good with the Genesis specific stuff, but I need help with arrays, chunks and the ability to create function as a variable. I can pick up stuff by looking at similar things, but it takes me a little while. I'm like a musician who can't read music, I want to read the music but my right brain takes a little longer to understand it.
March 22, 2016 at 8:31 pm #182069Tonya
MemberHere is some help for you on Arrays as I go deep into them as well as discussing their internal pointer. PHP functions use the internal pointer to access the elements within the array.
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 22, 2016 at 8:33 pm #182070Tonya
MemberBTW The best way to learn is to roll up your sleeves and get into the code. I promote reverse engineering everything so that you can see what it does. It really helps you to understand it in detail. And it's ok to break stuff when you're doing it on your local development machine.
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 22, 2016 at 9:26 pm #182073Tonya
MemberPorter and everyone,
I went ahead and shot a video to further explain what is happening and why. I show you the event registry, WordPress Core, and Genesis. Let me know if you have any questions.
Cheers,
Tonya
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 23, 2016 at 1:26 pm #182051Tonya
MemberHello Porter,
Let me see if I can help you to understand action events.
Question 1: Can you add priority to add_action, and how does this work?
The add_action registers a callback to an event. It gives you a way to extend the functionality of WordPress, a plugin, or theme (yup, even Genesis). When that event fires, then all of the callbacks which are registered to it are also called (run). It's allowing you to tap into that point in the code's sequence and run your stuff.
Hooks are events. You have both action and filter events.
The priority level sets the order of when you want the callback to run. The lower the number, the quicker it is called. The default is 10, which means if you don't specify it, then it just defaults to a 10. So a priority level of 1 happens quickly and before a 7 or 10. And yes, callbacks are registered by a specific priority level. That means when you use
add_action
oradd_filter
you either specify the priority level or it will default to 10.I have a hands-on video-based lab which will explain the Event Registry System in WordPress Plugin API as well as how the registration process works for both actions and filters: WordPress Plugin API – Introduction & Registering Events.
remove_action unregisters a previously registered action callback. To unregister you have to provide both the callback and the same priority level that was used in the
add_action
. But here is a big gotcha: ready? You have to unregister after the callback is registered.To help you grasp it, think about a mailing list that people opt into to receive newsletters. If you try to unregister yourself before you ever signup for that list, it doesn't do anything. Right? You never signed up. It's the same with WordPress events. You can't unregister an event until it's already registered and stored in the event registry look-up table.
Question 2: Why on earth does the above work, but the code below not work?
This code does work:
`remove_action( 'genesis_entry_header', 'genesis_post_info', 12);
add_action( 'genesis_entry_header', 'genesis_post_info', 7 );`
The first line above is unregistering the callback
genesis_post_info
, which was first registered with a priority of 12. If you want to see that, yes it is registered before you do theremove_action
, then do the following to look at Event Registry Look-up Table:`global $wp_filter;
var_dump( $wp_filter['genesis_entry_header'][12] );`
Let me explain what you are doing in your code:
1. Genesis loads up and registers the callback in file:
genesis/lib/structure/post.php
on about line 268:add_action( 'genesis_entry_header', 'genesis_post_info', 12 );
2. Then at the point in the program's sequence, the eventgenesis_entry_header
is fired using ado_action( 'genesis_entry_header' );
. Psst you can find that ingenesis/lib/structure/loops.php
on about line 93.
3. WordPress starts looping through and calling each registered callback in order based upon the priority level that each was registered. The smaller the priority number the quicker the callback is called in this loop.
4. Your callbackbeamery_reposition_header_meta
is set to a priority 1. Therefore, it will get called quickly before the 12 above.
5. Then you run the unregister with theremove_action()
function. It unregisters the callbackgenesis_post_info
from the priority 12 spot in the registry table.
6. But then you go and add it back in again (register it again) on the next line. This time though you changed priority to a 7. So you are wanting it to display before the featured image and the post title.If I may make a recommendation, change your event from
genesis_entry_header
togenesis_meta
. I tend to change my registrations as early as I can. So your code would be:add_action('genesis_meta', 'beamery_reposition_header_meta' );
Question 3: How could a hook effect every element in a loop, but not the first? Or if it does effect it, how can it effect it differently?
The event (or hook) works as I explained above. If you are getting wonky results, you need to look at when you trying to either add or remove an event. Do the lab I suggested and it will help you.
I hope that helps you out. Cheers 🙂
Software & Electrical Engineer and Programming Teacher · I’m on a mission to help developers be more awesome.
Find Me: KnowTheCode.io | @hellofromTonya | Profitable WordPress Developer BootcampMarch 25, 2016 at 5:05 am #182213Brad Dalton
Participant -
AuthorPosts
- The forum ‘General Discussion’ is closed to new topics and replies.