Ben Rothman - WordPress Developer Ben Rothman, Author at ©2023 Ben Rothman, Web Developer

Blog

My blog is dedicated to sharing my expertise, recommendations, and tutorials on WordPress. If you're interested in developing with WordPress, my blog is a valuable resource that you won't want to miss.

Categories
Web Development WordPress

How do I use a transient?

Sometimes in WordPress or really on any other site you have to show something on your site that uses the results from another server like an API call or data about something someone else owns.

If you want to increase efficiency and not have to hit and wait for a response from the foreign resource every time a user does a search and the search itself is common, WordPress has a built in method for this called “transients”. If you have a bit of data that you have to call more than once and takes a lot of resources to get/calculate, you may want to store it in a transient so the data is stored in an easy-to-access place.

A transient is a single piece of data that is stored in the options table like an option, but they are different in that they expire. If I am storing API results, I would not want to store results in 2012 and then have a user in 2022 use the same data. There is a good chance that the API has changed and that data is no longer correct. So a transient is to store a bit of calculated, usually external data, for easy retrieval within a reasonable amount of time. If the transient has expired when the second user does the same search then the API results are gathered again and the transient is remade with the new data and with the expiration timer starting over. Let’s take a look at how transient code looks:

// if the transient does not exist or exists but expired
if ( get_transient('search_results_' . $search_term) == false ) {

            // get the search data for the term from the API
            $contents = wp_remote_get( 'https://APIURL/' . $search_term);

            // get only the body of the API response
            $body = wp_remote_retrieve_body( $contents );

            // decode the JSON array response for use into a PHP array
            $api_results = json_decode($body, true)['entry'];

            // delete expired transient if it exists
            delete_transient( 'search_results_' . $search_term );

            // since there was no valid transient for this search, store the results
            set_transient( 'search_results_' . $search_term, $api_results, 3600 );

        // the transient does exist so get the value from the database where it was stored last time
        } else {

            // since this search was done before and stored, get the stored results
            $api_results = get_transient( 'search_results_' . $search_term );

        }

Categories
Travel WordCamp WordPress

WordCamp Montclair 2024

Today I went to WordCamp Montclair and it was a great event. Props to the event organizers because they did a great job.

I saw several interesting and thought-provoking talks about accessibility and design but of course my favorite talk was from Sal Ferrarello, who gave a talk about Unit Tests. He always gives good talks so I was happy to see him.

I also saw an amazing talk by Rachel Winchester called “Death to Slidedecks: Why Your Next Presentation Needs to be a website”. I think using a website as your presentation rather than a 2 dimensional slide deck will allow for richer and more complex presentations that are more exciting for the viewer.

It was a great WordCamp, and it was in person which is awesome. There have been too few in-person WordCamps in the US in the last few years. I can’t wait for next year!

Categories
Web Development WordPress

Do we want or need the features in theme.json?

I have been a supporter of WordPress for years, and will continue to support it’s mission to democratize publishing. So many of the ideas WordPress has introduced over the years have been amazing, but the theme.json beyond use as a description file was almost a good idea with much to be desired in the execution. As is done in Twenty twentyfour at the time of writing this, we should stick to using functions.php for all code and only have the theme.json file be there to give metadata about the theme. I am not suggesting we abandon the idea of a theme.json or roll it back entirely, I am just suggesting we do not try to use it to do things like add styles or load scripts. I think Sam Hermes gets this just right in his article at https://samhermes.com/posts/slowly-backing-away-from-theme-json .

The theme.json file is a cool idea, but the execution is not very cool. Having the file allows you to convey theme information which is useful but it also allows us to edit a lot of features of WordPress that most people do not need. It takes away features that people do need by hiding them or making them impossible. The process introduced by theme.json is also potentially alienating long-time users who are used to the way things already worked in “classic” WordPress, and the use of the file is not bringing in new users. “Did you hear that WordPress lets you just write JSON to edit the theme now? Sign me up!” Obviously no one who is not a developer ever said that so the feature that is supposed to attract developers with a more efficient workflow just ends up alienating them because the things they knew and loved about WordPress are gone or different now. The feature ends up attracting no one new and alienates the old user base so it is really a loser of a feature all around.

