I worked on a hybrid mobile application for a newspaper company. They had a Wordpress website with news content (in a wp_posts table) which they wanted to be displayed in the application. I built the hybrid application with HTML, CSS, JavaScript, JQuery mobile and packaged with Phonegap build.
I used php to make a connection with their Wordpress database and retrieve the news data (i.e the post_content field of the wp_posts table) to be displayed in the client side application. I retrieved the data with ajax on the client side and inserted it to the DOM with JQuery. However the post_content data contained HTML tags and Script tags etc. It also contained Wordpress specific tags like [caption] and [soundcloud] so there were lots of display problems.
So I decided to filter the content (with php) before sending it back to the client side (and inserting to the DOM) so it could be displayed properly.
I'd really like for you to view my code (in relation to filtering the [caption] tags) and see if you think I filtered it in an efficient way or not (e.g Could I have achieve the same thing with Regex?). I'll firstly give you more information on the process I went through.
I firstly had to analyse the content of the post_content field in the wp_posts table.
On studying the data I found that the [caption]
tags followed the same pattern. More specifically, Inside the [caption]
tag, an <img>
tag appears firstly and then photo caption text.
Here's is an example of how it appears in the post_content field.
[caption id="attachment_14014" align="alignleft" width="599"]
<img class="size-full wp-image-14014"
src="https://www.example.com/wp-content/uploads/Joe-Soap.jpg"
alt="By Joe Soap" width="599" height="593" />
Photo courtesy of dp98.
[/caption]
I wanted to convert this (whenever it occurred within the post_content data) to the following HTML so I could target the elements and style with CSS.
<div class="img_wrapper">
<img class="size-full wp-image-14014" src="https://www.example.com/wp-content/uploads/Joe-Soap.jpg"
alt="By Joe Soap" width="599" height="593" />
<span class="photo_caption_text">Photo courtesy of dp98.</span>
</div>
So I wrote the following function. Do you think their was an easier/more efficient way to achieve the result I wanted? e.g with Regex
PHP function:
function filterPostContent($post_content){
//This function takes in the post_content field (of a wordpress wp_posts table) as a parameter,
//filters the content and returns the filtered content.
//Firstly we create an array from the post_content at every space character
//so we can then inspect each element of the array
//to see if it is a [caption] tag
//split the content into an array at every space.
$post_content_array = preg_split("/[\s]+/", $post_content);
$post_content_filtered = array();
//initialize booleans to false
$caption_tag_element = false;
$img_tag_element = false;
$caption_text = false;
//iterate through the array
for($x = 0; $x < count($post_content_array); $x++){
if(strpos($post_content_array[$x], '[caption') !== false){
//check if the element in the array is a caption tag
//we have found a caption tag so set the boolean to true
$caption_tag_element = true;
//do not push this element onto the array.
}else if($caption_tag_element == true){
//check if the caption_tag_element is true which means we have come across a [caption tag
//so now look for <img string or /> string
if(strpos($post_content_array[$x], '<img') !== false){
//if <img string is found then push the start of an image tag to the post content array therefore not including the characters before.
array_push($post_content_filtered, ' <img ');
$img_tag_element = true;
}else if($img_tag_element == true){
//therefore this element is still part of the img tag element
//check if we have come to the end of the img tag element
if(strpos($post_content_array[$x], '/>') !== false){
//we have come to the end of the img tag element so therefore
//we must be at the point where the photo caption text begins
//so we want to add in a class so that we can style this text with CSS on the client side.
//close the img tag with /> and add a span tag with a class of photo_caption_text
$new_element = '/><span class="photo_caption_text">';
array_push($post_content_filtered, $new_element);
//we have finished adding the img tag so set the boolean to false
$img_tag_element = false;
//set this to true so we know to look out for [/caption] in the next iterations of the loop
$caption_text = true;
}else{
//we have not come to the end of the img tag element yet so just push it to the array normally
array_push($post_content_filtered, $post_content_array[$x]);
}
}else if($caption_text == true){
//we have come across the caption text itself so now look for [/caption] tag within the element
//if we do find [/caption] we must replace it with a </span> tag in order to close the <span> tag
//we have just created for styling the caption text
if(strpos($post_content_array[$x], '[/caption]') !== false){
//found the end caption tag so replace it with a span tag
$element = $post_content_array[$x];
$new_element = str_replace("[/caption]", "</span>", $element);
array_push($post_content_filtered, $new_element);
//now we know we have come to the end of the photo caption text so set both booleans to false
$caption_text = false;
$caption_tag_element = false;
}else{
//[/caption] has not been found yet meaning the current element of the $post_content_array
//array is a part of the photo caption text itself.
array_push($post_content_filtered, $post_content_array[$x]);
}
}
}else{
//the current element of post_content_array does not contain the string: [caption
//also caption_tag_element is false meaning we havent come across a [caption] tag within the post_content
//so just push the element to the new array of filtered content
array_push($post_content_filtered, $post_content_array[$x]);
}
} //end for loop
//return the filtered content.
return $post_content_filtered;
}
CSS styling
On the client side, I was then able to target the photo_caption_text class as follows:
.photo_caption_text{
font-size: 1.0rem;
display: block;
padding: 3px 0px 4px 0px;
text-align: center;
color: #606060;
font-style: italic;
}