0

I would like my plugin to provide front-end pages; one which is a list of club members from a custom table and another that will show member details again from a custom member table. Ideally the pages would also be able to make use of custom javascript.

What is the best approach to handle this, whilst keeping in with the look and feel of whichever theme is being used?

Should my plugin create actual pages when it is activating, and somehow include custom content and javascript? Or would my plugin be responsible for providing its own custom content pages somehow?

There seems to be a few ways of doing this, but I am looking for what might be considered best practice.

  • 1
    As said, there are multiple ways of doing so. Is the content actually bound to a particular page or can it be displayed in a sidebar as well? Thus maybe a widget or a shortcode would be a good idea and place it where you need it. If you need a dedicated slug/permalink you can create custom rewrite rules and use e.g. template_include` to include a custom template if necessary. Use e.g the_content filter otherwise. – Fabian Marz Oct 5 '18 at 13:19
  • 1
    @MaxYudin, he's asking for suggestions out of plenty ways of achieving this in WordPress. In my opinion its a valid question and should not be flagged/downvoted as others may come across the same topic. – Fabian Marz Oct 5 '18 at 13:21
  • I was just wanting to be pointed in the right direction, as I assumed this would be quite a common thing to do. I am an experienced developer, but no nothing about wordpress or php. I've had a look into it, and wasn't sure what the best approach would be. I would prefer not to have a hostile response, to what I would consider a reasonable question. – Andrew Rimmer Oct 5 '18 at 13:49
  • 3
    The problem with this type of question is that it is such a broad topic with differing opinions from all sides. There wouldn't be one solid answer to your question which is what this type of site promotes ( one question, one informative answer ). You could use shortcodes, you could use templating similar to WooCommerce, you could create your own plugin pages upon activate, or combining any of these all of which are valid. I think this is better as an open discussion and may be better received on the Official WordPress Forums – Howdy_McGee Oct 5 '18 at 14:22
  • Asking for the "best" of something always leads to opinion-based answers. Which is discouraged. As this Q+A seeks to provide canonical answers. – leymannx May 9 at 7:12
0

Here is simple code to show jobs on frontend, Hopefully it will help you

add_filter( 'template_include', array($this, 'include_template_function' ) );

<?php
/* Plugin Name: WordPress Job Database
   Plugin URI: http://example.com/jobs
   Description: A test plugin to list jobs in wordpress website.
   Version: 1.0
   Author: Hemant Kumar
   Author URI: http://example.com/hemantkumar
   Licence: GPL2
 */
defined( 'ABSPATH' ) or die( 'Direct access not allowed!' );

class WPMDB{     
   function __construct(){       

       /* register_activation_hook(__FILE__, array($this, 'wmmdb_install')); */
       add_action( 'init', array( $this , 'codex_job_init'), 0 );
       add_action( 'init', array( $this , 'job_taxonomy' ), 0 );
       add_action( 'init', array( $this , 'job_locations'), 0 );
       add_action( 'save_post', array( $this , 'save_metabox' ) );
       add_filter( 'template_include', array($this, 'include_template_function' ) );
       add_shortcode ( 'hrm_job_list', array( $this , 'jobs_list_shortcode') );
       add_action( 'admin_enqueue_scripts', array( $this , 'enqueue_plugin_scripts') );


       if ( is_admin() ) {
            add_action( 'load-post.php',     array( $this, 'init_metabox' ) );
            add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
        }

   } 

    /**
     * Enqueue plugin styles and scripts    
     */

    function enqueue_plugin_scripts(){

        $screen = get_current_screen();

        if( is_object($screen) &&  $screen->post_type == 'job' ){

            wp_enqueue_style( 'jobs-admin', plugins_url( '/assets/css/jobs-admin.css', __FILE__ ) );
        }
    }         

    /**
     * Register a book post type.
     */
    function codex_job_init() {
            $labels = array(
                    'name'               => _x( 'Jobs', 'post type general name', 'your-plugin-textdomain' ),
                    'singular_name'      => _x( 'Job', 'post type singular name', 'your-plugin-textdomain' ),
                    'menu_name'          => _x( 'Jobs', 'admin menu', 'your-plugin-textdomain' ),
                    'name_admin_bar'     => _x( 'Job', 'add new on admin bar', 'your-plugin-textdomain' ),
                    'add_new'            => _x( 'Add New', 'Job', 'your-plugin-textdomain' ),
                    'add_new_item'       => __( 'Add New Job', 'your-plugin-textdomain' ),
                    'new_item'           => __( 'New Job', 'your-plugin-textdomain' ),
                    'edit_item'          => __( 'Edit Job', 'your-plugin-textdomain' ),
                    'view_item'          => __( 'View Job', 'your-plugin-textdomain' ),
                    'all_items'          => __( 'All Jobs', 'your-plugin-textdomain' ),
                    'search_items'       => __( 'Search Jobs', 'your-plugin-textdomain' ),
                    'parent_item_colon'  => __( 'Parent Jobs:', 'your-plugin-textdomain' ),
                    'not_found'          => __( 'No Jobs found.', 'your-plugin-textdomain' ),
                    'not_found_in_trash' => __( 'No Jobs found in Trash.', 'your-plugin-textdomain' )
            );

            $args = array(
                    'labels'             => $labels,
                    'description'        => __( 'Description.', 'your-plugin-textdomain' ),
                    'public'             => true,
                    'publicly_queryable' => true,
                    'show_ui'            => true,
                    'show_in_menu'       => true,
                    'query_var'          => true,
                    'rewrite'            => array( 'slug' => 'job' ),
                    'capability_type'    => 'post',
                    'has_archive'        => true,
                    'hierarchical'       => true,
                    'menu_position'      => null,
                    'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
            );

            register_post_type( 'job', $args );


    }


    function job_taxonomy(){

        $labels = array( 
            'name'                       => _x('Departments','taxonomy general name', 'plugin textdomain'),
            'singular_name'              => _x('Department', 'taxonomy singular name', 'plugin textdomain'),
            'search_items'               => __('Search Department', 'plugin textdomain'),
            'popular_items'              => __('Popular Department', 'plugin textdomain'),
            'all_items'                  => __('All Department', 'plugin textdomain'),
            'parent_item'                => null,
            'parent_item_colon'          => null,
            'edit_item'                  => __( 'Edit Department', 'textdomain' ),
            'update_item'                => __( 'Update Department', 'textdomain' ),
            'add_new_item'               => __( 'Add New Department', 'textdomain' ),
            'new_item_name'              => __( 'New Department Name', 'textdomain' ),
            'separate_items_with_commas' => __( 'Separate Department with commas', 'textdomain' ),
            'add_or_remove_items'        => __( 'Add or remove Departments', 'textdomain' ),
            'choose_from_most_used'      => __( 'Choose from the most used Departments', 'textdomain' ),
            'not_found'                  => __( 'No Departments found.', 'textdomain' ),
            'menu_name'                  => __( 'departments', 'textdomain' ),

        );

         $args = array(
            'hierarchical'          => true,
            'labels'                => $labels,
            'show_ui'               => true,
            'show_admin_column'     => true,
            'update_count_callback' => '_update_post_term_count',
            'query_var'             => true,
            'rewrite'               => array( 'slug' => 'department' ),
        );

        register_taxonomy( 'departments', 'job', $args );  

    }   


     function job_locations(){

        $labels = array( 
            'name'                       => _x('Locations','taxonomy general name', 'plugin textdomain'),
            'singular_name'              => _x('Location', 'taxonomy singular name', 'plugin textdomain'),
            'search_items'               => __('Search Locations', 'plugin textdomain'),
            'popular_items'              => __('Popular Locations', 'plugin textdomain'),
            'all_items'                  => __('All Locations', 'plugin textdomain'),
            'parent_item'                => null,
            'parent_item_colon'          => null,
            'edit_item'                  => __( 'Edit Location', 'textdomain' ),
            'update_item'                => __( 'Update Location', 'textdomain' ),
            'add_new_item'               => __( 'Add New Location', 'textdomain' ),
            'new_item_name'              => __( 'New Location Name', 'textdomain' ),
            'separate_items_with_commas' => __( 'Separate Location with commas', 'textdomain' ),
            'add_or_remove_items'        => __( 'Add or remove Locations', 'textdomain' ),
            'choose_from_most_used'      => __( 'Choose from the most used Locations', 'textdomain' ),
            'not_found'                  => __( 'No Location found.', 'textdomain' ),
            'menu_name'                  => __( 'Locations', 'textdomain' ),

        );

         $args = array(
            'hierarchical'          => true,
            'labels'                => $labels,
            'show_ui'               => true,
            'show_admin_column'     => true,
            'update_count_callback' => '_update_post_term_count',
            'query_var'             => true,
            'rewrite'               => array( 'slug' => 'location' ),
        );

        register_taxonomy( 'Locations', 'job', $args );  

    }   


    public function init_metabox() {
        add_action( 'add_meta_boxes', array( $this, 'add_metabox'  )        );
        add_action( 'save_post',      array( $this, 'save_metabox' ), 10, 2 );
    }

    /**
     * Adds the meta box.
     */
    public function add_metabox() {
        add_meta_box(
            'job-meta-box',
            __( 'Job Info', 'textdomain' ),
            array( $this, 'render_metabox' ),
            'job',
            'advanced',
            'default'
        );

    }

    /**
     * Renders the meta box.
     */
    public function render_metabox( $post ) {
        // Add nonce for security and authentication.         
        $metaval = get_post_meta($post->ID);
        wp_nonce_field( 'job_nonce', 'meta_box_nonce' );?>  

      <div class="ui-formcontrols">

        <div class="form-group">             
            <label>Job ID</label>                        
            <input type="text" name="jobid" value="<?php echo @$metaval['jobid'][0]; ?>" class="form-control">            
        </div> 

        <div class="form-group">
            <label for="adminemail1">Email</label>
            <input type="email" class="form-control" name="email" value="<?php echo @$metaval['email'][0]; ?>" id="adminemail1" placeholder="Email">
        </div> 

        <div class="form-group">
            <h4>Job Role</h4>
            <?php

              $content = get_post_meta( $post->ID, 'jobrole', true );
              $editor_id = 'jobrole';
              $settings = array(
                'textarea_rows' => 5,
                'name'          => 'jobrole'
              );

              wp_editor( $content, $editor_id, $settings );

            ?>            
        </div> 


      </div>           
    <?php
    }


    /**
     * Handles saving the meta box.
     *
     * @param int     $post_id Post ID.
     * @param WP_Post $post    Post object.
     * @return null
     */
    public function save_metabox( $post_id, $post ) {

       // Add nonce for security and authentication.
        $nonce_name   = isset( $_POST['meta_box_nonce'] ) ? $_POST['meta_box_nonce'] : '';
        $nonce_action = 'job_nonce';      

        // Check if nonce is set.
        if ( ! isset( $nonce_name ) ) {
            return;
        }

        // Check if nonce is valid.
        if ( ! wp_verify_nonce( $nonce_name, $nonce_action ) ) {
            return;
        }

        // Check if user has permissions to save data.
        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return;
        }

        // Check if not an autosave.
        if ( wp_is_post_autosave( $post_id ) ) {
            return;
        }

        // Check if not a revision.
        if ( wp_is_post_revision( $post_id ) ) {
            return;
        }

        $jobid=$_POST['jobid'];
        $email=$_POST['email'];
        $jobrole = $_POST['jobrole'];
        update_post_meta( $post_id, 'email', $email );
        update_post_meta( $post_id, 'jobid', $jobid );
        update_post_meta( $post_id, 'jobrole', $jobrole);

    }

    function get_jobs_posts() {
        $args = array(
            'post_type' => 'job',
            'order' => 'ASC',
            'post_per_page' => 100, /* add a reasonable max # rows */
            'no_found_rows' => true, /* don't generate a count as part of query */
        );

        $jobs = new WP_Query( $args );

        return $jobs;
    }


    function jobs_list_shortcode ( $atts, $content = null ) {

        $query = $this->get_jobs_posts();
            if ( $query->have_posts() ) : ?>

                <table id="job-list">
                    <tr>
                        <th>Job Title</th>
                        <th>Location</th>
                        <th></th>
                    </tr>
                    <?php while ( $query->have_posts() ) : $query->the_post(); ?>

                        <?php $jobUrl = get_permalink(); ?>

                    <tr>
                        <td id="<?php the_id(); ?>"><?php the_title(); ?></td>
                        <td><?php the_terms( get_the_ID(), 'Locations') ?></td>
                        <td><a href="<?php echo esc_url( $jobUrl ) ?>">Learn More</a></td>
                    </tr>

                    <?php endwhile; ?>
                </table>

                <?php else: ?>
                <p><?php _e( 'You have no Jobs to display.', 'hrm_jobs' ); ?></p>
                <?php endif; ?>
            </div>

        <?php

    }

    function include_template_function( $template_path ) {
        if ( get_post_type() == 'job' ) {
            //die('here');
            if ( is_single() ) {
                // checks if the file exists in the theme first,
                // otherwise serve the file from the plugin
                if ( $theme_file = locate_template( array ( 'single-job.php' ) ) ) {
                    $template_path = $theme_file;
                } else {
                    $template_path = plugin_dir_path( __FILE__ ) . '/single-job.php';
                }
            }
        }
        return $template_path;
    }



}

$newobj = new WPMDB();

single-job.php

<?php
 /*Template Name: Job Description
 */


get_header(); ?>

<div class="wrap">
    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">

        <?php while ( have_posts() ) : the_post();?>
            <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                <header class="entry-header">

                    <!-- Display featured image in right-aligned floating div -->
                    <div style="float: right; margin: 10px">
                        <?php the_post_thumbnail( array( 100, 100 ) ); ?>
                    </div>

                    <!-- Display Title and Author Name -->
                    <strong>Title: </strong><?php the_title(); ?><br />
                    <strong>Locations: </strong>
                   <?php the_terms( get_the_ID(), 'Locations') ?>
                </header>

                <!-- Display movie review contents -->
                <div class="entry-content"><?php the_content(); ?></div>
                <div class="job-role"><?php echo  get_post_meta( get_the_ID(), 'jobrole' , true ) ; ?></div>
                <div class="panel panel-default">
                  <div class="panel-body">
                     <div class="row">
                        <div class="col-xs-12">
                            <form>
                              <div class="form-group">

                                <input type="text" class="form-control" id="username" placeholder="Name">
                              </div>   
                              <div class="form-group">

                                <input type="email" class="form-control" id="email" placeholder="Email">
                              </div>                         
                              <div class="form-group">
                                <label for="exampleInputFile">Resume</label>
                                <input type="file" id="exampleInputFile">
                                <!-- <p class="help-block">Example block-level help text here.</p> -->
                              </div>
                              <!-- <div class="checkbox">
                                <label>
                                  <input type="checkbox"> Check me out
                                </label>
                              </div> -->
                              <button type="submit" class="btn btn-default">Submit</button>
                            </form>
                        </div>
                    </div>

                  </div>
                </div>

                <?php

                    the_post_navigation( array(
                        'prev_text' => '<span class="screen-reader-text">' . __( 'Previous Post', 'summer' ) . '</span><span aria-hidden="true" class="nav-subtitle">' . __( 'Previous', 'summer' ) . '</span> <span class="nav-title"><span class="nav-title-icon-wrapper">' . twentyseventeen_get_svg( array( 'icon' => 'arrow-left' ) ) . '</span>%title</span>',
                        'next_text' => '<span class="screen-reader-text">' . __( 'Next Post', 'summer' ) . '</span><span aria-hidden="true" class="nav-subtitle">' . __( 'Next', 'summer' ) . '</span> <span class="nav-title">%title<span class="nav-title-icon-wrapper">' . twentyseventeen_get_svg( array( 'icon' => 'arrow-right' ) ) . '</span></span>',
                    ) );
                ?>    

            </article>

        <?php endwhile; ?>

        </main><!-- #main -->
    </div><!-- #primary -->
    <?php get_sidebar(); ?>
</div><!-- .wrap -->
<?php wp_reset_query(); ?>
<?php get_footer(); ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.