More Specific Placements Than Hooks Can Provide

Community Forums Forums General Discussion More Specific Placements Than Hooks Can Provide

This topic is: not resolved

This topic contains 11 replies, has 2 voices, and was last updated by  Lord_Devi 1 year ago.

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #58537

    Lord_Devi
    Participant
    Post count: 10

    Hi Guys,

    I’ve been loving Genesis so much, it has been able to teach me a lot about web design and how to take control of my WordPress sites, far more than simple templates and plugins normally provide.

    But as I learn more and more, I find the complexity of my needs expanding.

    I have a problem right now, where I am trying to install a Review plugin, but need to add it’s various components via an API it provides.

    One item I need to add for instance are some extra fields which are to be inserted INSIDE the comment form to allow users to submit their own ratings.

    However, if I try to add this PHP snipped using a Genesis hook, I can get the fields to appear either directly BEFORE the #respond <div> and the form inside of it, or directly AFTER. Not actually INSIDE the form where it needs to be.

    I have tried changing the priority of the hook, but that does not help.

    Cobalt Apps support told me the solution may lie with Filters, but I have read a lot about filters and have not been able to decypher what it is exactly I need to do.

    The documentation on the filters do things like rename “Comments” to “Discussions”, or the like, but I need to ADD NEW content to the form itself.

    Further, I tend to see some of these filter snippets changing variables and passing args, that I can not find lists of anywhere. I am guessing this is something where I may need to read the actual code myself to know what variables there are to change or something, I don’t know.

    But if I can just simply learn how to get more precise with the placement of various content items, it would be like teaching me to fish. I really need to learn this, but I have not been able to pick it up from any of the documentation or blogs I’ve been reading. :(

    I really need help with this one.

    P.S. I’m using Genesis 2.0.1, but I am also using the Dynamik Website Builder which helps me with the creation of functions, hooks, custom widget areas and the like.

    Please help!

    Thanx =)

    #58803

    Gary Jones
    Moderator
    Post count: 686

    In wp-includes/comment-template.php, look around like 1626 and you should see a filter called comment_form_default_fields. This takes an array of fields, where each value is the markup that displays the field. You could filter it with something like (untested, and made-up in terms of what functions the review plugin wants you to use):

    add_filter( 'comment_form_default_fields', 'prefix_add_review_fields' );
    /**
     * Add some made-up review plugin's stars output function underneath existing comment fields.
     *
     * @param  array $fields Existing fields
     *
     * @return array         Amended fields.
     */
    function prefix_add_review_fields( array $fields ) {
    	$fields[] = '<p class="comment-form-review-stars">' . review_plugin_stars() . '</p>';
    	return $fields;
    }

    If using Genesis with an XHTML theme, you’ll need to filter genesis_comment_form_args instead, which is an array with one of the keys called fields. If you want some function to output in between other fields, you’ll need to do some array manipulation to make space for it.


    Changes in Genesis 2.1 – the ultimate guide to every single change in Genesis Framework 2.1 and 2.1.1 (all 88 of them!) | @GaryJ

    #58941

    Lord_Devi
    Participant
    Post count: 10

    Ok ok.. I’m looking at that comment-template.php file you showed me. I see what you are talking about. If you would be willing, or anyone else, a little mini walk through in what you are doing while you construct that statement would go a long way with me!

    With my understanding of what you are doing I adapted the following snippet you provided me with into this:

    add_filter( 'comment_form_default_fields', 'comment_form_review_fields' );
    
    function comment_form_review_fields( array $fields ) {
    	$fields[] = '<p class="comment-form-review-fields">' . myrp_api_ratings_form_table( $post_id = null, $return = false ) . '</p>';
    	return $fields;
    }

    1. If I am creating a functions or variables I like to go from the general to the specific, so I renamed the function to “comment_form_review_fields”.
    2. Editing the class for the review fields to be specific to the custom fields seemed appropriate.
    3. The API code I need to generate the fields is “myrp_api_ratings_form_table( $post_id = null, $return = false )” so I put that where you indicated.

    It did indeed show up! And mostly worked. However, this inserts the fields in a very similar fashion to what I would get by trying to assign it to the “genesis_comment_form” hook. That is, the fields still appear outside of the #respond <div> :( I need it to appear inside “#respond div #commentform form” element.

    I’m attaching a screenshot of the relevant section of the site being examined with Firebug to help provide some more helpful information.

    I’ve already included the snippet of code I am using to try and get this stuff appearing where it needs to be.

    Thanks for the help and insight you have already provided me with by the way!

    The highlighted line in the image are the fields I need inserted into the #respond <div> beneath it.

    Comment Fields Outside Comment Form

    #58956

    Gary Jones
    Moderator
    Post count: 686

    To address your points:

    1. Prefix everything. (Google Nacin’s post for just that phrase.) If your function is within a theme called “Devi”, then call it devi_comment_form_add_review_field(). If it’s in a plugin called “Foobar”, then call it foobar_comment_form_add_review_fields(). “prefix” in my example is a hint that it should be replaced, not dropped altogether. The purpose of the prefix is to help avoid namespace collisions – that is, two sets of code trying to create two functions (or classes etc.) with the same name.

    The inclusion of the verb “add” gives a clue as to what you’re doing with the review fields – you could be adding them, removing them, amending them, or some other action – so making the code a little more self-documenting is not a bad thing.

    3. When calling a function, you don’t need to assign arguments to variables, so instead of myrp_api_ratings_form_table( $post_id = null, $return = false ) you can just do myrp_api_ratings_form_table( null, false ). However…

    4. Your accidental inclusion of the variable names can help me to help you solve why it’s appearing in the wrong place. In short, the table is being echo’d immediately, instead of being assigned to the $fields array for later displaying. We can change that $return from false to true.

    Since I now know that it outputs a table, we can drop the paragraph element from wrapping it, since that would be invalid markup.

    One further point that I missed in my quick suggested code, is that you should always check that a function from a plugin actually exists before using it – if you later deactivate the plugin for whatever reason, the site won’t die of a fatal error.

    All in all then, try the following as the function:

    [php]
    add_filter( ‘comment_form_default_fields’, ‘prefix_add_review_fields’ );
    /**
    * Add some made-up review plugin’s stars output function underneath existing comment fields.
    *
    * @param array $fields Existing fields
    *
    * @return array Amended fields.
    */
    function prefix_add_review_fields( array $fields ) {
    // If plugin function doesn’t exist, abort
    if ( ! function_exists( ‘myrp_api_ratings_form_table’ ) )
    return $fields;

    // Add in the ratings table as one of the fields, returning it (true)
    $fields[] = myrp_api_ratings_form_table( null, true );
    return $fields;
    }[/php]

    I don’t know the inner workings of that plugin function, but if you get an issue where the ratings don’t seem to be applying to the right post, swap out that null and replace it with get_the_ID().


    Changes in Genesis 2.1 – the ultimate guide to every single change in Genesis Framework 2.1 and 2.1.1 (all 88 of them!) | @GaryJ

    #58967

    Lord_Devi
    Participant
    Post count: 10

    Oh ok! Good pointers for your naming conventions. I also like the addition of the function test, to make sure it’s there. I would have totally forgotten to do that.

    I admit again, php is new to me, and I didn’t know that about not needing to assign variables to arguments. I just pulled that line of code out of the MyReviewPlugin API directly.

    I’m understanding better I think now, what you are doing how this works. I just think I may be having some added difficulty being added by this particular plugin or the fact the fields are a table.

    I tried your code snippet again (as is this time), and was greeted with no extra field table at all :( Outside or in.

    so I tried a few different versions of what you suggested, trying to make my best educated guesses on what it could be that I could.

    Namely I only altered the:

    $fields[] = myrp_api_ratings_form_table( null, true );

    Line. I tried the following variations, and in any instance where “true” was used, the table just did not display at all.

    In all other instances, where “false” was used, the table appeared, but outside the actual form #respond <div> still. =/

    $fields[] = myrp_api_ratings_form_table( null, true );
    $fields[] = myrp_api_ratings_form_table( get_the_ID(), true );
    $fields[] = myrp_api_ratings_form_table( $post_id = null, $return = false );
    $fields[] = myrp_api_ratings_form_table( null, false );
    $fields[] = myrp_api_ratings_form_table( get_the_ID(), false );

    I also thought it might be prudent to try and see if I could remove the table and stuff as a possible complication factor. So I thought I would try to use your method to just output some generic text. So I could see if I could get some text to appear inside the comment form using it. But I must be doing something wrong, because I could not get this to display all anywhere! :

    add_filter( 'comment_form_default_fields', 'prefix_add_review_fields' );
    function prefix_add_review_fields( array $fields ) {
    	$fields[] = '<p class="comment-form-review-fields">TESTTESTTEST</p>';
    	return $fields;
    }

    You’ve been very helpful so far still Garyl! Thank you very much for taking the time to respond. =)

    #58973

    Gary Jones
    Moderator
    Post count: 686

    Are you viewing the site whilst logged in? If so, it may not be appearing. Open a private browsing session and then check your site. I just throw your test filter into http://azzag.co.uk/multi-page and it shows up for non-logged in guests.


    Changes in Genesis 2.1 – the ultimate guide to every single change in Genesis Framework 2.1 and 2.1.1 (all 88 of them!) | @GaryJ

    #59009

    Lord_Devi
    Participant
    Post count: 10

    Yes! That was totally it!

    I logged out and it was right there where it ought to be. Phew!

    Thank you so much for your help Garyl.

    I was able to extract from your help some better information about how to go about creating functions. How to find the information inside the code I need to use them effectively, and some good naming conventions. It’ll take some practice of course, but it was very informative!

    Using what you showed me, I expanded on it a bit to utilize this function available inside of Dynamik Website Builder for Genesis (I love that child theme SO much) to have the function also check for a custom conditional.

    I nested it so that first the function checks for the existence of the plugin, like you showed; then it moves on to check if the post has had the label ‘review’ applied to it or not, and if so, THEN to display the comment form.

    And it seems to be working great!

    Here is the final product:

    /*------------------------------------*/
    /* MyReviewPlugin Comment Review Form */
    /*------------------------------------*/
    add_filter( 'comment_form_default_fields', 'prefix_add_review_fields' );
    function prefix_add_review_fields( array $fields ) {
       // Verify the plugin is installed.
       if ( ! function_exists( 'myrp_api_ratings_form_table' ) ) {
          return $fields;
       }
       // Add review form only if the label "Review" has been applied to the page.
       elseif (dynamik_has_label('review')) {
          $fields[] = myrp_api_ratings_form_table( null, true );
          return $fields;
       }
       return $fields;
    }

    I admit a little confusion in a way though. This method seems to work fine, but it is different from what I was seeing around on my.studiopress.com. I was looking at their collection of snippets to modify comments, trying to figure out how to work with this.. and I noticed they were using a filter “genesis_comment_form_args” a lot to modify the form.

    You can see examples of this over at: my.studiopress.com.

    An example is someone using the following code to modify the “Speak Your Mind” text:

    add_filter( 'genesis_comment_form_args', 'sp_comment_form_args' );
    function sp_comment_form_args($args) {
       $args['title_reply'] = 'Leave a Comment';
       return $args;
    }

    I don’t suppose you (or someone else) could explain to me the difference here between using “genesis_comment_form_args” and “comment_form_default_fields”. Or even if one could use either methods..

    It SEEMED to me, like genesis_comment_form_args is a way to do perform similar (if not identical) tasks. And I thought if Genesis has an API to be doing such things, I should probably be using it.

    In my stumbling ignorance, I tried to adapt the genesis_comment_form_args to do the same thing Garyl’s code does, but was unsuccessful. =/

    #59017

    Lord_Devi
    Participant
    Post count: 10

    Ok one more post here…

    I have been going through comment-template.php, the WordPress codex, Genesis snippets, and I have one other related problem I am unable to solve. I was hoping that by fixing the above problem I would learn enough to fix the second issue, but it is not coming to me.

    The review plugin also displays each comment’s associated rating if it has one. Currently I have this assigned with a hook bound to “genesis_after_comment”, but the rating is then appearing BENEATH the “reply” button, and I need it above the reply button.

    I don’t know if I need to use a “replace_action” function or something here or not…

    But here is a picture of what the comment looks like now, and you can see how the star ratings are beneath the “Reply” link.

    How can I have this appear above the Reply button?

    This is the current code I am using to summon the stored rankings:

    myrp_api_comments_ratings_table( $comment_id = null, $post_id = null, $return = false )

    And the image of the problematic result:

    Comment-Post-With-Review-Wrong-Spot

    #59026

    Gary Jones
    Moderator
    Post count: 686

    There’s several levels of filters going on here.

    * comment_form_default_fields is from WordPress, and edits just the fields found in the comment form.
    * comment_form_defaults is another WP one, that allows filtering of all of the comment form arguments (which happens to include the fields as well).
    * Genesis creates its own filter function (genesis_comment_form_args()) that hooks into comment_form_defaults.

    Before Genesis 2.0, it re-built the fields to be a little more accessible over the WP default markup, and tweaked a few of the other labels. To make it easy for developers to tweak what Genesis has said should be the defaults (over what WP said should be the defaults), the genesis_comment_form_args filter was added.
    Since Genesis 2.0 however, for HTML5 themes, Genesis defers back to the WP defaults for HTML5 markup, and only maintains the XHTML markup (and use of the genesis_comment_form_args) for older child themes. Since you’re using Dynamik which I believe is a HTML5 theme, then filtering on genesis_comment_form_args would never have worked, as it simply doesn’t get called. Look at genesis/lib/structure/comments.php line 382 and you can see that if genesis_html5() is true, the rest of the function is ignored, including the filter at the bottom of it.

    In terms of your second question regarding displaying the rating – you’re right, in that genesis_after_comment is fired after the reply button is displayed. What we need to do, is create a custom comment callback, and tell Genesis to use that instead of it’s own one. The steps are:

    1. Copy the function genesis_html5_comment_callback() into your functions.php file, and rename it with your own prefix.
    2. Tweak the function so that your rating appears where you want it.
    3. Filter genesis_comment_list_args so that your custom callback is used.

    [php]
    /**
    * Custom comment callback for genesis_default_list_comments() if HTML5 is active.
    *
    * Does genesis_before_comment and genesis_after_comment actions.
    *
    * Applies comment_author_says_text and genesis_comment_awaiting_moderation filters.
    *
    * @param stdClass $comment Comment object.
    * @param array $args Comment args.
    * @param integer $depth Depth of current comment.
    */
    function prefix_html5_comment_callback( $comment, array $args, $depth ) {

    $GLOBALS['comment'] = $comment; ?>

    <li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>">
    <article <?php echo genesis_attr( ‘comment’ ); ?>>

    <?php do_action( ‘genesis_before_comment’ ); ?>

    <header class="comment-header">
    <p <?php echo genesis_attr( ‘comment-author’ ); ?>>
    <?php
    echo get_avatar( $comment, $args['avatar_size'] );

    $author = get_comment_author();
    $url = get_comment_author_url();

    if ( ! empty( $url ) && ‘http://’ !== $url ) {
    $author = sprintf( ‘%s‘, esc_url( $url ), $author );
    }

    printf( ‘<span itemprop="name">%s</span> <span class="says">%s</span>’, $author, apply_filters( ‘comment_author_says_text’, __( ‘says’, ‘genesis’ ) ) );
    ?>
    </p>

    <p class="comment-meta">
    <?php
    $pattern = ‘<time itemprop="commentTime" datetime="%s">%s %s %s</time>’;
    printf( $pattern, esc_attr( get_comment_time( ‘c’ ) ), esc_url( get_comment_link( $comment->comment_ID ) ), esc_html( get_comment_date() ), __( ‘at’, ‘genesis’ ), esc_html( get_comment_time() ) );

    edit_comment_link( __( ‘(Edit)’, ‘genesis’ ), ‘ ‘ );
    ?>
    </p>
    </header>

    <div class="comment-content" itemprop="commentText">
    <?php if ( ! $comment->comment_approved ) : ?>
    <p class="alert"><?php echo apply_filters( ‘genesis_comment_awaiting_moderation’, __( ‘Your comment is awaiting moderation.’, ‘genesis’ ) ); ?></p>
    <?php endif; ?>

    <?php comment_text(); ?>
    </div>

    <?php
    // Display ratings
    if ( function_exists( ‘myrp_api_comments_ratings_table’ ) ) {
    echo ‘<div class="comment-rating">’;
    myrp_api_comments_ratings_table();
    echo ‘</div>’;
    }

    comment_reply_link( array_merge( $args, array(
    ‘depth’ => $depth,
    ‘before’ => ‘<div class="comment-reply">’,
    ‘after’ => ‘</div>’,
    ) ) );
    ?>

    <?php do_action( ‘genesis_after_comment’ ); ?>

    </article>
    <?php
    //* No ending tag because of comment threading

    }

    add_filter( ‘genesis_comment_list_args’, ‘prefix_comment_list_args’ );
    /**
    * Tell Genesis to use our custom comment callback.
    *
    * (Only deals with HTML5 here.)
    *
    * @param array $defaults Existing defaults.
    *
    * @return array Amended defaults.
    */
    function prefix_comment_list_args( array $defaults ) {
    $defaults['callback'] = ‘prefix_html5_comment_callback’;
    return $defaults;
    }[/php]


    Changes in Genesis 2.1 – the ultimate guide to every single change in Genesis Framework 2.1 and 2.1.1 (all 88 of them!) | @GaryJ

    #59030

    Lord_Devi
    Participant
    Post count: 10

    Aha ok! Yeah I thought that was what needed to be done!

    I was actually just trying really hard to parse lib/structure/comments.php when I got a ping that this thread was updated. =) I admit I was having a difficult time finding exactly what part needed the replacing.

    But I’ve been trying to go through Nick The Geek’s Genesis Explained series to get a better grasp of these things, and it DID seem to me that what I needed to do was copy a function directly, an action anyway.. and then add it to my own custom function list (renaming it), and then manually changing what was there.

    Trying to find my way around all this code is confusing though, I suspect it may take a bit to get right. At least I have years of Linux BASH scripting under my belt to help with the programmatic side of things!

    Anyway, thank you very much for clearing up for me the genesis_comment_form_args() and such as well. I understand that way better now.

    A question though. Did you know to use the html5_comment_callback action just out of experience… or do you have a resource one can use to help find these actions..? — I’m happy I was on the right track. It means I’m actually picking this up! But I am dismayed a bit at just how difficult of a time I am having finding the components I need to modify. (At least I know about the structure of lib/structure now!).

    And one last question if I may:

    Taking an ENTIRE function, the whole action like this, and then making my own version of it.. and then creating a custom function using the entire (sometimes hefty) block of original code as the starting point

    If I need to create modifications like this, that is: Taking an ENTIRE function (sometimes hefty in size), create my own custom function using the ENTIRE original function as a template, and the applying my own (perhaps 1 line at times) tweak to the entire function… am I doing it the best way?

    It seems to me, if Genesis comes out with major updates or anything, I may end up having to redo this function. Or other things I can’t think of. I mean, it just seems like an awfully lot of code I’m copying for just one minor change.

    Thanks again for walking me through some of these little points I was missing from the available documentation again! It’s helping me a ton, that’s for sure!

    I hope you don’t mind some of the extra questions I’ve asked either. I’ve just learned from experience that it’s a good idea to try and avoid NOT learning best-practice approaches the first time around. There may be many ways to skin a cat, but a lot of the time, only a few ways are correct.

    P.S.: Thanks to you Garyl, my comment form’s extra fields are working and exactly where I want them. My rating stars are right where I need them.. Everything is well. And I now have a much better idea about not only how to work with genesis filters and actions, and I also know enough to reliably get stuff done with all the fun API’s out there I’ve been forced to gloss over in the past from lack of knowledge.

    Thanks a ton Garyl!

    #59134

    Gary Jones
    Moderator
    Post count: 686

    I have years of Linux BASH scripting under my belt

    Maybe you could suggest how I could improve https://github.com/GaryJones/wordpress-plugin-git-flow-svn-deploy then ;-)

    Did you know…

    I’m one of the (key) contributors for Genesis, and I’ve probably spent more time looking at and working on the code within Genesis than anyone else. I’ve got a pretty good grasp with how it all fits together :-) In terms of changes between 1.9 and 2.0, I literally wrote the book on it (see my signature!).

    There’s no canonical reference for actions and filters within Genesis, but I’m co-authoring a pair of ebooks that should do exactly that. In the meantime, search for Genesis Visual Hook Guiide (the site and the plugin) to get a better idea of what’s available.

    Taking an ENTIRE function…

    Ideally, Genesis would have an action hook at exactly the place you want it, but it doesn’t so cloning a function and tweaking it is the next best thing (in fact, it’s the only solution available). In this particular case, it doesn’t matter if Genesis 2.1 amends the original function in some way – your site won’t break, and you’ll continue to use your custom callback for displaying each comment. You can then, in your own time, update your theme to include any amendments that Genesis introduces, if you wish.

    P.s. It’s GaryJ, not GaryI :-)


    Changes in Genesis 2.1 – the ultimate guide to every single change in Genesis Framework 2.1 and 2.1.1 (all 88 of them!) | @GaryJ

    #59151

    Lord_Devi
    Participant
    Post count: 10

    Haha… Yeah.. Well BASH scripting is a bit of old obsession. I’m a bit of a control freak. =) (Or power user if you prefer. ;)

    Used to spend days working on little scripts just to help automatically encode video files, organizing images.. all sorts of silly little tasks. I’ve learnt something about that though… There is ALWAYS a way to improve a script =)

    Anyway, just taking a quick look at your svn => wp plugin installer, looks pretty clean to me! You certainly code in an easy to understand manner, I love that.

    The only comment I may have is that you allow the user to enter in custom paths and options to the script, but then do not verify them afterwards.

    Does the directory they enter for the SVN path actually exist? That kinda thing.

    Oh and one more item I guess is that removing the trailing slash from a user entered variable is actually pretty simple as well.

    Just changing:

    SVNPATH="${input:-$default_svnpath}"

    to

    SVNPATH="${input%/:-$default_svnpath}"

    Should do it. (See Here and Here.)

    Anyway yeah, I would enjoy reading those books of yours when they come out. Is there a place I can subscribe or anything to receive any updates in that regard?

    And thanks again for the help! Good to know about the function cloning system. This is still way easier than what I am used to. (Used to use Joomla :P )

    Updating the custom clone later on isn’t so bad really. At least it’s an easy to maintain and manage system. Especially when combined with Dynamik Website Builder. I love that particular marriage SO much!! Finally makes me feel in control of my websites.

    Anyway, I don’t suppose you might know of any good sites or documentation sources on learning Genesis fundamentals better? A little extra reading material perhaps…

    I’ve looked around and I find a decent amount of snippets, everyone has a list of hooks.. But I am surprised at how difficult it is for me to find good documentation on Genesis. The closest I’ve found so far is by “Nick The Geek”. A series titled “Genesis Explained” (Found here.)

    But honestly, and no offense to nick at all for trying so hard, but I find his material very difficult to understand. =/

    Thanks again GaryJ! =)

Viewing 12 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic.