I think I nearly get it, but I don't


hi guys, I've recently discovered Beans and so far I'm getting my head around its API, especially the HTML API and I find it a surprisingly refreshing way of creating contents for my site.

I do run into my limited knowledge about this subject. I think that my code can be a lot more elegant than it currently is and reading through the HTML API's functions I do get some ideas on how to make it better, but I can't really get my head around how to make it all work.

My questions:

  1. I have so many beans_open_markup_e and beans_close_markup_e I think I'm missing the point here
  2. I've seen the functions beans_open_markup and beans_close_markup to "Register open markup and attributes by ID." but I don't get this. Register in what? Can I use or reuse parts of my code? I don't understand the given explanation on this page, sorry πŸ™‚
  3. I also don't understand the function beans_wrap_markup. How can I use this and what is it for exactly?

Pardon my ignorance on this, but I do feel I'm quite getting this but I'm stuck on something that I just don't see yet, and hopefully you guys can shed some light on this case.

Thanks for taking the time to read this!

Jasper

//EDIT I've removed parts of this post because of privacy issues with client work.


ok, I've changed a bunch back to regular HTML tags and placed the function in the correct template for the page. This cleans up a bunch and it's easier to maintain. I also don't need all those hooks around this piece of code so plain' ol HTML suffices.

That still leaves me with question #1 and #2:

  1. I've seen the functions beans_open_markup and beans_close_markup to "Register open markup and attributes by ID." but I don't get this. Register in what? Can I use or reuse parts of my code? I don't understand the given explanation on this page, sorry πŸ™‚
  2. I also don't understand the function beans_wrap_markup. How can I use this and what is it for exactly?

If anybody can help me with this, I'd be very grateful πŸ™‚


Yeah, I get it now. Sometimes no reply is the best reply.


Hi Jasper vdM,

I am not good at english but i will try to explain it.

I've seen the functions beans_open_markup and beans_close_markup to "Register open markup and attributes by ID." but I don't get this. Register in what? Can I use or reuse parts of my code? I don't understand the given explanation on this page, sorry πŸ™‚

Every markup registered with Beans Markup API can be modified or removed just by using his ID as a reference to the markup. All attributes are escaped automatically.

Example 1:

// Beans API.
$id = 'beans_markup'; // Unique ID as a reference.
$tag = 'div';
$attributes = array( 'class' => 'myclass' );

// the suffix `_e` means echo.
beans_open_markup_e( $id, $tag, $attributes );
 echo 'Hello World';
beans_close_markup_e( $id, $tag );

Example 1 will output on your browser:

<div class="myclass">Hello World</div>

In this case, the Markup API doesn't help much right? Let's go more deeper. What if you want to add another class or another attribute or maybe change the tag or maybe remove that markup? Beans has build in helper functions to do that. One of them is the function mentioned by you ( i will explain in the second question ).

The helper functions must be called before the markup was registered. A good example is using them on a child theme since the child theme will run before parent theme was loaded.

Example 2 adding a class:

// On your child theme.

// functions.php
$id = 'beans_markup';  // Same unique ID registered on parent theme.
$attribute_name = 'class';
$attribute_value = 'secondclass';
beans_add_attribute( $id, $attribute_name, $attribute_value );

// On your parent theme .

// example.php
$id = 'beans_markup'; // Register markup with unique ID as a reference.
$tag = 'div';
$attributes = array( 'class' => 'myclass' );

beans_open_markup_e( $id, $tag, $attributes );
  echo 'Hello World';
beans_close_markup_e( $id, $tag );

Example 2 will output on your browser:

<div class="myclass secondclass">Hello World</div>

So what we did there. We added a class to the markup on example.php file (parent theme) just by using his ID on a helper function from functions.php on our child theme.

Example 3 using multiple helper functions.

// On your child theme.

// functions.php

