bookingactivities / booking-activities

Wordpress plugin booking system
GNU General Public License v3.0
27 stars 8 forks source link

Generating Structured Data for Events/Schedule #202

Open yabdali opened 1 month ago

yabdali commented 1 month ago

Hi, I am looking to pull the data displayed in every product page (WC Front End) in the format of [JSON-LD] ) to enable search engines identify the events in the calendar data and publish display them as events when people search for certain activities/events as per the image below. I am sure this will help in increasing your plugins popularity compared to the others. event-example

The basic idea is to add a code snippet that will be executed on every product page, construct the jSON-LD) and inject it to the page code so when search engine indexes the page it will find the structured data of the calendar events. I can see thee different possibilities such as bookacti_get_product_form_id and get_post_meta which can be used to do this but not sure what would be the ideal approach. Below is an example of the JSON-LD and a link for the Schema reference if you are interested. Thanks a lot for keeping this plugin evolving and for your continuous support. https://schema.org/Schedule

<script type="application/ld+json">
{
  "@context": "https://schema.org/",
  "@type": "Event",
  "url": "http://www.example.org/events/1",
  "name": "Tai chi Class",
  "description": "A weekly Tai-Chi class",
  "duration": "PT60M",
  "eventSchedule": {
     "@type": "Schedule",
     "startDate": "2017-01-01",
     "endDate": "2017-12-31",
     "repeatFrequency": "P1W",
     "byDay": "https://schema.org/Wednesday",
     "startTime": "19:00:00",
     "endTime": "20:00:00",
     "scheduleTimezone": "Europe/London"
  }
}
</script>
yoancutillas commented 1 month ago

Hello, That's a good idea, thank you!

Google says that it is capable of reading the page code after javascript processes (docs), so if that's really the case, you should be able to inject the JSON-LD on the bookacti_booking_system_reloaded hook. This hook is triggered after the events are initially loaded on the calendar.

$j( 'body' ).on( 'bookacti_booking_system_reloaded', '.bookacti-booking-system', function() {
    // Get the displayed events
    var booking_system_id = $j( this ).attr( 'id' );
    var events = bookacti.booking_system?.[ booking_system_id ]?.events;

    // Inject the JSON-LD here
    // ... your code
});
yabdali commented 1 month ago

Hello, That's a good idea, thank you!

Google says that it is capable of reading the page code after javascript processes (docs), so if that's really the case, you should be able to inject the JSON-LD on the bookacti_booking_system_reloaded hook. This hook is triggered after the events are initially loaded on the calendar.

$j( 'body' ).on( 'bookacti_booking_system_reloaded', '.bookacti-booking-system', function() {
  // Get the displayed events
  var booking_system_id = $j( this ).attr( 'id' );
  var events = bookacti.booking_system?.[ booking_system_id ]?.events;

  // Inject the JSON-LD here
  // ... your code
});

@yoancutillas Thanks for your response and highlights. I am just trying to find my way through this, do you mean I should place the injection part of the script into the file below booking-activities/js/booking-system-functions.js Just under // Trigger action for plugins comment or should I create a separate javascript file?

yabdali commented 1 month ago

I tried using code snippet to inject the script to output the content of the var events into the chrome developer console in order to decode the output and be able to identify the parts that can be used to build the JSON-LD but nothing is showing up!

`function inject_script_on_woocommerce_product_page() {
    if ( is_product() ) { // Check if it is a WooCommerce product page
        ?>
        <script type="text/javascript">
            jQuery(document).ready(function($) {
                $('body').on('bookacti_booking_system_reloaded', '.bookacti-booking-system', function() {
                    // Get the displayed events
                    var booking_system_id = $(this).attr('id');
                    var events = bookacti.booking_system?.[booking_system_id]?.events;
                    console.log(events);
                });
            });
        </script>
        <?php
    }
}
add_action('wp_footer', 'inject_script_on_woocommerce_product_page');`
yoancutillas commented 1 month ago

You should never add / edit code to existing plugin / theme files, as your changes will be removed with each plugin / theme update. You need to create child theme first (docs).

In order to add javascript in Wordpress, you should create a .js file and use the wp_enqueue_script() function on the wp_enqueue_scripts and admin_enqueue_scripts hooks.

If you want to add it in the footer, set the $args parameter to true.

You should as well identify the variables and functions used in your custom code and set the handles of the files where they are declared as dependencies in the $deps parameter. In this example, the variables $j and bookacti are declared in booking-activities/js/global-var.min.js (code), which handle is 'bookacti-js-global-var' (code). Your code also uses the jQuery library, jQuery in bundled in Wordpress and its handle is 'jquery' (docs).

Create a my-custom-code.js file at the root of your child theme, with this code:

$j( document ).ready( function() {
    console.log( 'my-custom-code.js file is properly enqueued' );

    $j( 'body' ).on( 'bookacti_booking_system_reloaded', '.bookacti-booking-system', function() {
        console.log( 'the calendar has loaded' );

        // Get the displayed events
        var booking_system_id = $j( this ).attr( 'id' );
        var events = bookacti.booking_system?.[ booking_system_id ]?.events;

        console.log( 'events displayed on the calendar', events );

        // Inject the JSON-LD here
        // ... your code
    });
});

And add this code in you child theme's functions.php:

function mytheme_enqueue_global_scripts() {
    // On backend, only include these scripts on Booking Activities pages
    if( ! function_exists( 'bookacti_is_booking_activities_screen' ) ) { return; }
    if( is_admin() && ! bookacti_is_booking_activities_screen() ) { return; }

    wp_enqueue_script( 'mytheme_custom_js', get_stylesheet_directory_uri() . '/my-custom-code.js', array( 'jquery', 'bookacti-js-global-var' ), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_global_scripts', 100 );
add_action( 'admin_enqueue_scripts', 'mytheme_enqueue_global_scripts', 100 );

As you can see in my-custom-code.js, before testing the events variable, you need to test if you have correctly enqueued your file, and if you have correctly hooked to the bookacti_booking_system_reloaded hook.

In functions.php, on your live website, you need to increase the $ver parameter everytime you modify the my-custom-code.js file, because the my-custom-code.js file is cached by your server (if caching tools / plugins are active) and by your browser. For the same reason, you need to hard refresh the page everytime you test (CTRL+F5 usually).

screenshot-custom-code

I do not provide support for custom code unfortunately. You can use the help of WP documentation and developer communities such as stackoverflow.


Note that this is the old way to make custom javascript code, when the custom code is not related to blocks. Guttenberg has made it even more a nightmare for newcomers: you need to set up a specific development environment, run command lines, learn two languages (Reactjs and ESNext), create dozen of files and follow a training to understand how they are working, then you can start coding, then you need to compilate your code, add the compilated files to your child theme, and register them in a specific way. And you can only rely on the few existing WP documentation, because nobody seem to be able to help on stackoverflow.

yabdali commented 1 month ago

$args

@yoancutillas Thanks a lot, I appreciate your insights. I will work on it next week and see how it goes. Thanks again.