Using of Custom Post Type and Advanced Custom Fields:

I created a new post type called “Modules” to hold all the modules I’ve studied in the last four years and the marks I’ve got. The way I did that was by adding a function to the WordPress functions.php file and executed it, here is the code:

/* Custom Post Type Start */

function create_posttype() {
register_post_type( 'modules',
array(
  'labels' => array(
   'name' => __( 'modules' ),
   'singular_name' => __( 'Module' )
  ),
  'public' => true,
  'has_archive' => false,
  'rewrite' => array('slug' => 'modules'),
  'menu_icon'   => 'dashicons-welcome-learn-more',
 )
);
    
}
// Hooking up our function to theme setup
add_action( 'init', 'create_posttype' );

// Create Taxonomy for Custom Post Type the above
add_action( 'init', 'modules_custom_taxonomy' );
 
//create a custom taxonomy name it "year" 
function modules_custom_taxonomy() {
 
  $labels = array(
    'name' => _x( 'Years', 'taxonomy general name' ),
    'singular_name' => _x( 'Year', 'taxonomy singular name' ),
    'search_items' =>  __( 'Search Years' ),
    'all_items' => __( 'All Years' ),
    'parent_item' => __( 'Parent Year' ),
    'parent_item_colon' => __( 'Parent Year:' ),
    'edit_item' => __( 'Edit Year' ), 
    'update_item' => __( 'Update Year' ),
    'add_new_item' => __( 'Add New Year' ),
    'new_item_name' => __( 'New Year Name' ),
    'menu_name' => __( 'Years' ),
  ); 	
 
  register_taxonomy('years',array('modules'), array(
    'hierarchical' => true,
    'labels' => $labels,
    'show_ui' => true,
    'show_admin_column' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'year' ),
  ));
}
/* Custom Post Type End */

Then I used ACF to customise the post page in the CMS for the purpose and added the needed fields, as follows:

Single Module-Post editing screen, showing the ACF fields and Year taxonomy.

This is how I wrote the main template file for Modules page after the header part and before the footer:

Template modules-page.php Code:

<?php $loop = new WP_Query( array( 'post_type' => 'modules', 'years' => 'first-year', 'orderby'=> 'title', 'order' => 'ASC', 'posts_per_page' => -1) ); ?>
<h2 class="roundy">First Year</h2>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
	<?php include('module-year1content.php');  ?>
<?php endwhile; wp_reset_query(); ?>

<?php $loop = new WP_Query( array( 'post_type' => 'modules', 'years' => 'second-year', 'orderby'=> 'title', 'order' => 'ASC', 'posts_per_page' => -1) ); ?>
<h2 class="roundy">Second Year</h2>
<div class="row">
  <?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
  <div class="col-md-4">
    <?php include('module-year2content.php');  ?>
  </div>
  <?php endwhile; wp_reset_query(); ?>
</div>

<?php $loop = new WP_Query( array( 'post_type' => 'modules', 'years' => 'third-year', 'orderby'=> 'title', 'order' => 'ASC', 'posts_per_page' => -1) ); ?>
<h2 class="roundy">Third Year</h2>
<div class="row">
  <?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
  <div class="col-md-4">
    <?php include('module-year3content.php');  ?>
  </div>
  <?php endwhile; wp_reset_query(); ?>
</div>

<?php $loop = new WP_Query( array( 'post_type' => 'modules', 'years' => 'fourth-year', 'orderby'=> 'title', 'order' => 'ASC', 'posts_per_page' => -1) ); ?>
<h2 class="roundy">Fourth Year</h2>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
	<?php include('module-year4content.php');  ?>
<?php endwhile; wp_reset_query(); ?>

JQuery Code:

Nothing is too much complicated in here. After using WP_Query() function to prepare the post type of “Modules” then filtering them as per the taxonomy “Year” then its time to loop through the modules within that year’s array and extract its data.

For Years 1 and 4: I used the standard library of JQuery-UI and called on of the UI widgets called progress bar by calling jQuery(“.selector”).progressbar({value: }); function then I passed on modules’ data to it as the code below.

If the value was missing because I didn’t finish my fourth-year modules for example, then the progress bar will show as it is under construction:

HTML/PHP/ JQuery Code inside module-year1content.php:

<div class="pindex">
    <h4>
        <?php echo get_the_title(); ?> <span>(Composite Mark:
            <?php the_field( 'composite_mark' ); ?>, Grade Point:
            <?php the_field( 'grade_point' ); ?>, Final Grade:
            <?php the_field( 'final_grade' ); ?>) </span></h4>
    <div id="progressbar_<?php the_field( 'module_code' ); ?>"></div>

    <script>
        jQuery(function() {
            jQuery("#progressbar_<?php the_field( 'module_code' ); ?>").progressbar({
                <?php if (get_field( 'composite_mark' )): ?>
                    value: <?php the_field( 'composite_mark' ); ?>
                <?php  else: ?>
                    value: false
                <?php  endif;  ?>
            });
        });
    </script>
</div>

For Years 2 and 3: I used a JQ Library called: Circle-Progress which has the following function circleProgress(); which I passed on my modules data to it as the following two piece of code.

HTML/PHP/ JQuery Code inside module-year2content.php:

<div class="pindex">
    <div class="circles">
        <div class="module_circle_<?php the_field( 'module_code' ); ?>">
          <h4>
                <?php echo get_the_title(); ?> 
               <span>(Composite Mark:
                <?php the_field( 'composite_mark' ); ?>, Grade Point:
                <?php the_field( 'grade_point' ); ?>, Final Grade:
                <?php the_field( 'final_grade' ); ?>) 
                </span>
          </h4>
        <strong></strong>
        </div>
    </div>
</div>

<script>
      jQuery('.module_circle_<?php the_field( 'module_code' ); ?>').circleProgress({
        value: <?php the_field( 'composite_mark' ); ?>/100,
      }).on('circle-animation-progress', function(event, progress) {
        jQuery(this).find('strong').html(Math.round(<?php the_field( 'composite_mark' ); ?> * progress) + '<i>%</i>');
      });
</script>

HTML/PHP/ JQuery Code inside module-year3content.php:

<div class="pindex">
    <div class="circles">
        <div class="module_circle_<?php the_field( 'module_code' ); ?>">
            <h4>
                <?php echo get_the_title(); ?>
              <span>(Composite Mark:
                <?php the_field( 'composite_mark' ); ?>, Grade Point:
                <?php the_field( 'grade_point' ); ?>, Final Grade:
                <?php the_field( 'final_grade' ); ?>)
              </span>
            </h4>
            <strong></strong>
        </div>
    </div>
</div>

<script>
      jQuery('.module_circle_<?php the_field( 'module_code' ); ?>').circleProgress({
        value: <?php the_field( 'composite_mark' ); ?>/100,
        fill: {gradient: [['#0681c4', .5], ['#4ac5f8', .5]], gradientAngle: Math.PI / 4}
      }).on('circle-animation-progress', function(event, progress, stepValue) {
        jQuery(this).find('strong').html((stepValue.toFixed(2).substr(1))*100 + '<i>%</i>');
      });
</script>

Conclusions/Recommendations:

  • The reason why I included the scripts inside the partial content.php files is because I am passing on a dynamic data which changes for each one of the modules, so I need to keep this inside the same PHP file that is requesting the ACF values to pass on to both; the HTML to render and JQuery to calculate and draw the circles.
  • Without using the dynamic CMS front-end back-end techniques, the data would be hardcoded into HTML static pages, then it will be challenging for the normal user (typically the website owner) to edit that data when any changes are required, in our example here to update fourth-year’s modules marks.

Implementation/Result:

First Year

CCN1 Introduction to Networks (Composite Mark: 91, Grade Point: 4.0, Final Grade: A1)

Computing Systems (Composite Mark: 90, Grade Point: 4.0, Final Grade: A1)

Design for Interaction (Composite Mark: 87, Grade Point: 3.5, Final Grade: A2)

Introduction to Programming (Composite Mark: 86.6, Grade Point: 3.5, Final Grade: A2)

Introduction to Web Development (Composite Mark: 91, Grade Point: 4.0, Final Grade: A1)

Mathematics for Computing (Composite Mark: 90, Grade Point: 4.0, Final Grade: A1)

Professional Development in Computing (Composite Mark: 60, Grade Point: 2.5, Final Grade: B1)

Second Year

Computing Project (Composite Mark: 50.5, Grade Point: 2.0, Final Grade: B2)

Database Development (Composite Mark: 88.56, Grade Point: 3.5, Final Grade: A2)

HTML5 and Javascript Programming (Composite Mark: 87.67, Grade Point: 3.5, Final Grade: A2)

Object Oriented Analysis (Composite Mark: 83, Grade Point: 3.5, Final Grade: A2)

Programming for Mobile Devices (Composite Mark: 77, Grade Point: 3.0, Final Grade: A3)

Structures and Algorithms (Composite Mark: 85.4, Grade Point: 3.5, Final Grade: A2)

Third Year

Advanced Programming for Mobile Devices (Composite Mark: 73, Grade Point: 3.0, Final Grade: A3)

Creative Technologies Professionalism (Composite Mark: 90, Grade Point: 4.0, Final Grade: A1)

Database Applications (Composite Mark: 77.4, Grade Point: 3.0, Final Grade: A3)

Internet Scripting (Composite Mark: 71, Grade Point: 3.0, Final Grade: A3)

Research Methods in Computing (Composite Mark: 84, Grade Point: 3.5, Final Grade: A2)

Web Server Technology (Composite Mark: 83.2, Grade Point: 3.5, Final Grade: A2)

Web Site Development (Composite Mark: 95, Grade Point: 4.0, Final Grade: A1)

Fourth Year

Computing Honours Project (Composite Mark: , Grade Point: , Final Grade: )

Digital Project (Composite Mark: , Grade Point: , Final Grade: )

Dynamic Web Technologies (Composite Mark: , Grade Point: , Final Grade: )

Server Side Systems (Composite Mark: , Grade Point: , Final Grade: )