Building a collaborative model tracker


BIM or building information modelling is a crucial workflow in today’s large construction project process.  I am going to go over how to set up a model tracker using WordPress.  This tutorial is intended for moderate WordPress users assuming that you already know how to buy hosting and install/manipulate WordPress.  If you do not, read this post.  The site we are going to build will be a child theme, so pick your favorite theme framework and create a child theme.

The plan

  • Create child theme
  • Add custom post types
  • Add custom fields
  • Create page templates

There is one plugin we want to use to display the model in our browser: 3D Model viewer.  We will also use ACF Pro.

Custom Post Types & Taxonomies

We are going to have two custom post types, one for companies and one for models.


/*-------------------------------------------------------*/
/* Companies Posttype
/*-------------------------------------------------------*/ 
function register_te_company_posttype() {
    // Custom Post Type Labels      
    $labels = array(
      'name'               => _x( 'Companies', 'post type general name' ),
      'singular_name'      => _x( 'Company', 'post type singular name' ),
      'add_new'            => _x( 'Add new', 'te_company' ),
      'add_new_item'       => __( 'Add new Company' ),
      'edit_item'          => __( 'Edit Company' ),
      'new_item'           => __( 'New Company' ),
      'all_items'          => __( 'Companys' ),
      'view_item'          => __( 'View Company' ),
      'search_items'       => __( 'Search Companys' ),
      'not_found'          => __( 'No Company found' ),
      'not_found_in_trash' => __( 'No Company found in trash' ),
      'parent_item_colon'  => __( 'Parent Company' ),
      'menu_name'          => __( 'Companys' )
    );

    // Custom Post Type Capabilities  
    $capabilities = array(
      'edit_post'          => 'edit_post',
      'edit_posts'         => 'edit_posts',
      'edit_others_posts'  => 'edit_others_posts',
      'publish_posts'      => 'publish_posts',
      'read_post'          => 'read_post',
      'read_private_posts' => 'read_private_posts',
      'delete_post'        => 'delete_post'
    );

    // Custom Post Type Taxonomies  
    $taxonomies = array();

    // Custom Post Type Supports  
    $supports = array('title', 'trackbacks', 'comments', 'revisions', 'post-formats');

    // Custom Post Type Arguments  
    $args = array(
        'labels'             => $labels,
        'hierarchical'       => true,
        'description'        => 'Companies',
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'show_in_nav_menus'  => false,
        'show_in_admin_bar'  => false,
        'exclude_from_search'=> true,
        'query_var'          => true,
        'rewrite'            => true,
        'can_export'         => true,
        'has_archive'        => true,
        'menu_position'      => 100,
        'taxonomies'   => $taxonomies,
        'supports'           => $supports,
        //'capabilities'   => $capabilities,
        'capability_type'    => 'page'
    );
    register_post_type('te_company', $args );
  }
add_action('init', 'register_te_company_posttype');
/*-------------------------------------------------------*/
/* Model Posttype
/*-------------------------------------------------------*/ 
function register_te_model_posttype() {
    // Custom Post Type Labels      
    $labels = array(
      'name'               => _x( 'Models', 'post type general name' ),
      'singular_name'      => _x( 'Model', 'post type singular name' ),
      'add_new'            => _x( 'Add new', 'te_Model' ),
      'add_new_item'       => __( 'Add new Model' ),
      'edit_item'          => __( 'Edit Model' ),
      'new_item'           => __( 'New Model' ),
      'all_items'          => __( 'Models' ),
      'view_item'          => __( 'View Model' ),
      'search_items'       => __( 'Search Models' ),
      'not_found'          => __( 'No Model found' ),
      'not_found_in_trash' => __( 'No Model found in trash' ),
      'parent_item_colon'  => __( 'Parent Model' ),
      'menu_name'          => __( 'Models' )
    );

    // Custom Post Type Capabilities  
    $capabilities = array(
      'edit_post'          => 'edit_post',
      'edit_posts'         => 'edit_posts',
      'edit_others_posts'  => 'edit_others_posts',
      'publish_posts'      => 'publish_posts',
      'read_post'          => 'read_post',
      'read_private_posts' => 'read_private_posts',
      'delete_post'        => 'delete_post'
    );

    // Custom Post Type Taxonomies  
    $taxonomies = array();

    // Custom Post Type Supports  
    $supports = array('title', 'trackbacks', 'comments', 'revisions', 'post-formats');

    // Custom Post Type Arguments  
    $args = array(
        'labels'             => $labels,
        'hierarchical'       => true,
        'description'        => 'Models',
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'show_in_nav_menus'  => false,
        'show_in_admin_bar'  => false,
        'exclude_from_search'=> true,
        'query_var'          => true,
        'rewrite'            => true,
        'can_export'         => true,
        'has_archive'        => true,
        'menu_position'      => 100,
        'taxonomies'   => $taxonomies,
        'supports'           => $supports,
        //'capabilities'   => $capabilities,
        'capability_type'    => 'page'
    );
    register_post_type('te_model', $args );
  }
add_action('init', 'register_te_model_posttype');

Add a custom taxonomy for all the MEP disciplines:


/*-------------------------------------------------------*/
/* Disciplines
/*-------------------------------------------------------*/ 
add_action( 'init', 'register_discipline_taxonomies' );
function register_discipline_taxonomies() {
  $labels = array(
    'name'                       => _x( 'disciplines', 'taxonomy general name', 'emanager'),
    'singular_name'              => _x( 'Disciplines', 'taxonomy singular name', 'emanager'),
    'search_items'               => __( 'Search Disciplines', 'emanager'),
    'popular_items'              => __( 'Popular Disciplines', 'emanager'),
    'all_items'                  => __( 'All Disciplines', 'emanager'),
    'parent_item'                => __( 'Parent Disciplines', 'emanager'),
    'parent_item_colon'          => __( 'Parent: Disciplines', 'emanager'),
    'edit_item'                  => __( 'Edit Disciplines', 'emanager'),
    'view_item'                  => __( 'View Disciplines', 'emanager'),
    'update_item'                => __( 'Update Disciplines', 'emanager'),
    'add_new_item'               => __( 'Add New Disciplines', 'emanager'),
    'new_item_name'              => __( 'New Disciplines Name', 'emanager'),
    'add_or_remove_items'        => __( 'Add or remove Disciplines', 'emanager'),
    'choose_from_most_used'      => __( 'Choose from the most used Disciplines', 'emanager'),
    'separate_items_with_commas' => __( 'Separate Disciplines with commas', 'emanager'),
    'menu_name'                  => __( 'Disciplines', 'emanager'),
  );

  // Taxonomy Capabilities  
  $capabilities = array(
      'edit_terms'   => 'manage_categories',
      'manage_terms' => 'manage_categories',
      'delete_terms' => 'manage_categories',
      'assign_terms' => 'edit_posts'
  );

  // Linked Custom Post Types
  $cpts = array('te_model');

  // Taxonomy Arguments  
  $args = array(
      'labels'             => $labels,
      'hierarchical'       => true,
      'description'        => '',
      'public'             => true,
      'show_ui'            => true,
      'show_tagcloud'      => true,
      'show_in_nav_menus'  => false,
      'show_admin_column'  => true,
      'query_var'          => true,
      'rewrite'            => true,
/*      'capabilities'   => $capabilities, */
  );
  register_taxonomy( 'disciplines', $cpts, $args );
}
add_action( 'init', 'build_discipline_taxonomies' );
function build_discipline_taxonomies() { 
  $parent_term = term_exists( 'disciplines', 'disciplines' ); // array is returned if taxonomy is given
  $parent_term_id = $parent_term['term_id']; // get numeric term id
  // management
  wp_insert_term('Mechanical','disciplines', array('description'=> '','slug' => 'mechanical','parent'=> $parent_term_id));
  wp_insert_term('Electrical','disciplines', array('description'=> '','slug' => 'electrical','parent'=> $parent_term_id));
  wp_insert_term('Plumbing','disciplines', array('description'=> '','slug' => 'plumbing','parent'=> $parent_term_id));
  wp_insert_term('Fire Sprinkler','disciplines', array('description'=> '','slug' => 'fire_sprinkler','parent'=> $parent_term_id));
  wp_insert_term('Data','disciplines', array('description'=> '','slug' => 'data','parent'=> $parent_term_id));
  wp_insert_term('Architectural','disciplines', array('description'=> '','slug' => 'architectural','parent'=> $parent_term_id));
  wp_insert_term('Structural','disciplines', array('description'=> '','slug' => 'structural','parent'=> $parent_term_id));
}

