Plugin Directory

Changeset 3748592


Ignore:
Timestamp:
10/15/2026 01:35:56 PM (4 weeks ago)
Author:
qreativethemes
Message:

Release version 1.0.6 with updated readme and plugin artwork

Location:
qreative-header-footer-designer
Files:
20 added
2 deleted
12 edited
1 copied

Legend:

Unmodified
Added
Removed
  • qreative-header-footer-designer/assets/icon-128x128.png

    • Property svn:mime-type changed from application/octet-stream to image/png
  • qreative-header-footer-designer/assets/icon-256x256.png

    • Property svn:mime-type changed from application/octet-stream to image/png
  • qreative-header-footer-designer/tags/1.0.6/includes/class-admin-columns.php

    r3685252 r3748592  
    2121                add_filter( 'manage_' . QREATIVE_HFD_POST_TYPE . '_posts_columns', array( $this, 'add_columns' ) );
    2222                add_action( 'manage_' . QREATIVE_HFD_POST_TYPE . '_posts_custom_column', array( $this, 'render_column' ), 10, 2 );
     23                add_filter( 'post_row_actions', array( $this, 'add_duplicate_action' ), 10, 2 );
     24                add_action( 'admin_action_qreative_hfd_duplicate_template', array( $this, 'duplicate_template' ) );
    2325                add_filter( 'views_edit-' . QREATIVE_HFD_POST_TYPE, array( $this, 'render_template_type_filters' ), 5 );
    2426                add_action( 'pre_get_posts', array( $this, 'filter_templates_by_type' ) );
    2527                add_action( 'wp_ajax_qreative_hfd_update_template_priority', array( $this, 'ajax_update_template_priority' ) );
    2628                add_filter( 'gettext', array( $this, 'replace_empty_list_message' ), 10, 3 );
     29        }
     30
     31        /**
     32         * Add a Duplicate link to each template's list-table row actions.
     33         *
     34         * @param string[] $actions Existing row actions.
     35         * @param WP_Post  $post    Current post.
     36         * @return string[]
     37         */
     38        public function add_duplicate_action( $actions, $post ) {
     39                if (
     40                        ! $post instanceof WP_Post
     41                        || QREATIVE_HFD_POST_TYPE !== $post->post_type
     42                        || ! current_user_can( 'edit_post', $post->ID )
     43                ) {
     44                        return $actions;
     45                }
     46
     47                $url = wp_nonce_url(
     48                        add_query_arg(
     49                                array(
     50                                        'action' => 'qreative_hfd_duplicate_template',
     51                                        'post'   => $post->ID,
     52                                ),
     53                                admin_url( 'admin.php' )
     54                        ),
     55                        'qreative_hfd_duplicate_template_' . $post->ID
     56                );
     57
     58                $actions['qreative_hfd_duplicate'] = sprintf(
     59                        '<a href="%1$s" aria-label="%2$s">%3$s</a>',
     60                        esc_url( $url ),
     61                        /* translators: %s: Template title. */
     62                        esc_attr( sprintf( __( 'Duplicate “%s”', 'qreative-header-footer-designer' ), $post->post_title ) ),
     63                        esc_html__( 'Duplicate', 'qreative-header-footer-designer' )
     64                );
     65
     66                return $actions;
     67        }
     68
     69        /**
     70         * Duplicate a builder template as an inactive draft, then open it for editing.
     71         */
     72        public function duplicate_template() {
     73                $post_id = isset( $_GET['post'] ) && is_scalar( $_GET['post'] )
     74                        ? absint( wp_unslash( $_GET['post'] ) )
     75                        : 0;
     76
     77                check_admin_referer( 'qreative_hfd_duplicate_template_' . $post_id );
     78
     79                $post = $post_id ? get_post( $post_id ) : null;
     80
     81                if ( ! $post instanceof WP_Post || QREATIVE_HFD_POST_TYPE !== $post->post_type ) {
     82                        wp_die(
     83                                esc_html__( 'The template to duplicate could not be found.', 'qreative-header-footer-designer' ),
     84                                esc_html__( 'Template not found', 'qreative-header-footer-designer' ),
     85                                array( 'response' => 404 )
     86                        );
     87                }
     88
     89                if ( ! current_user_can( 'edit_post', $post_id ) || ! current_user_can( 'edit_posts' ) ) {
     90                        wp_die(
     91                                esc_html__( 'You are not allowed to duplicate this template.', 'qreative-header-footer-designer' ),
     92                                esc_html__( 'Access denied', 'qreative-header-footer-designer' ),
     93                                array( 'response' => 403 )
     94                        );
     95                }
     96
     97                $new_post_id = wp_insert_post(
     98                        array(
     99                                'post_author'           => get_current_user_id(),
     100                                'post_content'          => $post->post_content,
     101                                'post_content_filtered' => $post->post_content_filtered,
     102                                'post_excerpt'          => $post->post_excerpt,
     103                                /* translators: %s: Original template title. */
     104                                'post_title'            => sprintf( __( '%s — Copy', 'qreative-header-footer-designer' ), $post->post_title ),
     105                                'post_status'           => 'draft',
     106                                'post_type'             => QREATIVE_HFD_POST_TYPE,
     107                                'comment_status'        => $post->comment_status,
     108                                'ping_status'           => $post->ping_status,
     109                                'menu_order'            => $post->menu_order,
     110                                'post_parent'           => $post->post_parent,
     111                        ),
     112                        true
     113                );
     114
     115                if ( is_wp_error( $new_post_id ) ) {
     116                        wp_die(
     117                                esc_html( $new_post_id->get_error_message() ),
     118                                esc_html__( 'Duplication failed', 'qreative-header-footer-designer' ),
     119                                array( 'response' => 500 )
     120                        );
     121                }
     122
     123                /**
     124                 * Filters metadata keys that should not be copied to a duplicated template.
     125                 *
     126                 * @param string[] $excluded_meta_keys Metadata keys to skip.
     127                 * @param int      $post_id            Source template ID.
     128                 * @param int      $new_post_id        Duplicated template ID.
     129                 */
     130                $excluded_meta_keys = apply_filters(
     131                        'qreative_hfd_duplicate_excluded_meta_keys',
     132                        array( '_edit_lock', '_edit_last', '_elementor_css' ),
     133                        $post_id,
     134                        $new_post_id
     135                );
     136                $excluded_meta_keys = is_array( $excluded_meta_keys ) ? $excluded_meta_keys : array();
     137
     138                // These defaults are added during insertion and must not override the source values.
     139                delete_post_meta( $new_post_id, '_qreative_hfd_template_active' );
     140                delete_post_meta( $new_post_id, '_qreative_hfd_template_priority' );
     141
     142                foreach ( get_post_meta( $post_id ) as $meta_key => $meta_values ) {
     143                        // Locks and generated Elementor CSS belong to the source post.
     144                        if ( in_array( $meta_key, $excluded_meta_keys, true ) ) {
     145                                continue;
     146                        }
     147
     148                        // Preserve metadata that other plugins may have added to the new post.
     149                        delete_post_meta( $new_post_id, $meta_key );
     150
     151                        foreach ( $meta_values as $meta_value ) {
     152                                add_post_meta( $new_post_id, $meta_key, maybe_unserialize( $meta_value ) );
     153                        }
     154                }
     155
     156                // Avoid activating two templates with the same display conditions.
     157                update_post_meta( $new_post_id, '_qreative_hfd_template_active', '' );
     158
     159                wp_safe_redirect( get_edit_post_link( $new_post_id, 'raw' ) );
     160                exit;
    27161        }
    28162
  • qreative-header-footer-designer/tags/1.0.6/includes/class-meta-fields.php

    r3685252 r3748592  
    3535         */
    3636        public function register_fields() {
    37                 add_action( 'add_meta_boxes',         array( $this, 'add_meta_boxes' ) );
     37                add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
    3838                add_action( 'add_meta_boxes_' . QREATIVE_HFD_POST_TYPE, array( $this, 'remove_default_meta_boxes' ), 20 );
    3939                add_action( 'save_post_' . QREATIVE_HFD_POST_TYPE, array( $this, 'save_meta' ), 10, 2 );
    … …  
    302302                $type_icons                  = $state['type_icons'];
    303303                $activation_errors           = $this->get_activation_errors_from_request();
    304 
    305304                ?>
     305
    306306                <div id="qt-hf-meta-box">
    307 
    308                         <?php // Active banner ?>
    309307                        <div class="qt-hf-active-banner">
    310308                                <div class="qt-hf-active-label">
    … …  
    324322                        </div>
    325323
    326                         <?php // Template type ?>
    327324                        <div class="qt-hf-section qt-hf-section--settings-layout qt-hf-section--template-type">
    328325                                <div id="qt-hf-type-validation"
    … …  
    357354
    358355                                                $field_id = 'qt-hf-type-' . sanitize_html_class( $val );
    359                                         ?>
    360                                         <div class="qt-hf-type-card">
    361                                                 <input type="radio" class="qt-hf-choice-input"
    362                                                        id="<?php echo esc_attr( $field_id ); ?>"
    363                                                        name="qreative_hfd_template_type"
    364                                                        value="<?php echo esc_attr( $val ); ?>"
    365                                                        <?php checked( $type, $val ); ?>>
    366                                                 <label class="qt-hf-control-surface qt-hf-type-card-surface" for="<?php echo esc_attr( $field_id ); ?>">
    367                                                         <span class="qt-hf-type-icon">
    368                                                                         <?php
    369                                                                         echo wp_kses(
    370                                                                                 isset( $type_icons[ $val ] ) ? $type_icons[ $val ] : '',
    371                                                                                 $this->get_svg_icon_allowed_html()
    372                                                                         );
    373                                                                         ?>
    374                                                         </span>
    375                                                         <?php echo esc_html( $label ); ?>
    376                                                 </label>
    377                                         </div>
     356                                                ?>
     357                                                <div class="qt-hf-type-card">
     358                                                        <input type="radio" class="qt-hf-choice-input"
     359                                                               id="<?php echo esc_attr( $field_id ); ?>"
     360                                                               name="qreative_hfd_template_type"
     361                                                               value="<?php echo esc_attr( $val ); ?>"
     362                                                               <?php checked( $type, $val ); ?>>
     363                                                        <label class="qt-hf-control-surface qt-hf-type-card-surface" for="<?php echo esc_attr( $field_id ); ?>">
     364                                                                <span class="qt-hf-type-icon">
     365                                                                                <?php
     366                                                                                echo wp_kses(
     367                                                                                        isset( $type_icons[ $val ] ) ? $type_icons[ $val ] : '',
     368                                                                                        $this->get_svg_icon_allowed_html()
     369                                                                                );
     370                                                                                ?>
     371                                                                </span>
     372                                                                <?php echo esc_html( $label ); ?>
     373                                                        </label>
     374                                                </div>
    378375                                        <?php endforeach; ?>
    379376
    … …  
    435432                        </div>
    436433
    437                         <?php // Display On ?>
    438434                        <div class="qt-hf-section qt-hf-section--settings-layout qt-hf-section--display-conditions">
    439435                                <?php
    … …  
    557553                                                <?php endif; ?>
    558554
    559                                                         <?php // Specific pages/posts picker ?>
    560                                                         <div id="qt-hf-specific-section" class="qt-hf-picker-section">
     555                                                <div id="qt-hf-specific-section" class="qt-hf-picker-section">
    561556                                                        <div class="qt-hf-section-head">
    562557                                                                <h3 class="qt-hf-control-label"><?php esc_html_e( 'Include Specific Pages / Posts', 'qreative-header-footer-designer' ); ?></h3>
    … …  
    573568                                                        </div>
    574569
    575                                                 <?php // Exclude picker ?>
    576570                                                        <div id="qt-hf-exclude-section" class="qt-hf-picker-section qt-hf-picker-section--exclude">
    577                                                         <div class="qt-hf-section-head">
    578                                                                 <h3 class="qt-hf-control-label"><?php esc_html_e( 'Exclude Specific Pages / Posts', 'qreative-header-footer-designer' ); ?></h3>
     571                                                                <div class="qt-hf-section-head">
     572                                                                        <h3 class="qt-hf-control-label"><?php esc_html_e( 'Exclude Specific Pages / Posts', 'qreative-header-footer-designer' ); ?></h3>
     573                                                                </div>
     574                                                                <p class="qt-hf-setting-description"><?php esc_html_e( 'Hide this template on selected pages or posts.', 'qreative-header-footer-designer' ); ?></p>
     575                                                                <?php
     576                                                                        $this->render_ajax_post_picker(
     577                                                                                'qt-hf-exclude',
     578                                                                                'qreative_hfd_exclude_pages_posts[]',
     579                                                                                $exclude_ids,
     580                                                                                esc_attr__( 'Search pages and posts to exclude…', 'qreative-header-footer-designer' )
     581                                                                        );
     582                                                                ?>
    579583                                                        </div>
    580                                                         <p class="qt-hf-setting-description"><?php esc_html_e( 'Hide this template on selected pages or posts.', 'qreative-header-footer-designer' ); ?></p>
    581                                                                 <?php
    582                                                                 $this->render_ajax_post_picker(
    583                                                                         'qt-hf-exclude',
    584                                                                         'qreative_hfd_exclude_pages_posts[]',
    585                                                                         $exclude_ids,
    586                                                                         esc_attr__( 'Search pages and posts to exclude…', 'qreative-header-footer-designer' )
    587                                                                 );
    588                                                                         ?>
    589                                                                 </div>
    590584                                                </div>
    591585                                </div>
  • qreative-header-footer-designer/tags/1.0.6/qreative-header-footer-designer.php

    r3685252 r3748592  
    44 * Plugin URI:                  https://www.qreativethemes.com/header-footer-builder/
    55 * Description:                 Build your theme header & footer with Elementor, works with classic WordPress themes.
    6  * Version:                     1.0.5
     6 * Version:                     1.0.6
    77 * Author:                      QreativeThemes
    88 * Author URI:                  https://www.qreativethemes.com/
    … …  
    2222}
    2323
    24 define( 'QREATIVE_HFD_VERSION',   '1.0.5' );
     24define( 'QREATIVE_HFD_VERSION',   '1.0.6' );
    2525define( 'QREATIVE_HFD_PATH',      plugin_dir_path( __FILE__ ) );
    2626define( 'QREATIVE_HFD_URL',       plugin_dir_url( __FILE__ ) );
  • qreative-header-footer-designer/tags/1.0.6/readme.txt

    r3685252 r3748592  
    66Requires PHP: 7.4
    77Requires Plugins: elementor
    8 Stable tag: 1.0.5
     8Stable tag: 1.0.6
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1111
    12 Create custom WordPress headers and footers with Elementor, display them exactly where you need them, and leave your theme files untouched.
     12Design custom WordPress headers and footers with Elementor, control where they appear, and leave your theme files untouched.
    1313
    1414== Description ==
    1515
    16 Take control of your WordPress header and footer without editing theme files or setting up a complete theme builder.
     16Build custom WordPress headers and footers without editing theme files or setting up a full theme builder.
    1717
    18 Qreative Header Footer Designer gives you a focused place to create header and footer templates, design them visually with Elementor, and choose exactly where they appear. Use one layout across your whole website or create different designs for specific pages, posts, and WordPress views.
     18Qreative Header Footer Designer gives you a place to create templates, design them visually with Elementor, and decide where they appear. Use one layout across your website or assign different designs to specific posts and pages.
    1919
    20 It works with the Elementor editor you already know, includes dedicated widgets for your logo, navigation, search overlay, and dynamic copyright notice.
     20The plugin works with the Elementor editor and includes dedicated widgets for your logo, navigation, search overlay, and dynamic copyright notice.
     21
     22https://www.youtube.com/watch?v=FvCszM2vnEA
    2123
    2224= 🎨 Create your header or footer in three steps =
    … …  
    26283. Build the layout visually with Elementor.
    2729
    28 That is all you need to replace your theme's standard header or footer with a design that fits your website.
     30Your new design replaces the theme's standard header or footer wherever its display conditions match.
    2931
    3032= ✨ What you can do =
    3133
    32 * **Design with Elementor:** Use Elementor containers, widgets, responsive controls, and styling options.
     34* **Design with Elementor:** Build layouts with Elementor containers, widgets, responsive controls, and styling options.
    3335* **Replace theme headers and footers:** Create custom layouts without modifying theme files.
    34 * **Control where templates appear:** Display a template across the entire website or target the front page, blog, pages, posts, archives, search results, or the 404 page.
    35 * **Include or exclude specific content:** Assign layouts to selected pages and posts or prevent them from appearing in particular places.
    36 * **Create sticky headers:** Keep important navigation visible while visitors scroll.
    37 * **Manage multiple templates:** Activate templates, set priorities, and quickly filter the template overview by type.
    38 * **Build multilingual layouts:** Use translated templates with WPML or Polylang.
     36* **Control where templates appear:** Show a template across the entire website or target the front page, blog, pages, posts, archives, search results, or 404 page.
     37* **Include or exclude specific content:** Assign layouts to selected pages and posts, or exclude them from particular locations.
     38* **Create sticky headers:** Keep navigation visible as visitors scroll.
     39* **Manage multiple templates:** Activate templates, set their priority, and filter the template overview by type.
     40* **Build multilingual layouts:** Create translated templates with WPML or Polylang.
    3941
    4042= 🧰 Included Elementor widgets =
    4143
    42 The plugin includes the essential elements needed for a practical website header:
     44The plugin includes four widgets for building practical headers and footers:
    4345
    44 * **Qreative: Site Logo** – Display the logo configured in WordPress Site Identity.
    45 * **Qreative: Menu** – Add and style an existing WordPress navigation menu, including responsive mobile navigation.
    46 * **Qreative: Search Overlay** – Add a compact search trigger that opens an overlay search form.
    47 * **Qreative: Copyright** – Display the current year, your site title, and optional text on either side.
     46* **Qreative: Site Logo** – Displays the logo configured in WordPress Site Identity.
     47* **Qreative: Menu** – Adds and styles an existing WordPress menu, with responsive mobile navigation.
     48* **Qreative: Search Overlay** – Adds a compact trigger that opens an overlay search form.
     49* **Qreative: Copyright** – Displays the current year, your site title, and optional text before or after it.
    4850
    4951= 🎯 Flexible display conditions =
    5052
    51 Choose where every template should be used:
     53Set display rules for each template:
    5254
    5355* Start with broad rules such as Entire Website, All Pages, or All Posts.
    5456* Target common WordPress views such as archives, search results, and the 404 page.
    55 * Select individual pages or posts when a layout is only needed in specific places.
     57* Select individual pages or posts when a layout belongs in specific places.
    5658* Add exclusions that always take priority over broader include rules.
    5759
    58 This makes it easy to use a global header, create a simplified layout for landing pages, or show a different footer in selected areas of your website.
     60Use a global header across the site, a simpler layout for landing pages, or a different footer in selected sections.
    5961
    6062= 🚀 Need more than headers and footers? =
    6163
    62 [Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro) gives you more creative freedom to build a polished, engaging website with Elementor:
     64[Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro) adds more template types, targeting options, and navigation features:
    6365
    64 * **Build richer navigation with mega menus:** Create visually engaging menus that help visitors explore more of your website.
    65 * **Create off-canvas panels:** Keep useful content within easy reach while giving your page design room to breathe.
    66 * **Highlight key messages with announcement bars:** Give promotions and important updates a prominent place on your website without interrupting the browsing experience.
    67 * **Design popups and modals in Elementor:** Bring attention to important messages with designs that feel like a natural part of your website.
    68 * **Reuse sections across your website:** Save time and keep your design consistent with reusable content sections.
    69 * **Target WooCommerce and custom post types:** Create tailored layouts for your store and custom content for a more cohesive website experience.
    70 * **Personalize the experience with Smart Targeting:** Show relevant content to the right visitors at the right time for a more engaging website experience.
    71 * **Add a better WooCommerce cart experience:** Make it easy for shoppers to review their cart while continuing to explore your store.
    72 * **Unlock advanced sticky header controls:** Go beyond the free plugin’s sticky headers with more control over when your header stays visible as visitors scroll.
     66* **Build mega menus:** Create larger, visual navigation layouts that help visitors find more of your content.
     67* **Create off-canvas panels:** Place navigation or supporting content in panels that open when needed.
     68* **Publish announcement bars:** Give promotions and updates a clear place on your website.
     69* **Design popups and modals in Elementor:** Build overlays that match the rest of your site.
     70* **Reusable global sections:** Maintain shared sections in one place and use them across your website.
     71* **Target WooCommerce and custom post types:** Assign layouts to store pages and custom content.
     72* **Use Smart Targeting:** Show different content based on visitor and browsing conditions.
     73* **Add a WooCommerce cart widget:** Open cart contents in a fully customizable slide-out panel, so shoppers can review their order without leaving the page.
     74* **Customize the sticky header state:** Give the header a different design when it becomes sticky and control how it behaves while visitors scroll.
    7375
    74 The free plugin remains fully functional for building and displaying custom headers and footers. Pro is an optional add-on for websites that need more creative possibilities.
     76The free plugin includes everything needed to build and display custom headers and footers. Pro is optional and intended for sites that need more layout types or targeting control.
    7577
    7678[Discover Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro)
    … …  
    7880= ⚙️ Requirements and compatibility =
    7981
    80 Elementor must be installed and active. Qreative Header Footer Designer is intended primarily for classic WordPress themes. Block themes already provide header and footer editing through the Site Editor, so compatibility can vary by theme.
     82Elementor must be installed and active. Qreative Header Footer Designer is built primarily for classic WordPress themes. Block themes manage headers and footers through the Site Editor, so compatibility varies by theme.
    8183
    8284== Installation ==
    … …  
    9092== Screenshots ==
    9193
    92 1. Manage header and footer templates, priorities, and active status from one overview.
     941. Manage header and footer templates, priorities, and active status from a single overview.
    93952. Configure an active header template and its display conditions.
    94 3. Build the header template in Elementor editor.
    95 4. Header template shows up on the website.
     963. Build the header template in the Elementor editor.
     974. View the finished header on the website.
    9698
    9799== Frequently Asked Questions ==
    … …  
    99101= Does this plugin require Elementor? =
    100102
    101 Yes. Elementor must be installed and active because the header and footer templates are edited with Elementor.
     103Yes. Elementor must be installed and active because you build the header and footer templates in its editor.
    102104
    103105= Does it work with every WordPress theme? =
    104106
    105 The plugin is designed primarily for classic WordPress themes. Block themes manage headers and footers through the WordPress Site Editor, so compatibility can vary.
     107The plugin is designed primarily for classic WordPress themes. Block themes manage headers and footers through the WordPress Site Editor, so compatibility varies by theme.
    106108
    107109= Can I use my existing WordPress menus? =
    … …  
    115117= Can I use different headers or footers on different pages? =
    116118
    117 Yes. Display conditions let you target the entire website, common WordPress views, or selected pages and posts. You can also exclude specific content from broader rules.
     119Yes. Display conditions can target the entire website, common WordPress views, or selected pages and posts. Exclusions let you remove specific content from broader rules.
    118120
    119121= Which Elementor widgets are included? =
    … …  
    123125= Does it support multilingual websites? =
    124126
    125 Yes. Header and footer templates and page-specific display conditions are compatible with WPML and Polylang workflows.
     127Yes. Header and footer templates and page-specific display conditions work with WPML and Polylang workflows.
    126128
    127129= Where can I find the documentation? =
    … …  
    131133= Is there a Pro version? =
    132134
    133 Yes. Pro extends the free plugin with mega menus, off-canvas panels, announcement bars, Elementor-designed popups and modals, reusable content sections, WooCommerce and custom post type display conditions, Smart Targeting, an enhanced WooCommerce cart experience, and advanced sticky header controls. [Explore Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro).
     135Yes. Pro adds mega menus, off-canvas panels, announcement bars, Elementor-designed popups and modals, reusable content sections, WooCommerce and custom post type display conditions, Smart Targeting, an enhanced WooCommerce cart, and advanced sticky header controls. [Explore Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro).
    134136
    135137== Changelog ==
     138
     139= 1.0.6 =
     140* Added a secure Duplicate action to the template overview that copies Elementor content and template settings into a new inactive draft.
     141* Changed uninstall behavior to always preserve user-created templates, Elementor designs, and display settings when the plugin is deleted.
    136142
    137143= 1.0.5 =
  • qreative-header-footer-designer/tags/1.0.6/uninstall.php

    r3595054 r3748592  
    33 * Uninstall — runs when the plugin is deleted from wp-admin.
    44 *
    5  * Removes all post meta stored by this plugin (_qreative_hfd_* keys) for every
    6  * builder post, then deletes all builder posts themselves.
    7  * Does NOT remove posts/pages built with the templates — only the
    8  * template definitions created by this plugin.
     5 * User-created templates and their Elementor data are deliberately preserved so
     6 * they remain available if the plugin is installed again.
    97 *
    108 * @package qreative-header-footer-designer
    … …  
    1614}
    1715
    18 global $wpdb;
    19 
    20 $qreative_hfd_post_type = 'qreative_hfd_tpl';
    21 
    22 // Retrieve all builder post IDs.
    23 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    24 $qreative_hfd_post_ids = $wpdb->get_col(
    25         $wpdb->prepare(
    26                 "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s",
    27                 $qreative_hfd_post_type
    28         )
    29 );
    30 
    31 if ( ! empty( $qreative_hfd_post_ids ) ) {
    32         // Delete all _qreative_hfd_ meta for these posts.
    33         foreach ( $qreative_hfd_post_ids as $qreative_hfd_post_id ) {
    34                 $qreative_hfd_post_id = absint( $qreative_hfd_post_id );
    35 
    36                 $qreative_hfd_keys_to_delete = array(
    37                         '_qreative_hfd_template_active',
    38                         '_qreative_hfd_template_type',
    39                         '_qreative_hfd_sticky_enabled',
    40                         '_qreative_hfd_template_priority',
    41                         '_qreative_hfd_display_on',
    42                         '_qreative_hfd_specific_pages_posts',
    43                         '_qreative_hfd_exclude_pages_posts',
    44                 );
    45 
    46                 foreach ( $qreative_hfd_keys_to_delete as $qreative_hfd_key ) {
    47                         delete_post_meta( $qreative_hfd_post_id, $qreative_hfd_key );
    48                 }
    49 
    50                 // Force-delete (bypass trash) so the CPT posts are fully removed.
    51                 wp_delete_post( $qreative_hfd_post_id, true );
    52         }
    53 }
    54 
    55 // Elementor owns this option name; remove only this plugin's CPT from Elementor's supported post types.
    56 $qreative_hfd_elementor_cpt_support = get_option( 'elementor_cpt_support' );
    57 if ( is_array( $qreative_hfd_elementor_cpt_support ) && in_array( $qreative_hfd_post_type, $qreative_hfd_elementor_cpt_support, true ) ) {
    58         update_option( 'elementor_cpt_support', array_values( array_diff( $qreative_hfd_elementor_cpt_support, array( $qreative_hfd_post_type ) ) ) );
    59 }
     16// Remove the legacy uninstall preference used briefly in version 1.0.6.
     17delete_option( 'qreative_hfd_delete_data_on_uninstall' );
  • qreative-header-footer-designer/trunk/includes/class-admin-columns.php

    r3685252 r3748592  
    2121                add_filter( 'manage_' . QREATIVE_HFD_POST_TYPE . '_posts_columns', array( $this, 'add_columns' ) );
    2222                add_action( 'manage_' . QREATIVE_HFD_POST_TYPE . '_posts_custom_column', array( $this, 'render_column' ), 10, 2 );
     23                add_filter( 'post_row_actions', array( $this, 'add_duplicate_action' ), 10, 2 );
     24                add_action( 'admin_action_qreative_hfd_duplicate_template', array( $this, 'duplicate_template' ) );
    2325                add_filter( 'views_edit-' . QREATIVE_HFD_POST_TYPE, array( $this, 'render_template_type_filters' ), 5 );
    2426                add_action( 'pre_get_posts', array( $this, 'filter_templates_by_type' ) );
    2527                add_action( 'wp_ajax_qreative_hfd_update_template_priority', array( $this, 'ajax_update_template_priority' ) );
    2628                add_filter( 'gettext', array( $this, 'replace_empty_list_message' ), 10, 3 );
     29        }
     30
     31        /**
     32         * Add a Duplicate link to each template's list-table row actions.
     33         *
     34         * @param string[] $actions Existing row actions.
     35         * @param WP_Post  $post    Current post.
     36         * @return string[]
     37         */
     38        public function add_duplicate_action( $actions, $post ) {
     39                if (
     40                        ! $post instanceof WP_Post
     41                        || QREATIVE_HFD_POST_TYPE !== $post->post_type
     42                        || ! current_user_can( 'edit_post', $post->ID )
     43                ) {
     44                        return $actions;
     45                }
     46
     47                $url = wp_nonce_url(
     48                        add_query_arg(
     49                                array(
     50                                        'action' => 'qreative_hfd_duplicate_template',
     51                                        'post'   => $post->ID,
     52                                ),
     53                                admin_url( 'admin.php' )
     54                        ),
     55                        'qreative_hfd_duplicate_template_' . $post->ID
     56                );
     57
     58                $actions['qreative_hfd_duplicate'] = sprintf(
     59                        '<a href="%1$s" aria-label="%2$s">%3$s</a>',
     60                        esc_url( $url ),
     61                        /* translators: %s: Template title. */
     62                        esc_attr( sprintf( __( 'Duplicate “%s”', 'qreative-header-footer-designer' ), $post->post_title ) ),
     63                        esc_html__( 'Duplicate', 'qreative-header-footer-designer' )
     64                );
     65
     66                return $actions;
     67        }
     68
     69        /**
     70         * Duplicate a builder template as an inactive draft, then open it for editing.
     71         */
     72        public function duplicate_template() {
     73                $post_id = isset( $_GET['post'] ) && is_scalar( $_GET['post'] )
     74                        ? absint( wp_unslash( $_GET['post'] ) )
     75                        : 0;
     76
     77                check_admin_referer( 'qreative_hfd_duplicate_template_' . $post_id );
     78
     79                $post = $post_id ? get_post( $post_id ) : null;
     80
     81                if ( ! $post instanceof WP_Post || QREATIVE_HFD_POST_TYPE !== $post->post_type ) {
     82                        wp_die(
     83                                esc_html__( 'The template to duplicate could not be found.', 'qreative-header-footer-designer' ),
     84                                esc_html__( 'Template not found', 'qreative-header-footer-designer' ),
     85                                array( 'response' => 404 )
     86                        );
     87                }
     88
     89                if ( ! current_user_can( 'edit_post', $post_id ) || ! current_user_can( 'edit_posts' ) ) {
     90                        wp_die(
     91                                esc_html__( 'You are not allowed to duplicate this template.', 'qreative-header-footer-designer' ),
     92                                esc_html__( 'Access denied', 'qreative-header-footer-designer' ),
     93                                array( 'response' => 403 )
     94                        );
     95                }
     96
     97                $new_post_id = wp_insert_post(
     98                        array(
     99                                'post_author'           => get_current_user_id(),
     100                                'post_content'          => $post->post_content,
     101                                'post_content_filtered' => $post->post_content_filtered,
     102                                'post_excerpt'          => $post->post_excerpt,
     103                                /* translators: %s: Original template title. */
     104                                'post_title'            => sprintf( __( '%s — Copy', 'qreative-header-footer-designer' ), $post->post_title ),
     105                                'post_status'           => 'draft',
     106                                'post_type'             => QREATIVE_HFD_POST_TYPE,
     107                                'comment_status'        => $post->comment_status,
     108                                'ping_status'           => $post->ping_status,
     109                                'menu_order'            => $post->menu_order,
     110                                'post_parent'           => $post->post_parent,
     111                        ),
     112                        true
     113                );
     114
     115                if ( is_wp_error( $new_post_id ) ) {
     116                        wp_die(
     117                                esc_html( $new_post_id->get_error_message() ),
     118                                esc_html__( 'Duplication failed', 'qreative-header-footer-designer' ),
     119                                array( 'response' => 500 )
     120                        );
     121                }
     122
     123                /**
     124                 * Filters metadata keys that should not be copied to a duplicated template.
     125                 *
     126                 * @param string[] $excluded_meta_keys Metadata keys to skip.
     127                 * @param int      $post_id            Source template ID.
     128                 * @param int      $new_post_id        Duplicated template ID.
     129                 */
     130                $excluded_meta_keys = apply_filters(
     131                        'qreative_hfd_duplicate_excluded_meta_keys',
     132                        array( '_edit_lock', '_edit_last', '_elementor_css' ),
     133                        $post_id,
     134                        $new_post_id
     135                );
     136                $excluded_meta_keys = is_array( $excluded_meta_keys ) ? $excluded_meta_keys : array();
     137
     138                // These defaults are added during insertion and must not override the source values.
     139                delete_post_meta( $new_post_id, '_qreative_hfd_template_active' );
     140                delete_post_meta( $new_post_id, '_qreative_hfd_template_priority' );
     141
     142                foreach ( get_post_meta( $post_id ) as $meta_key => $meta_values ) {
     143                        // Locks and generated Elementor CSS belong to the source post.
     144                        if ( in_array( $meta_key, $excluded_meta_keys, true ) ) {
     145                                continue;
     146                        }
     147
     148                        // Preserve metadata that other plugins may have added to the new post.
     149                        delete_post_meta( $new_post_id, $meta_key );
     150
     151                        foreach ( $meta_values as $meta_value ) {
     152                                add_post_meta( $new_post_id, $meta_key, maybe_unserialize( $meta_value ) );
     153                        }
     154                }
     155
     156                // Avoid activating two templates with the same display conditions.
     157                update_post_meta( $new_post_id, '_qreative_hfd_template_active', '' );
     158
     159                wp_safe_redirect( get_edit_post_link( $new_post_id, 'raw' ) );
     160                exit;
    27161        }
    28162
  • qreative-header-footer-designer/trunk/includes/class-meta-fields.php

    r3685252 r3748592  
    3535         */
    3636        public function register_fields() {
    37                 add_action( 'add_meta_boxes',         array( $this, 'add_meta_boxes' ) );
     37                add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
    3838                add_action( 'add_meta_boxes_' . QREATIVE_HFD_POST_TYPE, array( $this, 'remove_default_meta_boxes' ), 20 );
    3939                add_action( 'save_post_' . QREATIVE_HFD_POST_TYPE, array( $this, 'save_meta' ), 10, 2 );
    … …  
    302302                $type_icons                  = $state['type_icons'];
    303303                $activation_errors           = $this->get_activation_errors_from_request();
    304 
    305304                ?>
     305
    306306                <div id="qt-hf-meta-box">
    307 
    308                         <?php // Active banner ?>
    309307                        <div class="qt-hf-active-banner">
    310308                                <div class="qt-hf-active-label">
    … …  
    324322                        </div>
    325323
    326                         <?php // Template type ?>
    327324                        <div class="qt-hf-section qt-hf-section--settings-layout qt-hf-section--template-type">
    328325                                <div id="qt-hf-type-validation"
    … …  
    357354
    358355                                                $field_id = 'qt-hf-type-' . sanitize_html_class( $val );
    359                                         ?>
    360                                         <div class="qt-hf-type-card">
    361                                                 <input type="radio" class="qt-hf-choice-input"
    362                                                        id="<?php echo esc_attr( $field_id ); ?>"
    363                                                        name="qreative_hfd_template_type"
    364                                                        value="<?php echo esc_attr( $val ); ?>"
    365                                                        <?php checked( $type, $val ); ?>>
    366                                                 <label class="qt-hf-control-surface qt-hf-type-card-surface" for="<?php echo esc_attr( $field_id ); ?>">
    367                                                         <span class="qt-hf-type-icon">
    368                                                                         <?php
    369                                                                         echo wp_kses(
    370                                                                                 isset( $type_icons[ $val ] ) ? $type_icons[ $val ] : '',
    371                                                                                 $this->get_svg_icon_allowed_html()
    372                                                                         );
    373                                                                         ?>
    374                                                         </span>
    375                                                         <?php echo esc_html( $label ); ?>
    376                                                 </label>
    377                                         </div>
     356                                                ?>
     357                                                <div class="qt-hf-type-card">
     358                                                        <input type="radio" class="qt-hf-choice-input"
     359                                                               id="<?php echo esc_attr( $field_id ); ?>"
     360                                                               name="qreative_hfd_template_type"
     361                                                               value="<?php echo esc_attr( $val ); ?>"
     362                                                               <?php checked( $type, $val ); ?>>
     363                                                        <label class="qt-hf-control-surface qt-hf-type-card-surface" for="<?php echo esc_attr( $field_id ); ?>">
     364                                                                <span class="qt-hf-type-icon">
     365                                                                                <?php
     366                                                                                echo wp_kses(
     367                                                                                        isset( $type_icons[ $val ] ) ? $type_icons[ $val ] : '',
     368                                                                                        $this->get_svg_icon_allowed_html()
     369                                                                                );
     370                                                                                ?>
     371                                                                </span>
     372                                                                <?php echo esc_html( $label ); ?>
     373                                                        </label>
     374                                                </div>
    378375                                        <?php endforeach; ?>
    379376
    … …  
    435432                        </div>
    436433
    437                         <?php // Display On ?>
    438434                        <div class="qt-hf-section qt-hf-section--settings-layout qt-hf-section--display-conditions">
    439435                                <?php
    … …  
    557553                                                <?php endif; ?>
    558554
    559                                                         <?php // Specific pages/posts picker ?>
    560                                                         <div id="qt-hf-specific-section" class="qt-hf-picker-section">
     555                                                <div id="qt-hf-specific-section" class="qt-hf-picker-section">
    561556                                                        <div class="qt-hf-section-head">
    562557                                                                <h3 class="qt-hf-control-label"><?php esc_html_e( 'Include Specific Pages / Posts', 'qreative-header-footer-designer' ); ?></h3>
    … …  
    573568                                                        </div>
    574569
    575                                                 <?php // Exclude picker ?>
    576570                                                        <div id="qt-hf-exclude-section" class="qt-hf-picker-section qt-hf-picker-section--exclude">
    577                                                         <div class="qt-hf-section-head">
    578                                                                 <h3 class="qt-hf-control-label"><?php esc_html_e( 'Exclude Specific Pages / Posts', 'qreative-header-footer-designer' ); ?></h3>
     571                                                                <div class="qt-hf-section-head">
     572                                                                        <h3 class="qt-hf-control-label"><?php esc_html_e( 'Exclude Specific Pages / Posts', 'qreative-header-footer-designer' ); ?></h3>
     573                                                                </div>
     574                                                                <p class="qt-hf-setting-description"><?php esc_html_e( 'Hide this template on selected pages or posts.', 'qreative-header-footer-designer' ); ?></p>
     575                                                                <?php
     576                                                                        $this->render_ajax_post_picker(
     577                                                                                'qt-hf-exclude',
     578                                                                                'qreative_hfd_exclude_pages_posts[]',
     579                                                                                $exclude_ids,
     580                                                                                esc_attr__( 'Search pages and posts to exclude…', 'qreative-header-footer-designer' )
     581                                                                        );
     582                                                                ?>
    579583                                                        </div>
    580                                                         <p class="qt-hf-setting-description"><?php esc_html_e( 'Hide this template on selected pages or posts.', 'qreative-header-footer-designer' ); ?></p>
    581                                                                 <?php
    582                                                                 $this->render_ajax_post_picker(
    583                                                                         'qt-hf-exclude',
    584                                                                         'qreative_hfd_exclude_pages_posts[]',
    585                                                                         $exclude_ids,
    586                                                                         esc_attr__( 'Search pages and posts to exclude…', 'qreative-header-footer-designer' )
    587                                                                 );
    588                                                                         ?>
    589                                                                 </div>
    590584                                                </div>
    591585                                </div>
  • qreative-header-footer-designer/trunk/qreative-header-footer-designer.php

    r3685252 r3748592  
    44 * Plugin URI:                  https://www.qreativethemes.com/header-footer-builder/
    55 * Description:                 Build your theme header & footer with Elementor, works with classic WordPress themes.
    6  * Version:                     1.0.5
     6 * Version:                     1.0.6
    77 * Author:                      QreativeThemes
    88 * Author URI:                  https://www.qreativethemes.com/
    … …  
    2222}
    2323
    24 define( 'QREATIVE_HFD_VERSION',   '1.0.5' );
     24define( 'QREATIVE_HFD_VERSION',   '1.0.6' );
    2525define( 'QREATIVE_HFD_PATH',      plugin_dir_path( __FILE__ ) );
    2626define( 'QREATIVE_HFD_URL',       plugin_dir_url( __FILE__ ) );
  • qreative-header-footer-designer/trunk/readme.txt

    r3685252 r3748592  
    66Requires PHP: 7.4
    77Requires Plugins: elementor
    8 Stable tag: 1.0.5
     8Stable tag: 1.0.6
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1111
    12 Create custom WordPress headers and footers with Elementor, display them exactly where you need them, and leave your theme files untouched.
     12Design custom WordPress headers and footers with Elementor, control where they appear, and leave your theme files untouched.
    1313
    1414== Description ==
    1515
    16 Take control of your WordPress header and footer without editing theme files or setting up a complete theme builder.
     16Build custom WordPress headers and footers without editing theme files or setting up a full theme builder.
    1717
    18 Qreative Header Footer Designer gives you a focused place to create header and footer templates, design them visually with Elementor, and choose exactly where they appear. Use one layout across your whole website or create different designs for specific pages, posts, and WordPress views.
     18Qreative Header Footer Designer gives you a place to create templates, design them visually with Elementor, and decide where they appear. Use one layout across your website or assign different designs to specific posts and pages.
    1919
    20 It works with the Elementor editor you already know, includes dedicated widgets for your logo, navigation, search overlay, and dynamic copyright notice.
     20The plugin works with the Elementor editor and includes dedicated widgets for your logo, navigation, search overlay, and dynamic copyright notice.
     21
     22https://www.youtube.com/watch?v=FvCszM2vnEA
    2123
    2224= 🎨 Create your header or footer in three steps =
    … …  
    26283. Build the layout visually with Elementor.
    2729
    28 That is all you need to replace your theme's standard header or footer with a design that fits your website.
     30Your new design replaces the theme's standard header or footer wherever its display conditions match.
    2931
    3032= ✨ What you can do =
    3133
    32 * **Design with Elementor:** Use Elementor containers, widgets, responsive controls, and styling options.
     34* **Design with Elementor:** Build layouts with Elementor containers, widgets, responsive controls, and styling options.
    3335* **Replace theme headers and footers:** Create custom layouts without modifying theme files.
    34 * **Control where templates appear:** Display a template across the entire website or target the front page, blog, pages, posts, archives, search results, or the 404 page.
    35 * **Include or exclude specific content:** Assign layouts to selected pages and posts or prevent them from appearing in particular places.
    36 * **Create sticky headers:** Keep important navigation visible while visitors scroll.
    37 * **Manage multiple templates:** Activate templates, set priorities, and quickly filter the template overview by type.
    38 * **Build multilingual layouts:** Use translated templates with WPML or Polylang.
     36* **Control where templates appear:** Show a template across the entire website or target the front page, blog, pages, posts, archives, search results, or 404 page.
     37* **Include or exclude specific content:** Assign layouts to selected pages and posts, or exclude them from particular locations.
     38* **Create sticky headers:** Keep navigation visible as visitors scroll.
     39* **Manage multiple templates:** Activate templates, set their priority, and filter the template overview by type.
     40* **Build multilingual layouts:** Create translated templates with WPML or Polylang.
    3941
    4042= 🧰 Included Elementor widgets =
    4143
    42 The plugin includes the essential elements needed for a practical website header:
     44The plugin includes four widgets for building practical headers and footers:
    4345
    44 * **Qreative: Site Logo** – Display the logo configured in WordPress Site Identity.
    45 * **Qreative: Menu** – Add and style an existing WordPress navigation menu, including responsive mobile navigation.
    46 * **Qreative: Search Overlay** – Add a compact search trigger that opens an overlay search form.
    47 * **Qreative: Copyright** – Display the current year, your site title, and optional text on either side.
     46* **Qreative: Site Logo** – Displays the logo configured in WordPress Site Identity.
     47* **Qreative: Menu** – Adds and styles an existing WordPress menu, with responsive mobile navigation.
     48* **Qreative: Search Overlay** – Adds a compact trigger that opens an overlay search form.
     49* **Qreative: Copyright** – Displays the current year, your site title, and optional text before or after it.
    4850
    4951= 🎯 Flexible display conditions =
    5052
    51 Choose where every template should be used:
     53Set display rules for each template:
    5254
    5355* Start with broad rules such as Entire Website, All Pages, or All Posts.
    5456* Target common WordPress views such as archives, search results, and the 404 page.
    55 * Select individual pages or posts when a layout is only needed in specific places.
     57* Select individual pages or posts when a layout belongs in specific places.
    5658* Add exclusions that always take priority over broader include rules.
    5759
    58 This makes it easy to use a global header, create a simplified layout for landing pages, or show a different footer in selected areas of your website.
     60Use a global header across the site, a simpler layout for landing pages, or a different footer in selected sections.
    5961
    6062= 🚀 Need more than headers and footers? =
    6163
    62 [Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro) gives you more creative freedom to build a polished, engaging website with Elementor:
     64[Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro) adds more template types, targeting options, and navigation features:
    6365
    64 * **Build richer navigation with mega menus:** Create visually engaging menus that help visitors explore more of your website.
    65 * **Create off-canvas panels:** Keep useful content within easy reach while giving your page design room to breathe.
    66 * **Highlight key messages with announcement bars:** Give promotions and important updates a prominent place on your website without interrupting the browsing experience.
    67 * **Design popups and modals in Elementor:** Bring attention to important messages with designs that feel like a natural part of your website.
    68 * **Reuse sections across your website:** Save time and keep your design consistent with reusable content sections.
    69 * **Target WooCommerce and custom post types:** Create tailored layouts for your store and custom content for a more cohesive website experience.
    70 * **Personalize the experience with Smart Targeting:** Show relevant content to the right visitors at the right time for a more engaging website experience.
    71 * **Add a better WooCommerce cart experience:** Make it easy for shoppers to review their cart while continuing to explore your store.
    72 * **Unlock advanced sticky header controls:** Go beyond the free plugin’s sticky headers with more control over when your header stays visible as visitors scroll.
     66* **Build mega menus:** Create larger, visual navigation layouts that help visitors find more of your content.
     67* **Create off-canvas panels:** Place navigation or supporting content in panels that open when needed.
     68* **Publish announcement bars:** Give promotions and updates a clear place on your website.
     69* **Design popups and modals in Elementor:** Build overlays that match the rest of your site.
     70* **Reusable global sections:** Maintain shared sections in one place and use them across your website.
     71* **Target WooCommerce and custom post types:** Assign layouts to store pages and custom content.
     72* **Use Smart Targeting:** Show different content based on visitor and browsing conditions.
     73* **Add a WooCommerce cart widget:** Open cart contents in a fully customizable slide-out panel, so shoppers can review their order without leaving the page.
     74* **Customize the sticky header state:** Give the header a different design when it becomes sticky and control how it behaves while visitors scroll.
    7375
    74 The free plugin remains fully functional for building and displaying custom headers and footers. Pro is an optional add-on for websites that need more creative possibilities.
     76The free plugin includes everything needed to build and display custom headers and footers. Pro is optional and intended for sites that need more layout types or targeting control.
    7577
    7678[Discover Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro)
    … …  
    7880= ⚙️ Requirements and compatibility =
    7981
    80 Elementor must be installed and active. Qreative Header Footer Designer is intended primarily for classic WordPress themes. Block themes already provide header and footer editing through the Site Editor, so compatibility can vary by theme.
     82Elementor must be installed and active. Qreative Header Footer Designer is built primarily for classic WordPress themes. Block themes manage headers and footers through the Site Editor, so compatibility varies by theme.
    8183
    8284== Installation ==
    … …  
    9092== Screenshots ==
    9193
    92 1. Manage header and footer templates, priorities, and active status from one overview.
     941. Manage header and footer templates, priorities, and active status from a single overview.
    93952. Configure an active header template and its display conditions.
    94 3. Build the header template in Elementor editor.
    95 4. Header template shows up on the website.
     963. Build the header template in the Elementor editor.
     974. View the finished header on the website.
    9698
    9799== Frequently Asked Questions ==
    … …  
    99101= Does this plugin require Elementor? =
    100102
    101 Yes. Elementor must be installed and active because the header and footer templates are edited with Elementor.
     103Yes. Elementor must be installed and active because you build the header and footer templates in its editor.
    102104
    103105= Does it work with every WordPress theme? =
    104106
    105 The plugin is designed primarily for classic WordPress themes. Block themes manage headers and footers through the WordPress Site Editor, so compatibility can vary.
     107The plugin is designed primarily for classic WordPress themes. Block themes manage headers and footers through the WordPress Site Editor, so compatibility varies by theme.
    106108
    107109= Can I use my existing WordPress menus? =
    … …  
    115117= Can I use different headers or footers on different pages? =
    116118
    117 Yes. Display conditions let you target the entire website, common WordPress views, or selected pages and posts. You can also exclude specific content from broader rules.
     119Yes. Display conditions can target the entire website, common WordPress views, or selected pages and posts. Exclusions let you remove specific content from broader rules.
    118120
    119121= Which Elementor widgets are included? =
    … …  
    123125= Does it support multilingual websites? =
    124126
    125 Yes. Header and footer templates and page-specific display conditions are compatible with WPML and Polylang workflows.
     127Yes. Header and footer templates and page-specific display conditions work with WPML and Polylang workflows.
    126128
    127129= Where can I find the documentation? =
    … …  
    131133= Is there a Pro version? =
    132134
    133 Yes. Pro extends the free plugin with mega menus, off-canvas panels, announcement bars, Elementor-designed popups and modals, reusable content sections, WooCommerce and custom post type display conditions, Smart Targeting, an enhanced WooCommerce cart experience, and advanced sticky header controls. [Explore Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro).
     135Yes. Pro adds mega menus, off-canvas panels, announcement bars, Elementor-designed popups and modals, reusable content sections, WooCommerce and custom post type display conditions, Smart Targeting, an enhanced WooCommerce cart, and advanced sticky header controls. [Explore Qreative Header Footer Designer Pro](https://qreativethemes.com/header-footer-builder#pro).
    134136
    135137== Changelog ==
     138
     139= 1.0.6 =
     140* Added a secure Duplicate action to the template overview that copies Elementor content and template settings into a new inactive draft.
     141* Changed uninstall behavior to always preserve user-created templates, Elementor designs, and display settings when the plugin is deleted.
    136142
    137143= 1.0.5 =
  • qreative-header-footer-designer/trunk/uninstall.php

    r3595054 r3748592  
    33 * Uninstall — runs when the plugin is deleted from wp-admin.
    44 *
    5  * Removes all post meta stored by this plugin (_qreative_hfd_* keys) for every
    6  * builder post, then deletes all builder posts themselves.
    7  * Does NOT remove posts/pages built with the templates — only the
    8  * template definitions created by this plugin.
     5 * User-created templates and their Elementor data are deliberately preserved so
     6 * they remain available if the plugin is installed again.
    97 *
    108 * @package qreative-header-footer-designer
    … …  
    1614}
    1715
    18 global $wpdb;
    19 
    20 $qreative_hfd_post_type = 'qreative_hfd_tpl';
    21 
    22 // Retrieve all builder post IDs.
    23 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    24 $qreative_hfd_post_ids = $wpdb->get_col(
    25         $wpdb->prepare(
    26                 "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s",
    27                 $qreative_hfd_post_type
    28         )
    29 );
    30 
    31 if ( ! empty( $qreative_hfd_post_ids ) ) {
    32         // Delete all _qreative_hfd_ meta for these posts.
    33         foreach ( $qreative_hfd_post_ids as $qreative_hfd_post_id ) {
    34                 $qreative_hfd_post_id = absint( $qreative_hfd_post_id );
    35 
    36                 $qreative_hfd_keys_to_delete = array(
    37                         '_qreative_hfd_template_active',
    38                         '_qreative_hfd_template_type',
    39                         '_qreative_hfd_sticky_enabled',
    40                         '_qreative_hfd_template_priority',
    41                         '_qreative_hfd_display_on',
    42                         '_qreative_hfd_specific_pages_posts',
    43                         '_qreative_hfd_exclude_pages_posts',
    44                 );
    45 
    46                 foreach ( $qreative_hfd_keys_to_delete as $qreative_hfd_key ) {
    47                         delete_post_meta( $qreative_hfd_post_id, $qreative_hfd_key );
    48                 }
    49 
    50                 // Force-delete (bypass trash) so the CPT posts are fully removed.
    51                 wp_delete_post( $qreative_hfd_post_id, true );
    52         }
    53 }
    54 
    55 // Elementor owns this option name; remove only this plugin's CPT from Elementor's supported post types.
    56 $qreative_hfd_elementor_cpt_support = get_option( 'elementor_cpt_support' );
    57 if ( is_array( $qreative_hfd_elementor_cpt_support ) && in_array( $qreative_hfd_post_type, $qreative_hfd_elementor_cpt_support, true ) ) {
    58         update_option( 'elementor_cpt_support', array_values( array_diff( $qreative_hfd_elementor_cpt_support, array( $qreative_hfd_post_type ) ) ) );
    59 }
     16// Remove the legacy uninstall preference used briefly in version 1.0.6.
     17delete_option( 'qreative_hfd_delete_data_on_uninstall' );
Note: See TracChangeset for help on using the changeset viewer.