/**
  * Applies a node template to the current layout.
  *
  * @since 1.6.3
  * @param int $template_id The node template ID.
  * @param string $parent_id The new parent node ID for the template.
  * @param int $position The position of the template within the layout.
  * @param object $template Optional. Template data to use instead of pulling it with the template ID.
  * @return void
  */
 public static function apply_node_template($template_id = null, $parent_id = null, $position = 0, $template = null)
 {
     $parent = $parent_id == 0 ? null : self::get_node($parent_id);
     $template_post_id = self::get_node_template_post_id($template_id);
     // Apply a network-wide node template?
     if (!$template_post_id && !$template && class_exists('FLBuilderTemplatesOverride')) {
         $root_node = FLBuilderTemplatesOverride::apply_node($template_id, $parent_id, $position);
         if ($root_node) {
             return $root_node;
         }
     }
     // Get the template data from $template if we have it.
     if (is_object($template)) {
         $template_data = $template->data;
         $template_settings = $template->settings;
         $type = $template->type;
         $global = $template->global;
     } else {
         $template_data = self::get_layout_data('published', $template_post_id);
         $template_settings = self::get_layout_settings('published', $template_post_id);
         $type = self::get_user_template_type($template_post_id);
         $global = get_post_meta($template_post_id, '_fl_builder_template_global', true);
     }
     // Generate new node ids.
     $template_data = self::generate_new_node_ids($template_data);
     // Get the root node from the template data.
     $root_node = self::get_node_template_root($type, $template_data);
     // Add a new parent for module node templates if needed.
     if ('module' == $root_node->type && (!$parent || 'row' == $parent->type)) {
         $parent_id = self::add_module_parent($parent_id, $position);
         $position = null;
     }
     // Update the root node's parent.
     $template_data[$root_node->node]->parent = !$parent_id ? null : $parent_id;
     // Get the layout data and settings.
     $layout_data = self::get_layout_data('draft');
     $layout_settings = self::get_layout_settings('draft');
     // Only merge the root node for global templates.
     if ($global) {
         $layout_data[$root_node->node] = $template_data[$root_node->node];
     } else {
         // Merge template data.
         foreach ($template_data as $node_id => $node) {
             unset($template_data[$node_id]->template_id);
             unset($template_data[$node_id]->template_post_id);
             unset($template_data[$node_id]->template_root_node);
         }
         $layout_data = array_merge($layout_data, $template_data);
         // Merge template settings.
         $layout_settings = self::merge_layout_settings($layout_settings, $template_settings);
     }
     // Update the layout data and settings.
     self::update_layout_data($layout_data);
     self::update_layout_settings($layout_settings);
     // Reorder the main template node.
     if (null !== $position) {
         self::reorder_node($root_node->node, $position);
     }
     // Delete old asset cache.
     self::delete_asset_cache();
     // Return the root node.
     if ('module' == $root_node->type) {
         return self::get_module($root_node->node);
     } else {
         return $root_node;
     }
 }