Generating a question list
Usually, WordPress uses the archive.php file of the theme for generating post lists of any type. We can use a file called archive-{post type}.php for creating different layouts for different post types. Here, we will create a customized layout for our questions. The simplest solution is to copy the archive file and create a new file called archive-{post type}.php inside the theme. However, it's not the ideal way to create a custom template due to the reasons we discussed while creating the comments.php file. So, we have to use a plugin specific template and override the default behavior of the archive file. Refer to the following steps:
- Make a copy of the existing archive.php file of the TwentySeventeen theme, copy it to the root folder of the plugin, and rename it questions-list-template.php. Here, you will find the following code section:
get_template_part( 'template-parts/post/content', get_post_format() );
- The TwentySeventeen theme uses a separate template for generating the content of each post type. We have to replace this with our own template inside the plugin. The get_template_part function is only used to load the theme specific template. So, we can't use it to load a template file from a plugin. The solution is to include the template file using the following code:
require WPWA_PLUGIN_DIR . 'content.php';
- Next, we have to create the content template by copying the content.php file of the theme from the template-parts/post/content folder to the root folder of our plugin.
- Finally, we need to consider the implementation of the content.php file. In the questions list, only the question title will be displayed, and therefore, we don't need the content of the post. So, we have to either remove or comment the the_excerpt and the_content functions of the template. We can comment the following line within this template:
the_content( sprintf(
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentyseventeen' ), get_the_title()
) );
- Then, we will create our own metadata by adding the following code to the <div> element with the entry-content class:
<div class="answer_controls"><?php
comments_popup_link(__('No Answers ↓', 'twentyseventeen '),
__('1 Answer ↓', 'responsive'), __('% Answers ↓',
'twentyseventeen')); ?>
</div>
<div class="answer_controls">
<?php wpwa_get_correct_answers(get_the_ID()); ?>
</div>
<div class="answer_controls">
<?php echo get_the_date(); ?>
</div>
<div style="clear: both"></div>
The first container will make use of the existing comments_popup_link function to get the number of answers given for the questions.
- Then, we need to display the number of correct answers of each question. The custom function called get_correct_answers is created to get the correct answers. The following code contains the implementation of the get_correct_answers function inside the main class of the plugin:
function get_correct_answers( $post_id ) {
$args = array(
'post_id' => $post_id,
'status' => 'approve',
'meta_key' => '_wpwa_answer_status',
'meta_value'=> 1,
);
// Get number of correct answers for given question
$comments = get_comments( $args );
printf(__('<cite class="fn">%s</cite> correct answers'),
count( $comments ) );
}
We can set the array of arguments to include the conditions to retrieve the approved answers of each post, which contains the correct answers. The number of results generated from the get_comments function will be returned as correct answers.
We have completed the code for displaying the questions list. However, you will still see a list similar to the default posts list. The reason for that is we created a custom template and WordPress is not aware of its existence. So, the default template file is loaded instead of our custom template.
- We need to override the existing archive template of WordPress by adding the following action to the instance function of the main plugin class:
add_filter( 'archive_template',
array(self::$instance,'questions_list_template' ));
- Here, we have the implementation of the questions_list_template function inside the main class of the plugin:
public function questions_list_template($template){
global $post;
if ( is_post_type_archive ( 'wpwa_question' ) ) {
$template = WPWA_PLUGIN_DIR . '/questions-list-template.php';
}
return $template;
}
This function overrides the archive template when the questions list is displayed and keeps the default template for posts lists or any other custom post type lists.
Now, you should have a question list similar to the following screenshot:
Throughout this section, we looked at how we can convert the existing functionalities of WordPress for building a simple question-answer interface. We took the quick and dirty path for this implementation by mixing HTML and PHP code inside both, themes and plugins.