Custom Meta Fields

We are going to use Advanced Custom Fields Pro (ACF) to create the custom metaboxes.  ACF exports code to include in your child theme.  To include it, add the code to your functions.php file within a if( function_exists('register_field_group') ) {} statement. First add a color picker to the taxonomy disipline.


register_field_group(array (
	'key' => 'group_54c91066c2fa2',
	'title' => 'Discipline',
	'fields' => array (
		array (
			'key' => 'field_54c9106f45bc4',
			'label' => 'Color',
			'name' => 'color',
			'prefix' => '',
			'type' => 'color_picker',
			'instructions' => '',
			'required' => 0,
			'conditional_logic' => 0,
			'wrapper' => array (
				'width' => '',
				'class' => '',
				'id' => '',
			),
			'default_value' => '',
		),
	),
	'location' => array (
		array (
			array (
				'param' => 'taxonomy',
				'operator' => '==',
				'value' => 'disciplines',
			),
		),
	),
	'menu_order' => 0,
	'position' => 'normal',
	'style' => 'default',
	'label_placement' => 'top',
	'instruction_placement' => 'label',
	'hide_on_screen' => '',
));

 

Then add meta to the model post type including:

  • Date Uploaded
  • Company – linked to discipline
  • File
  • Discipline – linked to taxonomy

register_field_group(array (
	'key' => 'group_54b581e083c8a',
	'title' => 'Model',
	'fields' => array (
		array (
			'key' => 'field_54c9103b1790f',
			'label' => 'Date Uploaded',
			'name' => 'date_uploaded',
			'prefix' => '',
			'type' => 'date_picker',
			'instructions' => '',
			'required' => 0,
			'conditional_logic' => 0,
			'wrapper' => array (
				'width' => '',
				'class' => '',
				'id' => '',
			),
			'display_format' => 'd/m/Y',
			'return_format' => 'd/m/Y',
			'first_day' => 1,
		),
		array (
			'key' => 'field_54c912e976b84',
			'label' => 'Company',
			'name' => 'company',
			'prefix' => '',
			'type' => 'post_object',
			'instructions' => '',
			'required' => 0,
			'conditional_logic' => 0,
			'wrapper' => array (
				'width' => '',
				'class' => '',
				'id' => '',
			),
			'post_type' => array (
				0 => 'te_company',
			),
			'taxonomy' => '',
			'allow_null' => 0,
			'multiple' => 0,
			'return_format' => 'object',
			'ui' => 1,
		),
		array (
			'key' => 'field_54b581f3cdaaf',
			'label' => 'File',
			'name' => 'file',
			'prefix' => '',
			'type' => 'file',
			'instructions' => '',
			'required' => 0,
			'conditional_logic' => 0,
			'wrapper' => array (
				'width' => '',
				'class' => '',
				'id' => '',
			),
			'return_format' => 'array',
			'library' => 'all',
		),
		array (
			'key' => 'field_54b5820ccdab0',
			'label' => 'Discipline',
			'name' => 'discipline',
			'prefix' => '',
			'type' => 'taxonomy',
			'instructions' => '',
			'required' => 0,
			'conditional_logic' => 0,
			'wrapper' => array (
				'width' => '',
				'class' => '',
				'id' => '',
			),
			'taxonomy' => 'disciplines',
			'field_type' => 'checkbox',
			'allow_null' => 0,
			'load_save_terms' => 1,
			'return_format' => 'id',
			'multiple' => 0,
		),
	),
	'location' => array (
		array (
			array (
				'param' => 'post_type',
				'operator' => '==',
				'value' => 'te_model',
			),
		),
	),
	'menu_order' => 0,
	'position' => 'normal',
	'style' => 'default',
	'label_placement' => 'top',
	'instruction_placement' => 'label',
	'hide_on_screen' => '',
));

Page View

Let’s create a new page template called single-te_model.php in your theme directory.  Where your content will be placed, add this:


$title = get_the_title();
$date_uploaded = get_field('date_uploaded');
$company = get_field('company');
$model = get_field('file');
$discipline = get_field('discipline');
echo do_shortcode('[model file="'.$model.'"]');  // uses model shortcode
echo 'Date Uploaded: '.$date_uploaded;
echo 'Company: '.$company;
echo 'Discipline: '.$discipline;

Thanks so much comment for questions and concerns!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.