How To Edit Event CPT Single Layout Elementor Free

  1. You need to put this custom code inside a snippet plugin. I am using WPCodeBox, which is a paid plugin. You can also choose a snippet plugin that is free, or create a child theme and put it inside the functions file. Make sure that if you choose a snippet plugin, you put it in as a PHP snippet.
<?php
/**
 *Functions for Linnet Templates
 */

// 1. Register Linnet Templates CPT
function linnet_register_templates_cpt() {
    $labels = array(
        'name'               => __( 'Linnet Templates', 'linnet' ),
        'singular_name'      => __( 'Linnet Template', 'linnet' ),
        'add_new_item'       => __( 'Add New Linnet Template', 'linnet' ),
        'edit_item'          => __( 'Edit Linnet Template', 'linnet' ),
        'new_item'           => __( 'New Linnet Template', 'linnet' ),
        'view_item'          => __( 'View Linnet Template', 'linnet' ),
        'search_items'       => __( 'Search Linnet Templates', 'linnet' ),
        'not_found'          => __( 'No templates found', 'linnet' ),
        'not_found_in_trash' => __( 'No templates found in Trash', 'linnet' ),
    );

    $args = array(
        'labels'             => $labels,
        'public'             => true, // <--- CHANGED! Now visible on frontend
        'publicly_queryable' => true,  // <--- IMPORTANT
        'show_ui'            => true,
        'show_in_menu'       => false,
        'show_in_rest'       => true, // Enable Gutenberg editor
        'rest_base'          => 'linnet_templates',
        'supports'           => array( 'title', 'editor' ),
        'capability_type'    => 'post',
        'has_archive'        => false,
        'rewrite'            => array( 'slug' => 'linnet-template', 'with_front' => false ), // <--- ADD THIS!
    );

    register_post_type( 'linnet_template', $args );
}
add_action( 'init', 'linnet_register_templates_cpt' );


// 2. Admin Menus
function linnet_add_templates_menus() {
    add_menu_page(
        __( 'Linnet Templates', 'linnet' ),
        __( 'Linnet Templates', 'linnet' ),
        'manage_options',
        'edit.php?post_type=linnet_template',
        '',
        'dashicons-layout',
        20
    );
    add_submenu_page( 'edit.php?post_type=linnet_template', __( 'Templates', 'linnet' ), __( 'Templates', 'linnet' ), 'manage_options', 'edit.php?post_type=linnet_template' );
    add_submenu_page( 'edit.php?post_type=linnet_template', __( 'Archive Layouts', 'linnet' ), __( 'Archive', 'linnet' ), 'manage_options', 'linnet_templates_archive', 'linnet_render_archive_page' );
    add_submenu_page( 'edit.php?post_type=linnet_template', __( 'Post Layouts', 'linnet' ), __( 'Post', 'linnet' ), 'manage_options', 'linnet_templates_post', 'linnet_render_post_page' );
    add_submenu_page( 'edit.php?post_type=linnet_template', __( 'Taxonomy Layouts', 'linnet' ), __( 'Taxonomy', 'linnet' ), 'manage_options', 'linnet_templates_taxonomy', 'linnet_render_taxonomy_page' );
}
add_action( 'admin_menu', 'linnet_add_templates_menus' );

// 3. Save Handlers
function linnet_save_archive_layouts() {
    if ( ! current_user_can( 'manage_options' ) ) wp_die( __( 'Insufficient permissions', 'linnet' ) );
    check_admin_referer( 'linnet_archive_nonce' );
    $mapping = array_map( 'absint', (array) $_POST['linnet_archive'] );
    update_option( 'linnet_archive_templates', $mapping );
    wp_redirect( admin_url( 'admin.php?page=linnet_templates_archive&updated=1' ) );
    exit;
}
add_action( 'admin_post_linnet_save_archive', 'linnet_save_archive_layouts' );