// Remove class attribute.
beans_remove_attribute( 'beans_markup', 'class' );
// Add id attribute.
beans_add_attribute( 'beans_markup', 'id', 'welcome' );
// Modify tag from 'div' to 'h1'.
beans_modify_markup( 'beans_markup', 'h1' );

// On your parent theme .

// example.php
$id = 'beans_markup'; // Register markup with unique ID as a reference.
$tag = 'div';
$attributes = array( 'class' => 'myclass' );

beans_open_markup_e( $id, $tag, $attributes );
 echo 'Hello World';
beans_close_markup_e( $id, $tag );

Example 3 will output on your browser:

<h1 id="welcome">Hello World</h1>

So, the registered ID now makes sense. The whole markup was modified just by using his ID with 3 lines of code from our child theme.

I also don't understand the function beans_wrap_markup. How can I use this and what is it for exactly?

This is another helper function and must be used the same way as we did on other examples. Using this function will call both beans_open_markup and beans_close_markup.

Example 4:

// On your child theme.

// functions.php
$id = 'beans_markup'; // The registered ID (markup) that we want to wrap with another markup.
$new_id = 'beans_new_markup'; // Register ID for the new markup we are creating.
$tag = 'main'; // The tag for the new markup.
$attributes = array( 'class' => 'main' ); // The class for the new markup.
beans_wrap_markup( $id, $new_id, $tag, $attributes );

// On your parent theme .

// example.php
$id = 'beans_markup'; // Register markup with unique ID as a reference.
$tag = 'div';
$attributes = array( 'class' => 'myclass' );

beans_open_markup_e( $id, $tag, $attributes );
  echo 'Hello World';
beans_close_markup_e( $id, $tag );

Example 4 will output on your browser:

<main class="main"><div class="myclass">Hello World</div></main>

The markup we targeted using his ID is now wrapped with our new markup we registered. The same way we can wrap inner markup using beans_wrap_inner_markup().

beans_wrap_inner_markup( 'beans_markup', 'beans_inner_markup', 'span' );

Output:

<div class="myclass"><span>Hello World</span></div>

To remove the markup use beans_remove_markup( $id ) with registered ID as a reference to the markup;

beans_remove_markup( 'beans_markup' );

Output:

Hello World

Hope it helps now, have a nice day.


Hope it helps now, have a nice day.

It definitely does. I see a whole world of possibilities opening now. This way I can perfectly tuck away a bunch of premade, good looking templates and wrap any output I want in these templates with beans_wrap_markup.

And then if I want to add any markup to that output after wrapping it, I can use beans_wrap_inner_markup.

Even without fully understanding this, I was perfectly able to create a big website recently, but knowing this now it's absolutely time to refactor my code, as I now see I used a bunch of templates where I could've used some markup wrappers.

Very, very intelligent system and thank you SO much for explaing especially the wrap_markup part. Awesome, +1.


I am happy to hear that. Thierry has created an amazing framework.

My examples show only the half of the markup potential. I will give more examples about hooks created now.

Potentially hooks (actions) created by markup

// On your parent theme .

// example.php
$id = 'beans_header'; // Register markup with unique ID as a reference.
$tag = 'header';
$attributes = array( 'class' => 'site-header' );

beans_open_markup_e( $id, $tag, $attributes );
    echo 'Hello World';
beans_close_markup_e( $id, $tag );

Output:

[beans_header_before_markup]
 <header class="site-header">
    [beans_header_prepend_markup]
       Hello World
   [beans_header_append_markup]
  </header>
[beans_header_after_markup]

Every markup except ( self-closing ) has 4 potentially hooks that can be created automatically if an action is ommited. All hooks have as prefix the $id in this case beans_header and as suffix they have the position where they belong to this markup. ( _before_markup, _prepend_markup, _append_markup and _after_markup ). To use these hooks, you have to use WordPress function add_action().

The beans_wrap_markup() uses $id_before_markup and $id_after_markup hooks to wrap the markup. The beans_wrap_inner_markup() uses $id_prepend_markup and $id_append_markup hooks to wrap inner markup.