I suggest we only use the theme.json for limited metadata about the theme, and we go back to using functions.php for the important theme configuration. I want to emphasize that I am not saying to get rid of the theme file, I am just suggesting we make sure it is not important and go back to using the functions.php file for everything code.

At work, I work on several WordPress classic sites and one WordPress site that uses a theme.json. The theme.json site is not bad, and from the front-end user view it is no different from any other site. On the admin side of the site it is a different story, it does have a few differences which I find ok, but it also has a few differences which I do not find ok. Thankfully, we can and did use a supplementary functions.php with the theme.json file.

It sounds efficient to have your different kinds of code and theme functionality simplified by being set with one language and all sent from one place by json which is what the theme.json file does. In reality of course, if someone is editing a json file and writing code then they are a developer. This feature is meant to attract developers but does not. A random non-developer is never going to write a code file in the filesystem of their web server, and that should not happen. The WordPress platform out of the box with plugins allows users to make semi-complex sites without any assistance already, but that is kind of the limit of what a normal person can make without hiring some help.

This coming on the heels of the even worse decision to remove ‘Menus’ from the dashboard, stop using the header.php file as well as the footer.php. Why are we changing WordPress so drastically when it was the market leader for CMSs by far in a way that makes it more similar to it’s failing “competition”? I put that word in quotes because technically they were competition but they were all so far behind.

Can a regular person wire their house with electricity? Maybe in a few cases but the answer is generally no so they hire a specialist to do it. Who is WordPress core making this theme editing process better for? Some random, unassisted person is not going to write code, so why are we making it easier for them? The users the theme.json is made to help will never use it. Let’s pivot away from using theme.json to do theme code adjustments in favor of using it to store metadata (like theme headers and possibly a simplified way of adding fonts to the theme) and use the functions.php file to add/modify the code.

Categories
Web Development WordPress

WordPress: How to send an AJAX call with js to execute PHP

Several of the webpages and plugins that I have made with WordPress needed to update the database in some way or reference PHP on a button click. Since PHP and access to the database are run before page load, that seems impossible. This need to run PHP on as a response to user input when a button is pressed is exactly the case that an asynchronous AJAX call like the one I am about to show you comes in handy. Making this asynchronous call work is a multi-step process, but when it works it will do exactly what you want it to do.

First, in functions.php file, enqueue the script as normally but localize the script with a nonce which we will use for security purposes later:

wp_register_script( 'script', plugin_dir_url( __FILE__ ) . '/library/js/script.js', [ 'jquery' ], 'all', true );
wp_localize_script( 'script', 'cp_script', [
	'ajaxurl' => admin_url( 'admin-ajax.php' ),
] );
wp_enqueue_script( 'script' );

Then in the JQuery file, use create a handler for a user clicking a button and in the response include a $.ajax call, which is the asynchronous part. Also in the JQuery we are sending the AJAX to the ajax_url that we localized into the script and we also pass the nonce for use in the PHP for security purposes:

$( 'body' ).on( 'click', '.button_input', function() {	
	var data = {
		index: index,
		author: author,
		message: message,
		style: style,
	};
	
	
	$.ajax({
		type: 'POST',   // Adding Post method
		url: cp_script.ajaxurl, // Including ajax file
		data: {
		"action": "the_function",
		"data"   : data,
		"nonce": cp_script.nonce
	},
	success: function( response ) { // Show returned data using the function.
		console.log( response.data.message );
	
	}
	
        });
	
	
});

And finally in the PHP file, add both actions listed below with the prefixes wp_ajax_ and wp_ajax_nopriv for users of different types, define the function using the same name used in the JQuery and get any data sent from the JQuery from post variables. One of those bits of data is the nonce, it is used to verify that your code sent the command and not some malicious actor. From here you can update the WordPress database and then optionally send results of the update back to the JQuery:

add_action( 'wp_ajax_the_function', 'the_function' );
add_action( 'wp_ajax_noprivs_the_function', 'the_function' );
function the_function() {
// check the nonce to make sure the request came from a user of your code
check_ajax_referer( 'the_function', 'nonce')
// do whatever you want to update the database with PHP
$message = wp_unslash( sanitize_text_field( $_POST['data']) );
update_option( 'latest_message', data );
// optionally send data back to the JQuery that you got from the PHP
wp_send_json_success{ [
   'message'  => 'succeeded'
] );
}
Categories
WordPress

WordPress NYC Meetup

Hey everyone, I was the organizer or the WordPress meetup SotW Watch Party last week at the beautiful Automattic/Tumblr offices. It was fun, we had a sponsorship from Automattic so we had free food, the space was amazing and the speech was obviously very interesting. There were people there in-person, plus it was a hybrid event so half of the attendees were on zoom.

I was part of the in-person side and I have to say it was a lot of fun. Then after the speech we had a nice discussion about what was said and how it related to our WordPress lives! Anyway, it was a lot of fun and I don’t know when there the next one will be but I hope to see you there!

Categories
Plugin Web Development WordPress

HowTo Upload a plugin to the WordPress repository via svn

Checkout the svn repository using the command svn co https://plugins.svn.wordpress.org/{slug here}

Make your changes and create a new branch folder with the new version of the code in it, copy the same files to the trunk folder, then execute svn add * to add the new code to the repository and allow existing versions of your plugin to be updated from the repository.

The final step after adding the new code to the commit is to add the commit message and actually commit the code. Both of those things can be accomplished with one command, svn ci -m 'commit message'

Categories
Web Development Website

I forgot mysql password on a local server, how do I enter the command line?

Just run mysql with a different file as the defaults file:

sudo mysql --defaults-file=/etc/mysql/debian.cnf

Categories
Web Development

Github on Linux: I could push to my repo yesterday but now I get an error

This issue can be caused by multiple problems, but when I ran into this issue it was because my access token had expired but my SSH key was fine.

If you are having this issue and suspect that it may be caused by the token expiration, follow the steps below.

First, generate a new access token on github by following this very simple guide: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token and do not forget to copy the token because you cannot see it again.

Clone a repo to test pushes on and open that location in the terminal.

Run the command:

git remote -v

The output of this command will be the remote URL(s) associated with that particular repository. If there are entries there, you can remove them with the follow command:

git remote remove origin

Add a new remote URL built with the token, the username and the repository name by running the following command but substituting in your own values:

git remote add origin https://[PERSONALACCESSTOKEN]@github.com/[USERNAME]/[REPO].git

After you add that new remote URL you can try to push but you will get an error:

fatal: The current branch main has no upstream branch.
To push the current branch and set the remote as upstream, use

fatal: The current branch main has no upstream branch.
To push the current branch and set the remote as upstream, use

git push --set-upstream origin main

As described in the error, run the command:

git push --set-upstream origin main

and now the pushing will work. Happy coding!

Categories
Web Development WordPress

WordPress: How to send data and variables from js to PHP in an AJAX call

In this post we will learn ways to run a PHP function from JQuery and then from react.

First the JQuery:

jQuery.ajax({
         type : "post",
         dataType : "json",
         url : myAjax.ajaxurl,
         data : {
            action: "my_user_vote",
            nonce: nonce
         },
         success: function(response) {
            if(response.type == "success") {
               jQuery("#vote_counter").html(response.vote_count)
            }
            else {
               alert("Your vote could not be added")
            }
         }
      })   

   })

I’m sure many of you recognize the javascript code block above, added to your code to call an AJAX function and run a PHP function from javascript. The above code will call the PHP function my_user_vote() when an action picked up by JQuery takes place if the function exists, the AJAX hooks were added correctly and the script was in fact localized with the ajaxurl.

If we want to pass data from the original JQuery function that calls the PHP function TO that PHP function, we can simply add more ‘data’ to the call and that data/those variables will be accessible in the PHP as $_POST variables in the function that is called with the names the data was given in the data part of the call.