function linnet_save_post_layouts() {
    if ( ! current_user_can( 'manage_options' ) ) wp_die();
    check_admin_referer( 'linnet_post_nonce' );
    $mapping = array_map( 'absint', (array) $_POST['linnet_post'] );
    update_option( 'linnet_post_templates', $mapping );
    wp_redirect( admin_url( 'admin.php?page=linnet_templates_post&updated=1' ) );
    exit;
}
add_action( 'admin_post_linnet_save_post', 'linnet_save_post_layouts' );

function linnet_save_taxonomy_layouts() {
    if ( ! current_user_can( 'manage_options' ) ) wp_die();
    check_admin_referer( 'linnet_taxonomy_nonce' );
    $mapping = array_map( 'absint', (array) $_POST['linnet_taxonomy'] );
    update_option( 'linnet_taxonomy_templates', $mapping );
    wp_redirect( admin_url( 'admin.php?page=linnet_templates_taxonomy&updated=1' ) );
    exit;
}
add_action( 'admin_post_linnet_save_taxonomy', 'linnet_save_taxonomy_layouts' );

// Helper: Fetch Linnet Templates
function linnet_get_templates() {
    $posts = get_posts( array(
        'post_type'      => 'linnet_template',
        'posts_per_page' => -1,
        'post_status'    => 'publish',
    ) );
    $list = array( 0 => __( '&mdash; None &mdash;', 'linnet' ) );
    foreach ( $posts as $p ) {
        $list[ $p->ID ] = $p->post_title;
    }
    return $list;
}

function linnet_render_archive_page() {
    $types   = get_post_types( array( 'has_archive' => true ), 'objects' );
    $options = linnet_get_templates();
    $current = (array) get_option( 'linnet_archive_templates', array() );
    ?>
    <div class="wrap"><h1><?php esc_html_e( 'Archive Layouts', 'linnet' ); ?></h1>
    <?php if ( isset( $_GET['updated'] ) ): ?><div class="updated notice"><p><?php esc_html_e( 'Settings saved.', 'linnet' ); ?></p></div><?php endif; ?>
    <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
        <?php wp_nonce_field( 'linnet_archive_nonce' ); ?>
        <input type="hidden" name="action" value="linnet_save_archive">
        <table class="form-table"><tbody>
        <?php foreach ( $types as $type ) : ?>
            <tr>
                <th><label><?php echo esc_html( $type->labels->name ); ?></label></th>
                <td><select name="linnet_archive[<?php echo esc_attr( $type->name ); ?>]">
                    <?php foreach ( $options as $id => $label ) : ?>
                        <option value="<?php echo esc_attr( $id ); ?>" <?php selected( $current[ $type->name ] ?? 0, $id ); ?>><?php echo esc_html( $label ); ?></option>
                    <?php endforeach; ?>
                </select></td>
            </tr>
        <?php endforeach; ?>
        </tbody></table>
        <?php submit_button(); ?>
    </form></div>
    <?php
}

function linnet_render_post_page() {
    $types   = get_post_types( array( 'public' => true ), 'objects' );
    $options = linnet_get_templates();
    $current = (array) get_option( 'linnet_post_templates', array() );
    ?>
    <div class="wrap"><h1><?php esc_html_e( 'Post Layouts', 'linnet' ); ?></h1>
    <?php if ( isset( $_GET['updated'] ) ): ?><div class="updated notice"><p><?php esc_html_e( 'Settings saved.', 'linnet' ); ?></p></div><?php endif; ?>
    <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
        <?php wp_nonce_field( 'linnet_post_nonce' ); ?>
        <input type="hidden" name="action" value="linnet_save_post">
        <table class="form-table"><tbody>
        <?php foreach ( $types as $type ) : ?>
            <tr>
                <th><label><?php echo esc_html( $type->labels->name ); ?></label></th>
                <td><select name="linnet_post[<?php echo esc_attr( $type->name ); ?>]">
                    <?php foreach ( $options as $id => $label ) : ?>
                        <option value="<?php echo esc_attr( $id ); ?>" <?php selected( $current[ $type->name ] ?? 0, $id ); ?>><?php echo esc_html( $label ); ?></option>
                    <?php endforeach; ?>
                </select></td>
            </tr>
        <?php endforeach; ?>
        </tbody></table>
        <?php submit_button(); ?>
    </form></div>
    <?php
}