But sometimes you want to use only one hook to add extra elements to the page.

Example of adding a text

// On your child theme.

add_action( 'beans_header_prepend_markup', 'my_prepend_function' );
function my_prepend_function() {
  echo 'Someone said: '; // the text to prepend.
}

// On your parent theme .

// example.php
$id = 'beans_header'; // Register markup with unique ID as a reference.
$tag = 'header';
$attributes = array( 'class' => 'site-header' );

beans_open_markup_e( $id, $tag, $attributes );
    echo 'Hello World';
beans_close_markup_e( $id, $tag );

Output:

<header class="site-header">Someone said: Hello World</header>

The text is now prepended to the markup. In the same way you can use other hooks i mentioned.

Another big feature are extra variable passed to the markup.

beans_open_markup() accepts only 3 parameters, $id, $tag, $attributes, extra parameters will be passed to the functions hooked to the 4 hooks i mentioned. beans_close_markup() accepts only 2 parameters, $id, $tag.

Here is an example:

// On your child theme.

// Let's add an action after markup.
add_action( 'beans_nav_after_markup', 'my_function' );
// We are using the extra parameter we added to the function.
function my_function( $item_name ) {
  // With the help of extra parameter, we can target the navigation items we want.
    if ( 'Contact' === $item_name ) {
     ?><a href="#join">Join Us</a><?php
    }
    if ( 'Home' === $item_name ) {
     ?><a href="#blog">Blog</a><?php
    }
}

// On parent theme.

// example.php

$nav = array(
 'Home' => '#home',
    'Portfolio' => '#portfolio',
    'About Us' => '#about',
    'Contact' => '#contact',
);

foreach ( $nav as $item_name => $item_link ) {
 // the first 3 parameters are used by current markup.
 // extra parameters, `$item_name`.
    beans_open_markup_e( 'beans_nav', 'a', array( 'href', $item_link ), $item_name );

        echo $item_name;

    // the first 2 parameters are used by current markup.
    // extra parameters, `$item_name`
    beans_close_markup_e( 'beans_nav', 'a', $item_name );
}

The output:

<a href="#home">Home</a>
<a href="#blog">Blog</a> // with the help of extra parameters, we added this after Home.
<a href="#portfolio">Portfolio</a>
<a href="#about">About Us</a>
<a href="#contact">Contact</a>
<a href="#join">Join Us</a> // with the help of extra parameters, we added this after Contact.

Incredibly interesting, thanks a lot for the thorough writeup this really helps a lot!

I do see in your code you have parts of your code in the functions.php of your child theme and you refer to this example.php file on your parent theme? Do you use your parent theme for displaying the code created in your child theme? Why would that be good? What happens then if Beans has an update?

Thanks again for the amazing help, and thank you @Thierry for creating such an amazing framework. This should be in core, it's so powerful.


Ah, it just mean that the 'modified' markup should run before the original markup was registered, not to change the existing files from parent theme. The example.php is your targeted file from parent theme you want to modify.

Happy coding πŸ™‚


Ah, it just mean that the 'modified' markup should run before the original markup was registered, not to change the existing files from parent theme

Ah, I now fully get everything you've explained to me. YOU ARE AWESOME!!!


Without reading all the comments I just wanted to add something about why we should use all those beans_open_markup and beans_close_markup functions: Beans is so badass you definitely need to get ALL in!

I see you use echo $item_name; througout all your comments, while using more and more beans functions with each comment. You should definitely use beans_output instead, because you can still use filters in future reference. Or - because beans is code agnostic - you can just skip that since it will do what you want anyway.

Let's say you use:

beans_output( 'beans_nav_item' , $item_name );

instead, you can use:

beans_add_filter( 'beans_nav_item_output' , function( $output ) { return '' . $output . '' ;} ); to make it italic.

Well you can get more creative than that I guess but point is that beans is pretty fantastic.

Write a reply

Login or register to write a reply, it's free!