data : {
            action: "my_user_vote",
            nonce: nonce,
            myVariable: "foobar"
         },

Now, in my PHP function I can get the value “foobar” simply by

public function my_user_vote() {
     $my_variable = wp_unslash( wp_kses_post( $_POST'myVariable'] ) );
...
}

Now from React:

Inside the React element that you wish to send the request from we first define a function that will send a request to a specific endpoint and pass the PHP function a variable called “answers”. Define the following new function in the React element:

const run_algorithm = async () => {
  try {
      const formData = new FormData();
      formData.append('answers', JSON.stringify(answers));

      const response = await fetch('/wp-json/v1/run_algorithm', {
          method: 'POST',
          body: formData,
      });

      const responseData = await response.text();
      console.log(responseData);
  } catch (error) {
      console.error('Error calling PHP function:', error);
  }
};

Then in the return for that element, call the function. In this case we will call the PHP function when a button in react is pushed:

return (
  <>
  <div>
      <button onClick={run_algorithm}>Run PHP Algorithm</button>
  </div>
.
.
.

Finally we will do two things in the PHP. Firstly we will register a new REST endpoint and we will specify the callback function to be run when that endpoint is hit (in this case by the React request):

add_action('rest_api_init', function () {
  register_rest_route('/v1', '/run_algorithm', array(
      'methods' => 'POST',
      'callback' => 'run_algorithm',
  ));
});

Secondly we ill define the actual callback function that is hit by the REST endpoint:

function run_algorithm() {

  // pass the answers from the react
  $answers = wp_unslash(wp_unslash($_POST['answers']));

  // Return a response or print the answers for demo purposes
  return $answers;
}

These are not the only ways to send an asynchronous request from js that runs a PHP function using the REST API in WordPress but these are two possible methods that can be used depending on the structure of the project.

Categories
Web Development WordPress

WordPress: How to Use Nonces to secure AJAX calls

This article assumes you have knowledge of PHP, JQuery, developing for WordPress and enqueueing scripts and using AJAX calls that work but do not use nonce security.

I am not here to try to sell you on using nonces. Nonces do add security to AJAX calls but they are not REQUIRED, just greatly recommended. WordPress describes nonces as “a one-time token generated by a website… This could prevent unwanted, repeated, expired, or malicious requests from being processed.”

In other words, a nonce is a unique key that your website creates that allows you to verify actions. For the purposes of this article, we’re going to focus on using nonces to ensure that requests are originating from our own website.

First, let’s start by generating the nonce. The proper way of doing this is by localizing your javascript files in the PHP where you register and enqueue the script files.

wp_register_script( 'cp_script', plugin_dir_url( __FILE__ ) . '/library/js/cp_script.js', [ 'jquery' ], 'all', true );

		wp_localize_script( 'cp_script', 'vars', [
			'ajaxurl' => admin_url( 'admin-ajax.php' ),
			'nonce'   => wp_create_nonce('any_text'),
		] );

		wp_enqueue_script( 'cp_script' );

In the code above we register a script, point to it’s file, tell WordPress jquery is a dependency, and then localize into the script 1) the ajax url and 2) the nonce that we generate

Then inside the script file, create a JQuery on click function and inside it put this AJAX call:

jQuery.ajax({
	type: 'POST',   // Adding Post method
	url: cp_script.ajaxurl, // Including ajax file
	data: {
	 "action": "my_function",
	 "data"   : data,
	 "nonce": cp_script.nonce
	},
	success: function( response ) { // Show returned data using the function.
		alert( response );
	}

The final step is the shortest. Inside of my_function, the function being called by the AJAX call, just add the actual check as it’s first line:

function my_function() {
     check_ajax_referer( 'any_text', 'nonce' );
...

The check is just that one line. Notice ‘any_text’ can be subbed for any string you choose as long as it matches the string used in the function to generate the nonce, and ‘nonce’ can also be any variable name, as long as it matches the parameter passed in the data of the AJAX call.

Happy WordPressing!

Sources:

How to Add a WordPress AJAX Nonce