function linnet_render_taxonomy_page() {
    $taxes   = get_taxonomies( array( 'public' => true ), 'objects' );
    $options = linnet_get_templates();
    $current = (array) get_option( 'linnet_taxonomy_templates', array() );
    ?>
    <div class="wrap"><h1><?php esc_html_e( 'Taxonomy Layouts', 'linnet' ); ?></h1>
    <?php if ( isset( $_GET['updated'] ) ): ?><div class="updated notice"><p><?php esc_html_e( 'Settings saved.', 'linnet' ); ?></p></div><?php endif; ?>
    <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
        <?php wp_nonce_field( 'linnet_taxonomy_nonce' ); ?>
        <input type="hidden" name="action" value="linnet_save_taxonomy">
        <table class="form-table"><tbody>
        <?php foreach ( $taxes as $tax ) : ?>
            <tr>
                <th><label><?php echo esc_html( $tax->labels->name ); ?></label></th>
                <td><select name="linnet_taxonomy[<?php echo esc_attr( $tax->name ); ?>]">
                    <?php foreach ( $options as $id => $label ) : ?>
                        <option value="<?php echo esc_attr( $id ); ?>" <?php selected( $current[ $tax->name ] ?? 0, $id ); ?>><?php echo esc_html( $label ); ?></option>
                    <?php endforeach; ?>
                </select></td>
            </tr>
        <?php endforeach; ?>
        </tbody></table>
        <?php submit_button(); ?>
    </form></div>
    <?php
}

function linnet_apply_linnet_template() {
    // Do not override when viewing Linnet Template itself
    if ( is_singular( 'linnet_template' ) ) {
        return;
    }

    $tid = 0;

    // Determine context
    if ( is_archive() && ! is_singular() && ! is_tax() ) {
        $ptype = get_post_type();
        $opt   = get_option( 'linnet_archive_templates', array() );
        $tid   = $opt[ $ptype ] ?? 0;
    } elseif ( is_singular() ) {
        $ptype = get_post_type();
        $opt   = get_option( 'linnet_post_templates', array() );
        $tid   = $opt[ $ptype ] ?? 0;
    } elseif ( is_tax() ) {
        $tax    = get_queried_object()->taxonomy;
        $opt    = get_option( 'linnet_taxonomy_templates', array() );
        $tid    = $opt[ $tax ] ?? 0;
    }

    if ( $tid ) {
        global $post;

        $post = get_post( $tid );
        setup_postdata( $post );

        // Render template content
        get_header();
        echo '<main id="primary" class="content-area">';
        echo '<div class="linnet-template-content">';
        echo apply_filters( 'the_content', get_post_field( 'post_content', $tid ) );
        echo '</div>';
        echo '</main>';
        get_footer();

        // Reset post
        wp_reset_postdata();

        // Prevent default template
        exit;
    }
}

add_action( 'template_redirect', 'linnet_apply_linnet_template', 5 );
  1. Now there is an new menu point called Linnet Templates in the left side admin menu click on that.
  2. Then click Add New Linnet Template.
  3. Give it a title click publish and then click edit with Elementor.
  4. Then you can add what you want there, that you want to show on the single page. In the video i am adding an container and then just a heading with Event single, then click publish.
  5. Then go back to the backend.
  6. Then click on Linnets Templates -> post.
  7. Here you can see the post types you have on the website, locate Events and then from the dropdown select the template you just created and click save changes.
  8. Now if you go to a single event url, it will show your template.