Plugin Directory

Changeset 3275104


Ignore:
Timestamp:
04/16/2025 07:52:08 PM (12 months ago)
Author:
grzelkowski
Message:

version 1.6.4

Location:
quick-ajax-post-loader/trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • quick-ajax-post-loader/trunk/DEVELOPER_GUIDE.md

    r3269883 r3275104  
    4141    - 4.7. [Hooks: Modify Template Elements](#47-hooks-modify-template-elements)
    4242    - 4.8. [Hooks: Modifying Post Content Elements](#48-hooks-modifying-post-content-elements)
    43     - 4.9. [Hooks: Customize Load More Button HTML & Styling](#49-hooks-customize-load-more-button-html--styling)
     43    - 4.9. [Hooks: Customize "No Posts Found" Message](#49-hooks-customize-no-posts-found-message)
    4444    - 4.10. [Hooks: Customize End of Posts Message](#410-hooks-customize-end-of-posts-message)
    45     - 4.11. [Debugging: Find & Log quick_ajax_id for AJAX Hooks](#411-debugging-find--log-quick_ajax_id-for-ajax-hooks)
    46     - 4.12. [Best Practices for Hooks and Filters](#412-best-practices-for-hooks-and-filters)
     45    - 4.11. [Hooks: Customize Load More Button HTML & Styling](#411-hooks-customize-load-more-button-html--styling)
     46    - 4.12. [Debugging: Find & Log quick_ajax_id for AJAX Hooks](#412-debugging-find--log-quick_ajax_id-for-ajax-hooks)
     47    - 4.13. [Best Practices for Hooks and Filters](#413-best-practices-for-hooks-and-filters)
    47485. [Advanced Features](#5-advanced-features)
    4849    - 5.1. [AJAX Function Generator](#51-ajax-function-generator)
     
    257258#### Example File Structure
    258259
    259     <div class="qapl-no-posts">
     260    <div class="qapl-no-posts-found">
    260261       <p>Sorry, no posts found to display.</p>
    261262    </div>
     
    415416
    416417    function my_filter_container_before( $quick_ajax_id ) {
    417         if ( $quick_ajax_id === 'example_id' ) {
     418        if ( $quick_ajax_id === 'p963' ) {
    418419            echo '<div class="custom-filter-header">My Custom Filter Section</div>';
    419420        }
     
    543544
    544545    function modify_query_args( $args, $quick_ajax_id ) {
    545         if ($quick_ajax_id === 'some_specific_id') {
     546        if ($quick_ajax_id === 'p963') {
    546547            $args['posts_per_page'] = 5; // change posts per page to 5
    547548        }
     
    568569
    569570    function modify_sorting_options_variants( $sorting_options, $quick_ajax_id ) {
    570     if ($quick_ajax_id === 'p369') {
     571    if ($quick_ajax_id === 'p963') {
    571572        $sorting_options[] = [
    572573            'orderby' => 'modified',
     
    598599    function modify_filter_buttons( $buttons, $quick_ajax_id ) {
    599600        foreach ($buttons as &$button) {
    600             if ($quick_ajax_id === 'some_specific_id') {
     601            if ($quick_ajax_id === 'p963') {
    601602                if ($button['term_id'] === 'none') {
    602603                    $button['button_label'] = 'View All';
     
    749750---
    750751
    751 ### 4.9. Hooks: Customize Load More Button HTML & Styling
     752### 4.9. Hooks: Customize "No Posts Found" Message
     753
     754Customize the **"No Posts Found" message** displayed when there are no posts to show initially (e.g., after filtering).
     755
     756#### **qapl_template_no_post_message**
     757
     758Modify the HTML output for the message shown when no posts match the filter or query.
     759
     760**Parameters:**
     761- `$output` *(string)* - the default message HTML output.
     762- `$quick_ajax_id` *(string)* - unique instance identifier.
     763
     764**Example:**
     765
     766    function customize_no_post_message( $output, $quick_ajax_id ) {
     767        if ( $quick_ajax_id === 'p963' ) {
     768            $output = '<div class="custom-no-posts-found"><p>Nothing to display</p></div>';
     769        }
     770        return $output;
     771    }
     772    add_filter( 'qapl_template_no_post_message', 'customize_no_post_message', 10, 2 );
     773
     774This example replaces the **default "No Posts Found" message** with a custom message for a specific instance.
     775
     776---
     777
     778### 4.10. Hooks: Customize End of Posts Message
     779
     780Customize the **"End of Posts" message** displayed when all posts have been loaded and there are no more items to show.
     781
     782#### **qapl_template_end_post_message**
     783
     784Modify the HTML output for the final message shown when no more posts are available to load.
     785
     786**Parameters:**
     787- `$output` *(string)* - the default message HTML output.
     788- `$quick_ajax_id` *(string)* - unique instance identifier.
     789
     790**Example:**
     791
     792    function customize_end_post_message( $output, $quick_ajax_id ) {
     793        $output = '<div class="custom-end-message"><p>That\'s all we have for now!</p></div>';
     794        return $output;
     795    }
     796    add_filter( 'qapl_template_end_post_message', 'customize_end_post_message', 10, 2 );
     797
     798This example replaces the **default "End of Posts" message** with a custom-styled HTML block.
     799
     800---
     801
     802### 4.11. Hooks: Customize Load More Button HTML & Styling
    752803
    753804Customize the **"Load More" button** styling and behavior.
     
    773824---
    774825
    775 ### 4.10. Hooks: Customize End of Posts Message
    776 
    777 Customize the **"End of Posts" message** displayed when all posts have been loaded and there are no more items to show.
    778 
    779 #### **qapl_template_end_post_message**
    780 
    781 Modify the HTML output for the final message shown when no more posts are available to load.
    782 
    783 **Parameters:**
    784 - `$output` *(string)* - the default message HTML output.
    785 - `$template_name` *(string)* - the template type used.
    786 - `$quick_ajax_id` *(string)* - unique instance identifier.
    787 
    788 **Example:**
    789 
    790     function customize_end_post_message( $output, $quick_ajax_id ) {
    791         $output = '<div class="custom-end-message"><p>That\'s all we have for now!</p></div>';
    792         return $output;
    793     }
    794     add_filter( 'qapl_template_end_post_message', 'customize_end_post_message', 10, 2 );
    795 
    796 This example replaces the **default "End of Posts" message** with a custom-styled HTML block.
    797 
    798 ---
    799 
    800 ### 4.11. Debugging: Find & Log quick_ajax_id for AJAX Hooks
     826### 4.12. Debugging: Find & Log quick_ajax_id for AJAX Hooks
    801827
    802828Each **quick_ajax_id** is unique to an instance of the **Quick Ajax Post Loader** shortcode. It is needed when using hooks and filters to apply changes to a specific shortcode instance.
     
    860886---
    861887
    862 ### 4.12. Best Practices for Hooks and Filters
     888### 4.13. Best Practices for Hooks and Filters
    863889
    864890To ensure safe and effective modifications to the **Quick Ajax Post Loader**, follow these best practices:
  • quick-ajax-post-loader/trunk/admin/pages/help/help_en_US.json

    r3269883 r3275104  
    1414    "3_custom_no_posts_template": {
    1515        "title": "<h4>Templates: Customize &quot;No Posts Found&quot; Message</h4>",
    16         "content": "<p>By default, if no posts match the AJAX query, the plugin displays a <strong>&quot;No Posts Found&quot;</strong> message. You can customize this message by creating a custom template file.</p>\n<h4>Template File Location</h4>\n<p>Place a file named <strong>no-posts.php</strong> in the following directory:</p>\n<pre><code class=\"no-background\">wp-content/themes/your-theme/quick-ajax-post-loader/templates/post-items/\n</code></pre>\n<h4>Example File Structure</h4>\n<pre><code class=\"no-background\">&lt;div class=&quot;qapl-no-posts&quot;&gt;\n   &lt;p&gt;Sorry, no posts found to display.&lt;/p&gt;\n&lt;/div&gt;\n</code></pre>"
     16        "content": "<p>By default, if no posts match the AJAX query, the plugin displays a <strong>&quot;No Posts Found&quot;</strong> message. You can customize this message by creating a custom template file.</p>\n<h4>Template File Location</h4>\n<p>Place a file named <strong>no-posts.php</strong> in the following directory:</p>\n<pre><code class=\"no-background\">wp-content/themes/your-theme/quick-ajax-post-loader/templates/post-items/\n</code></pre>\n<h4>Example File Structure</h4>\n<pre><code class=\"no-background\">&lt;div class=&quot;qapl-no-posts-found&quot;&gt;\n   &lt;p&gt;Sorry, no posts found to display.&lt;/p&gt;\n&lt;/div&gt;\n</code></pre>"
    1717    },
    1818    "3_custom_end_of_posts_template": {
     
    3838    "4_filter_container_hooks": {
    3939        "title": "<h4>Hooks: Filter Container - Modify the Filtering Section</h4>",
    40         "content": "<p>Filter container hooks allow you to insert custom elements within the filter section of the plugin interface. These hooks provide flexibility to enhance filtering options or add additional UI components.</p>\n<p>Below is a list of available hooks and their usage.</p>\n<h4><strong>qapl_filter_container_before</strong></h4>\n<p>Triggered just before rendering the filter container.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - the unique identifier of the plugin instance.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function my_filter_container_before( $quick_ajax_id ) {\n    if ( $quick_ajax_id === &#39;example_id&#39; ) {\n        echo &#39;&lt;div class=&quot;custom-filter-header&quot;&gt;My Custom Filter Section&lt;/div&gt;&#39;;\n    }\n}\nadd_action( &#39;qapl_filter_container_before&#39;, &#39;my_filter_container_before&#39;, 10, 1 );\n</code></pre>\n<h4><strong>qapl_filter_container_start</strong></h4>\n<p>Triggered at the beginning of the filter container rendering.</p>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function my_filter_container_start( $quick_ajax_id ) {\n    echo &#39;&lt;div class=&quot;custom-filter-start&quot;&gt;Start of the filter container&lt;/div&gt;&#39;;\n}\nadd_action( &#39;qapl_filter_container_start&#39;, &#39;my_filter_container_start&#39;, 10, 1 );\n</code></pre>\n<h4><strong>qapl_filter_container_end</strong></h4>\n<p>Triggered just before finishing the rendering of the filter container.</p>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function my_filter_container_end( $quick_ajax_id ) {\n    echo &#39;&lt;div class=&quot;custom-filter-end&quot;&gt;End of the filter container&lt;/div&gt;&#39;;\n}\nadd_action( &#39;qapl_filter_container_end&#39;, &#39;my_filter_container_end&#39;, 10, 1 );\n</code></pre>\n<h4><strong>qapl_filter_container_after</strong></h4>\n<p>Triggered immediately after rendering the filter container.</p>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function my_filter_container_after( $quick_ajax_id ) {\n    echo &#39;&lt;div class=&quot;custom-filter-after&quot;&gt;After the filter container&lt;/div&gt;&#39;;\n}\nadd_action( &#39;qapl_filter_container_after&#39;, &#39;my_filter_container_after&#39;, 10, 1 );\n</code></pre>"
     40        "content": "<p>Filter container hooks allow you to insert custom elements within the filter section of the plugin interface. These hooks provide flexibility to enhance filtering options or add additional UI components.</p>\n<p>Below is a list of available hooks and their usage.</p>\n<h4><strong>qapl_filter_container_before</strong></h4>\n<p>Triggered just before rendering the filter container.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - the unique identifier of the plugin instance.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function my_filter_container_before( $quick_ajax_id ) {\n    if ( $quick_ajax_id === &#39;p963&#39; ) {\n        echo &#39;&lt;div class=&quot;custom-filter-header&quot;&gt;My Custom Filter Section&lt;/div&gt;&#39;;\n    }\n}\nadd_action( &#39;qapl_filter_container_before&#39;, &#39;my_filter_container_before&#39;, 10, 1 );\n</code></pre>\n<h4><strong>qapl_filter_container_start</strong></h4>\n<p>Triggered at the beginning of the filter container rendering.</p>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function my_filter_container_start( $quick_ajax_id ) {\n    echo &#39;&lt;div class=&quot;custom-filter-start&quot;&gt;Start of the filter container&lt;/div&gt;&#39;;\n}\nadd_action( &#39;qapl_filter_container_start&#39;, &#39;my_filter_container_start&#39;, 10, 1 );\n</code></pre>\n<h4><strong>qapl_filter_container_end</strong></h4>\n<p>Triggered just before finishing the rendering of the filter container.</p>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function my_filter_container_end( $quick_ajax_id ) {\n    echo &#39;&lt;div class=&quot;custom-filter-end&quot;&gt;End of the filter container&lt;/div&gt;&#39;;\n}\nadd_action( &#39;qapl_filter_container_end&#39;, &#39;my_filter_container_end&#39;, 10, 1 );\n</code></pre>\n<h4><strong>qapl_filter_container_after</strong></h4>\n<p>Triggered immediately after rendering the filter container.</p>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function my_filter_container_after( $quick_ajax_id ) {\n    echo &#39;&lt;div class=&quot;custom-filter-after&quot;&gt;After the filter container&lt;/div&gt;&#39;;\n}\nadd_action( &#39;qapl_filter_container_after&#39;, &#39;my_filter_container_after&#39;, 10, 1 );\n</code></pre>"
    4141    },
    4242    "4_post_container_hooks": {
     
    5050    "4_modify_posts_query": {
    5151        "title": "<h4>Hooks: Modify WP_Query Parameters for AJAX Requests</h4>",
    52         "content": "<p>Query modification hooks allow you to <strong>customize the post retrieval process</strong> by altering WP_Query arguments before the AJAX request is executed. This enables fine-grained control over which posts are displayed.</p>\n<h4><strong>qapl_modify_posts_query_args</strong></h4>\n<p>This filter allows you to modify <strong>WP_Query</strong> arguments to fully control the data retrieved by AJAX requests.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$args</code> <em>(array)</em> - original query arguments.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function modify_query_args( $args, $quick_ajax_id ) {\n    if ($quick_ajax_id === &#39;some_specific_id&#39;) {\n        $args[&#39;posts_per_page&#39;] = 5; // change posts per page to 5\n    }\n    return $args;\n}\nadd_filter( &#39;qapl_modify_posts_query_args&#39;, &#39;modify_query_args&#39;, 10, 2 );\n</code></pre>\n<p>This example shows how to change the number of posts per page to <strong>5</strong>, using a specific AJAX identifier.</p>"
     52        "content": "<p>Query modification hooks allow you to <strong>customize the post retrieval process</strong> by altering WP_Query arguments before the AJAX request is executed. This enables fine-grained control over which posts are displayed.</p>\n<h4><strong>qapl_modify_posts_query_args</strong></h4>\n<p>This filter allows you to modify <strong>WP_Query</strong> arguments to fully control the data retrieved by AJAX requests.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$args</code> <em>(array)</em> - original query arguments.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function modify_query_args( $args, $quick_ajax_id ) {\n    if ($quick_ajax_id === &#39;p963&#39;) {\n        $args[&#39;posts_per_page&#39;] = 5; // change posts per page to 5\n    }\n    return $args;\n}\nadd_filter( &#39;qapl_modify_posts_query_args&#39;, &#39;modify_query_args&#39;, 10, 2 );\n</code></pre>\n<p>This example shows how to change the number of posts per page to <strong>5</strong>, using a specific AJAX identifier.</p>"
    5353    },
    5454    "4_modify_sorting_options": {
    5555        "title": "<h4>Hooks: Modify Sorting Options for AJAX Queries</h4>",
    56         "content": "<p>Sorting filters allow you to <strong>customize or extend the available sorting methods</strong> used by the AJAX query. This can be useful for adding new sorting options based on custom fields, modified dates, or taxonomies.</p>\n<h4><strong>qapl_modify_sorting_options_variants</strong></h4>\n<p>This filter allows modifying or extending the available sorting methods.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$sorting_options</code> <em>(array)</em> - array containing sorting options.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function modify_sorting_options_variants( $sorting_options, $quick_ajax_id ) {\nif ($quick_ajax_id === &#39;p369&#39;) {\n    $sorting_options[] = [\n        &#39;orderby&#39; =&gt; &#39;modified&#39;,\n        &#39;order&#39;   =&gt; &#39;DESC&#39;,\n        &#39;label&#39;   =&gt; &#39;Modify date&#39;,\n    ];\n}\nreturn $sorting_options;\n</code></pre>\n<p>}\nadd_filter( &#39;qapl_modify_sorting_options_variants&#39;, &#39;modify_sorting_options_variants&#39;, 10, 2 );</p>\n<p>This example adds a <strong>sorting option based on the last modified date</strong> for the AJAX instance with <strong>quick_ajax_id = &#39;p369&#39;</strong>.</p>"
     56        "content": "<p>Sorting filters allow you to <strong>customize or extend the available sorting methods</strong> used by the AJAX query. This can be useful for adding new sorting options based on custom fields, modified dates, or taxonomies.</p>\n<h4><strong>qapl_modify_sorting_options_variants</strong></h4>\n<p>This filter allows modifying or extending the available sorting methods.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$sorting_options</code> <em>(array)</em> - array containing sorting options.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function modify_sorting_options_variants( $sorting_options, $quick_ajax_id ) {\nif ($quick_ajax_id === &#39;p963&#39;) {\n    $sorting_options[] = [\n        &#39;orderby&#39; =&gt; &#39;modified&#39;,\n        &#39;order&#39;   =&gt; &#39;DESC&#39;,\n        &#39;label&#39;   =&gt; &#39;Modify date&#39;,\n    ];\n}\nreturn $sorting_options;\n</code></pre>\n<p>}\nadd_filter( &#39;qapl_modify_sorting_options_variants&#39;, &#39;modify_sorting_options_variants&#39;, 10, 2 );</p>\n<p>This example adds a <strong>sorting option based on the last modified date</strong> for the AJAX instance with <strong>quick_ajax_id = &#39;p369&#39;</strong>.</p>"
    5757    },
    5858    "4_modify_taxonomy_filters": {
    5959        "title": "<h4>Hooks: Modify Taxonomy Filter Buttons</h4>",
    60         "content": "<p>Taxonomy filter hooks let you <strong>modify the taxonomy filter buttons</strong>, changing their appearance, labels, or even adding custom logic.</p>\n<h4><strong>qapl_modify_taxonomy_filter_buttons</strong></h4>\n<p>This filter allows modifying the properties of taxonomy filter buttons.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$buttons</code> <em>(array)</em> - array containing button data.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function modify_filter_buttons( $buttons, $quick_ajax_id ) {\n    foreach ($buttons as &amp;$button) {\n        if ($quick_ajax_id === &#39;some_specific_id&#39;) {\n            if ($button[&#39;term_id&#39;] === &#39;none&#39;) {\n                $button[&#39;button_label&#39;] = &#39;View All&#39;;\n            } else {\n                $button[&#39;button_label&#39;] = strtoupper($button[&#39;button_label&#39;]);\n            }\n        }\n    }\n    return $buttons;\n}\nadd_filter( &#39;qapl_modify_taxonomy_filter_buttons&#39;, &#39;modify_filter_buttons&#39;, 10, 2 );\n</code></pre>\n<p>This example changes the <strong>&quot;Show All&quot;</strong> button label to <strong>&quot;View All&quot;</strong> and converts the labels of other filter buttons to uppercase.</p>"
     60        "content": "<p>Taxonomy filter hooks let you <strong>modify the taxonomy filter buttons</strong>, changing their appearance, labels, or even adding custom logic.</p>\n<h4><strong>qapl_modify_taxonomy_filter_buttons</strong></h4>\n<p>This filter allows modifying the properties of taxonomy filter buttons.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$buttons</code> <em>(array)</em> - array containing button data.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function modify_filter_buttons( $buttons, $quick_ajax_id ) {\n    foreach ($buttons as &amp;$button) {\n        if ($quick_ajax_id === &#39;p963&#39;) {\n            if ($button[&#39;term_id&#39;] === &#39;none&#39;) {\n                $button[&#39;button_label&#39;] = &#39;View All&#39;;\n            } else {\n                $button[&#39;button_label&#39;] = strtoupper($button[&#39;button_label&#39;]);\n            }\n        }\n    }\n    return $buttons;\n}\nadd_filter( &#39;qapl_modify_taxonomy_filter_buttons&#39;, &#39;modify_filter_buttons&#39;, 10, 2 );\n</code></pre>\n<p>This example changes the <strong>&quot;Show All&quot;</strong> button label to <strong>&quot;View All&quot;</strong> and converts the labels of other filter buttons to uppercase.</p>"
    6161    },
    6262    "4_modify_post_content": {
     
    6464        "content": "<p>These filters allow customizing different parts of the post content.</p>\n<h4>Modifying the Post Title</h4>\n<h4><strong>qapl_template_post_item_title</strong></h4>\n<p>Modify the <strong>title HTML output</strong>.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the original HTML of the post title.</li>\n<li><code class=\"code-tag\">$template</code> <em>(string)</em> - the template file name.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_post_title( $output, $template, $quick_ajax_id ) {\n    if ( $template === &#39;post-item&#39; ) {\n        $output = &#39;&lt;div class=&quot;qapl-post-title&quot;&gt;&lt;h2 class=&quot;custom-title&quot;&gt;&#39; . esc_html(get_the_title()) . &#39;&lt;/h2&gt;&lt;/div&gt;&#39;;\n    }\n    return $output;\n}\nadd_filter( &#39;qapl_template_post_item_title&#39;, &#39;customize_post_title&#39;, 10, 3 );\n</code></pre>\n<p>This example wraps the title in an <strong>H2 tag</strong> and adds a permalink.</p>\n<h4>Modifying the Post Excerpt</h4>\n<h4><strong>qapl_template_post_item_excerpt</strong></h4>\n<p>Modify the <strong>excerpt HTML output</strong>.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the original HTML of the post excerpt.</li>\n<li><code class=\"code-tag\">$template</code> <em>(string)</em> - the template file name.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_post_excerpt( $output, $template, $quick_ajax_id ) {\n    if ( $template === &#39;post-item&#39; ) {\n        $output = &#39;&lt;div class=&quot;qapl-post-description&quot;&gt;&lt;p class=&quot;custom-excerpt&quot;&gt;&#39; . wp_trim_words(get_the_excerpt(), 15) . &#39;&lt;/p&gt;&lt;/div&gt;&#39;;\n    }\n    return $output;\n}\nadd_filter( &#39;qapl_template_post_item_excerpt&#39;, &#39;customize_post_excerpt&#39;, 10, 3 );\n</code></pre>\n<p>This example limits the excerpt to <strong>15 words</strong> and wraps it in a <code class=\"code-tag\">&lt;p&gt;</code> tag.</p>\n<h4>Modifying the Post Image</h4>\n<h4><strong>qapl_template_post_item_image</strong></h4>\n<p>Modify the <strong>featured image (thumbnail)</strong>.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the original HTML of the post thumbnail.</li>\n<li><code class=\"code-tag\">$template</code> <em>(string)</em> - the template file name (e.g., <code class=\"code-tag\">&#39;post-item.php&#39;</code>).</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_post_image( $output, $template, $quick_ajax_id ) {\n    if ( $template === &#39;post-item&#39; ) {\n        $output = &#39;&lt;div class=&quot;qapl-post-image&quot;&gt;&lt;img src=&quot;&#39; . esc_url(get_the_post_thumbnail_url(null, &quot;large&quot;)) . &#39;&quot; alt=&quot;&#39; . esc_attr(get_the_title()) . &#39;&quot;&gt;&lt;/div&gt;&#39;;\n    }\n    return $output;\n}\nadd_filter( &#39;qapl_template_post_item_image&#39;, &#39;customize_post_image&#39;, 10, 3 );\n</code></pre>\n<p>This example forces <strong>large images</strong> instead of using the default thumbnail size.</p>\n<h4>Modifying the Post Date</h4>\n<h4><strong>qapl_template_post_item_date</strong></h4>\n<p>Modify how the <strong>post date</strong> is displayed.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the original HTML of the post date.</li>\n<li><code class=\"code-tag\">$template</code> <em>(string)</em> - the template file name (e.g., <code class=\"code-tag\">&#39;post-item.php&#39;</code>).</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_post_date( $output, $template, $quick_ajax_id ) {\n    if ( $template === &#39;post-item&#39; ) {\n        $new_date = get_the_date( &#39;d-m-Y&#39; );\n        $output = &#39;&lt;div class=&quot;qapl-post-date&quot;&gt;&lt;div class=&quot;custom-date&quot;&gt;Date: &#39; . esc_html( $new_date ) . &#39;&lt;/div&gt;&lt;/div&gt;&#39;;\n    }\n    return $output;\n}\nadd_filter( &#39;qapl_template_post_item_date&#39;, &#39;customize_post_date&#39;, 10, 3 );\n</code></pre>\n<p>This example changes the <strong>date format</strong> and wraps it in a <code class=\"code-tag\">&lt;div class=&quot;custom-date&quot;&gt;&lt;/div&gt;</code> container.</p>\n<h4>Modifying the Read More Label</h4>\n<h4><strong>qapl_template_post_item_read_more</strong></h4>\n<p>Modify the <strong>&quot;Read More&quot; label inside post content</strong>.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the original HTML of the &quot;Read More&quot; Label.</li>\n<li><code class=\"code-tag\">$template</code> <em>(string)</em> - the template file name.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_read_more( $output, $template, $quick_ajax_id ) {\n    if ( $template === &#39;post-item&#39; ) {\n        $output = &#39;&lt;div class=&quot;qapl-read-more custom-read_more&quot;&gt;&lt;p&gt;Read Full Article&lt;/p&gt;&lt;/div&gt;&#39;;\n    }\n    return $output;\n}\nadd_filter( &#39;qapl_template_post_item_read_more&#39;, &#39;customize_read_more&#39;, 10, 3 );\n</code></pre>\n<p>This example changes the <strong>text of the &quot;Read More&quot; button</strong> to &quot;Read Full Article&quot;.</p>"
    6565    },
     66    "4_modify_no_post_message": {
     67        "title": "<h4>Hooks: Customize &quot;No Posts Found&quot; Message</h4>",
     68        "content": "<p>Customize the <strong>&quot;No Posts Found&quot; message</strong> displayed when there are no posts to show initially (e.g., after filtering).</p>\n<h4><strong>qapl_template_no_post_message</strong></h4>\n<p>Modify the HTML output for the message shown when no posts match the filter or query.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the default message HTML output.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_no_post_message( $output, $quick_ajax_id ) {\n    if ( $quick_ajax_id === &#39;p963&#39; ) {\n        $output = &#39;&lt;div class=&quot;custom-no-posts-found&quot;&gt;&lt;p&gt;Nothing to display&lt;/p&gt;&lt;/div&gt;&#39;;\n    }\n    return $output;\n}\nadd_filter( &#39;qapl_template_no_post_message&#39;, &#39;customize_no_post_message&#39;, 10, 2 );\n</code></pre>\n<p>This example replaces the <strong>default &quot;No Posts Found&quot; message</strong> with a custom message for a specific instance.</p>"
     69    },
     70    "4_modify_end_post_message": {
     71        "title": "<h4>Hooks: Customize End of Posts Message</h4>",
     72        "content": "<p>Customize the <strong>&quot;End of Posts&quot; message</strong> displayed when all posts have been loaded and there are no more items to show.</p>\n<h4><strong>qapl_template_end_post_message</strong></h4>\n<p>Modify the HTML output for the final message shown when no more posts are available to load.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the default message HTML output.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_end_post_message( $output, $quick_ajax_id ) {\n    $output = &#39;&lt;div class=&quot;custom-end-message&quot;&gt;&lt;p&gt;That\\&#39;s all we have for now!&lt;/p&gt;&lt;/div&gt;&#39;;\n    return $output;\n}\nadd_filter( &#39;qapl_template_end_post_message&#39;, &#39;customize_end_post_message&#39;, 10, 2 );\n</code></pre>\n<p>This example replaces the <strong>default &quot;End of Posts&quot; message</strong> with a custom-styled HTML block.</p>"
     73    },
    6674    "4_modify_loadmore_button": {
    6775        "title": "<h4>Hooks: Customize Load More Button HTML &amp; Styling</h4>",
    6876        "content": "<p>Customize the <strong>&quot;Load More&quot; button</strong> styling and behavior.</p>\n<h4><strong>qapl_template_load_more_button</strong></h4>\n<p>Modify the <strong>&quot;Load More&quot; button</strong> HTML output.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the original HTML of the button.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_load_more_button( $output, $quick_ajax_id ) {\n    $output = &#39;&lt;button type=&quot;button&quot; class=&quot;custom-load-more qapl-load-more-button qapl-button&quot; data-button=&quot;quick-ajax-load-more-button&quot;&gt;Show More Posts&lt;/button&gt;&#39;;\n    return $output;\n}\nadd_filter( &#39;qapl_template_load_more_button&#39;, &#39;customize_load_more_button&#39;, 10, 2 );\n</code></pre>\n<p>This example replaces the <strong>default &quot;Load More&quot; button</strong> with a custom-styled version.</p>"
    69     },
    70     "4_modify_end_post_message": {
    71         "title": "<h4>Hooks: Customize End of Posts Message</h4>",
    72         "content": "<p>Customize the <strong>&quot;End of Posts&quot; message</strong> displayed when all posts have been loaded and there are no more items to show.</p>\n<h4><strong>qapl_template_end_post_message</strong></h4>\n<p>Modify the HTML output for the final message shown when no more posts are available to load.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code class=\"code-tag\">$output</code> <em>(string)</em> - the default message HTML output.</li>\n<li><code class=\"code-tag\">$template_name</code> <em>(string)</em> - the template type used.</li>\n<li><code class=\"code-tag\">$quick_ajax_id</code> <em>(string)</em> - unique instance identifier.</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre><code class=\"no-background\">function customize_end_post_message( $output, $quick_ajax_id ) {\n    $output = &#39;&lt;div class=&quot;custom-end-message&quot;&gt;&lt;p&gt;That\\&#39;s all we have for now!&lt;/p&gt;&lt;/div&gt;&#39;;\n    return $output;\n}\nadd_filter( &#39;qapl_template_end_post_message&#39;, &#39;customize_end_post_message&#39;, 10, 2 );\n</code></pre>\n<p>This example replaces the <strong>default &quot;End of Posts&quot; message</strong> with a custom-styled HTML block.</p>"
    7377    },
    7478    "4_finding_debugging_quick_ajax_id": {
  • quick-ajax-post-loader/trunk/admin/pages/settings-page.php

    r3269883 r3275104  
    2525            $this->create_field($field_properties);
    2626            $field_properties = QAPL_Form_Fields_Helper::get_global_options_field_set_load_more_label();
     27            $this->create_field($field_properties);
     28            $field_properties = QAPL_Form_Fields_Helper::get_global_options_field_set_no_post_message();
    2729            $this->create_field($field_properties);
    2830            $field_properties = QAPL_Form_Fields_Helper::get_global_options_field_set_end_post_message();
     
    165167            $content .= $this->add_field(QAPL_Quick_Ajax_Helper::global_options_field_set_show_all_label());
    166168            $content .= $this->add_field(QAPL_Quick_Ajax_Helper::global_options_field_set_load_more_label());
     169            $content .= $this->add_field(QAPL_Quick_Ajax_Helper::global_options_field_set_no_post_message());
    167170            $content .= $this->add_field(QAPL_Quick_Ajax_Helper::global_options_field_set_end_post_message());
    168171            $content .= '<h4>'.__('Sorting Option Labels', 'quick-ajax-post-loader').'</h4>';
  • quick-ajax-post-loader/trunk/css/style.css

    r3269883 r3275104  
    149149    display: block;
    150150    width: 100%;
     151    text-align: center;
    151152}
    152153.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-end-message-container{
     
    415416    width: 60px;
    416417    height: 60px;
     418    margin: 1rem auto 1rem;
    417419    -webkit-animation: loader-one-spin 2s linear infinite;
    418420            animation: loader-one-spin 2s linear infinite;
  • quick-ajax-post-loader/trunk/css/style.min.css

    r3269883 r3275104  
    1 .quick-ajax-filter-container.quick-ajax-theme{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:10px;margin-bottom:2rem;text-align:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.quick-ajax-filter-container.quick-ajax-theme button.qapl-button,.quick-ajax-sort-options-container.quick-ajax-theme select{padding:10px 20px;font-size:16px;line-height:1;border:2px solid #1e1e1e;background-color:#1e1e1e;color:#fff;-webkit-box-shadow:0 0 22px rgba(0,0,0,.2);box-shadow:0 0 22px rgba(0,0,0,.2);border-radius:21px;outline:unset;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-filter-container.quick-ajax-theme button.qapl-button:focus{outline:0;text-decoration:none;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}.quick-ajax-filter-container.quick-ajax-theme button.qapl-button.active,.quick-ajax-filter-container.quick-ajax-theme button.qapl-button:hover{border:2px solid #1e1e1e;background-color:transparent;color:#1e1e1e;-webkit-box-shadow:0 0 14px rgba(0,0,0,.5);box-shadow:0 0 14px rgba(0,0,0,.5);-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-controls-container{display:-webkit-box;display:-ms-flexbox;display:flex;gap:10px}.quick-ajax-controls-container .quick-ajax-filter-container{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.quick-ajax-controls-container .quick-ajax-sort-options-container{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.quick-ajax-controls-container .quick-ajax-filter-container.quick-ajax-theme{text-align:left;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:start}.quick-ajax-sort-options-container.quick-ajax-theme{margin-left:auto;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;position:relative}.quick-ajax-sort-options-container.quick-ajax-theme select{background-color:#1e1e1e;background-image:url('data:image/svg+xml;charset=US-ASCII,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 5"><path fill="%23ffffff" d="M2 5L0 3h4z"/></svg>');background-repeat:no-repeat;background-position:calc(100% - 20px) 8px;background-size:10px;padding:5px 40px 5px 20px;min-height:40px;font-weight:500;text-align:center;outline:0;cursor:pointer;position:relative;-webkit-appearance:none;-moz-appearance:none;appearance:none}.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper select:hover,.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper:hover select{background-color:transparent;background-image:url('data:image/svg+xml;charset=US-ASCII,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 5"><path fill="%231e1e1e" d="M2 5L0 3h4z"/></svg>');background-repeat:no-repeat;background-position:calc(100% - 20px) 8px;background-size:10px;border:2px solid #1e1e1e;color:#1e1e1e;-webkit-box-shadow:0 0 14px rgba(0,0,0,.5);box-shadow:0 0 14px rgba(0,0,0,.5);-webkit-transition:background-color .3s ease;transition:background-color .3s ease}.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper select:focus{background-color:transparent;background-image:url('data:image/svg+xml;charset=US-ASCII,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 5"><path fill="%231e1e1e" d="M2 0L0 2h4z"/></svg>');background-repeat:no-repeat;background-position:calc(100% - 20px) 16px;background-size:10px;color:#1e1e1e;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper select option{background-color:#fff;color:#1e1e1e;font-weight:500;padding:10px;text-align:center}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-posts-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;width:calc(100% + 2rem);margin-left:-1rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-no-posts-found{display:block;width:100%}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-end-message-container{display:block;width:100%;text-align:center;opacity:0;-webkit-animation:qapl-fade-in .3s ease forwards;animation:qapl-fade-in .3s ease forwards;-webkit-animation-delay:.5s;animation-delay:.5s}.quick-ajax-posts-container.quick-ajax-theme .qapl-load-more-button{display:block;width:auto;margin:0 auto}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;width:100%;padding:1rem}.quick-ajax-posts-container.quick-ajax-theme .col-qty-2 .qapl-post-item{width:calc(100% / 2)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-3 .qapl-post-item{width:calc(100% / 3)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-4 .qapl-post-item{width:calc(100% / 4)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-5 .qapl-post-item{width:calc(100% / 5)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-6 .qapl-post-item{width:calc(100% / 6)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-7 .qapl-post-item{width:calc(100% / 7)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-8 .qapl-post-item{width:calc(100% / 8)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-9 .qapl-post-item{width:calc(100% / 9)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-10 .qapl-post-item{width:calc(100% / 10)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-11 .qapl-post-item{width:calc(100% / 11)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-12 .qapl-post-item{width:calc(100% / 12)}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item a:focus{outline:0;text-decoration:none;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item a>div{position:relative;display:block;width:100%}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item a{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;width:100%}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a{background-color:#fff;-webkit-box-shadow:0 0 10px rgba(0,0,0,.2);box-shadow:0 0 10px rgba(0,0,0,.2);text-decoration:none;border-radius:6px;text-decoration:none;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a:focus img{outline:0}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a:hover{-webkit-box-shadow:0 0 10px rgba(0,0,0,.5);box-shadow:0 0 10px rgba(0,0,0,.5);-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a>div{opacity:1;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a:hover>div{opacity:.8;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-image{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-image img{width:100%;max-width:100%;-o-object-fit:cover;object-fit:cover;-o-object-position:center;object-position:center;border-top-right-radius:6px;border-top-left-radius:6px}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-date{position:absolute;top:1rem;left:1rem;z-index:1;background-color:rgba(255,255,255,.6);display:-webkit-box;display:-ms-flexbox;display:flex;width:auto;border-radius:6px}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-date span{line-height:1;padding:.5rem;font-size:14px;font-weight:700;color:#1e1e1e}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-title{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;padding:.5rem 1rem 1rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-title,.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-title>*{color:#1e1e1e}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-no-image+.qapl-post-title{margin-top:3rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-description{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3;padding:0 1rem 1rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-description,.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-description *{color:#1e1e1e}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-read-more{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4;text-align:right;padding:0 1rem 1rem;color:#1e1e1e;margin-top:auto}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-read-more p{margin-bottom:0}.quick-ajax-posts-container.quick-ajax-theme.loading{margin-bottom:0}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-load-more-container{display:block;width:100%;opacity:1}.quick-ajax-posts-container.quick-ajax-theme.loading .quick-ajax-load-more-container{display:none;opacity:0}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-load-more-container .qapl-load-more-wrapper{margin-top:1rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-load-more-button{display:block;width:auto;margin:0 auto}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-load-more-container .qapl-load-more-button{display:block;padding:10px 20px;font-size:18px;line-height:1;border:2px solid #1e1e1e;background-color:#1e1e1e;color:#fff;-webkit-box-shadow:0 0 22px rgba(0,0,0,.2);box-shadow:0 0 22px rgba(0,0,0,.2);border-radius:21px;outline:unset;-webkit-transition:all .3s;transition:all .3s}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-load-more-container .qapl-load-more-button:hover{border:2px solid #1e1e1e;background-color:transparent;color:#1e1e1e;-webkit-box-shadow:0 0 14px rgba(0,0,0,.5);box-shadow:0 0 14px rgba(0,0,0,.5);-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container .quick-ajax-load-more-container.infinite-scroll{visibility:hidden}.quick-ajax-posts-container .quick-ajax-loader-container{visibility:hidden;opacity:0;height:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.quick-ajax-posts-container.loading .quick-ajax-loader-container{visibility:visible;opacity:1;height:auto;-webkit-transition:opacity .3s ease;transition:opacity .3s ease}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-loader-container{display:-webkit-box;display:-ms-flexbox;display:flex;margin:0 auto 0}.quick-ajax-posts-container.quick-ajax-theme.loading .quick-ajax-loader-container{display:-webkit-box;display:-ms-flexbox;display:flex;min-height:42px;height:auto}.qapl-loader-default{border:8px solid #ebeaea;border-top:8px solid #fff;border-radius:50%;width:60px;height:60px;-webkit-animation:loader-one-spin 2s linear infinite;animation:loader-one-spin 2s linear infinite}@-webkit-keyframes loader-one-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loader-one-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.qapl-loader-dot{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin:1rem auto 1rem}.qapl-loader-dot .dot{width:15px;height:15px;background:#fff;border-radius:50%;margin:5px;-webkit-animation:dotPulse 1.2s infinite ease-in-out both;animation:dotPulse 1.2s infinite ease-in-out both}.qapl-loader-dot .dot:nth-child(1){-webkit-animation-delay:-.24s;animation-delay:-.24s}.qapl-loader-dot .dot:nth-child(2){-webkit-animation-delay:-.12s;animation-delay:-.12s}.qapl-loader-dot .dot:nth-child(3){-webkit-animation-delay:0;animation-delay:0}@-webkit-keyframes dotPulse{0%,100%{-webkit-transform:scale(.8);transform:scale(.8);opacity:.7}50%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes dotPulse{0%,100%{-webkit-transform:scale(.8);transform:scale(.8);opacity:.7}50%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.qapl-loader-wave{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin:1rem auto 1rem}.qapl-loader-wave .wave{width:5px;height:30px;background:rgba(255,255,255,.1);margin:0 2px;-webkit-animation:wave 1.2s infinite ease-in-out;animation:wave 1.2s infinite ease-in-out}.qapl-loader-wave .wave:nth-child(1){-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.qapl-loader-wave .wave:nth-child(2){-webkit-animation-delay:-1s;animation-delay:-1s}.qapl-loader-wave .wave:nth-child(3){-webkit-animation-delay:-.9s;animation-delay:-.9s}.qapl-loader-wave .wave:nth-child(4){-webkit-animation-delay:-.8s;animation-delay:-.8s}.qapl-loader-wave .wave:nth-child(5){-webkit-animation-delay:-.7s;animation-delay:-.7s}@-webkit-keyframes wave{0%,100%,40%{-webkit-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);transform:scaleY(1);background:#fff}}@keyframes wave{0%,100%,40%{-webkit-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);transform:scaleY(1);background:#fff}}@-webkit-keyframes qapl-fade-in{from{opacity:0}to{opacity:1}}@keyframes qapl-fade-in{from{opacity:0}to{opacity:1}}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img{position:relative;overflow:hidden;color:#fff}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img a{text-decoration:none}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-image{position:absolute;top:0;left:0;width:100%;height:100%;-o-object-fit:cover;object-fit:cover;border-radius:4px;-o-object-position:center;object-position:center;object-fit:cover;z-index:1}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-no-image{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.6);border-radius:4px;z-index:0}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .post-content{position:relative;z-index:2;background-color:rgba(0,0,0,.6);padding:20px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;height:100%;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;overflow:hidden}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .post-content::before{content:'';position:absolute;top:0;left:-200%;width:200%;height:100%;background:linear-gradient(45deg,rgba(0,0,0,.9) 0,rgba(0,0,0,.1) 65%,rgba(0,0,0,0) 70%,rgba(0,0,0,0) 100%);opacity:0;z-index:-1;border-top-left-radius:4px;border-top-right-radius:4px;-webkit-transition:all .6s ease;transition:all .6s ease}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img a:hover>.post-content::before{left:0;opacity:1;-webkit-transition:all .6s ease;transition:all .6s ease}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-date{position:relative;background:0 0;line-height:1;margin-bottom:20px;font-size:14px;font-weight:600}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-date span{padding:0;margin-bottom:.5rem;color:#fff;text-decoration:none}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-title{padding-top:3rem;margin-top:auto}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-title,.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-title *{color:#fff;text-decoration:none}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-description,.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-description *{color:#fff;text-decoration:none}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-read-more{text-align:right;font-weight:600;color:#fff;text-decoration:none;background:rgba(0,0,0,.4);display:inline-block;margin-top:1rem;margin-left:auto;margin-bottom:0;padding:6px 20px 8px;text-transform:uppercase;border-radius:7px;line-height:1;opacity:0;-webkit-transition:all .6s ease;transition:all .6s ease}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-read-more p{margin-bottom:0}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img a:hover .qapl-read-more{opacity:1;background:rgba(0,0,0,.6);-webkit-transition:all .6s ease;transition:all .6s ease}
     1.quick-ajax-filter-container.quick-ajax-theme{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:10px;margin-bottom:2rem;text-align:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.quick-ajax-filter-container.quick-ajax-theme button.qapl-button,.quick-ajax-sort-options-container.quick-ajax-theme select{padding:10px 20px;font-size:16px;line-height:1;border:2px solid #1e1e1e;background-color:#1e1e1e;color:#fff;-webkit-box-shadow:0 0 22px rgba(0,0,0,.2);box-shadow:0 0 22px rgba(0,0,0,.2);border-radius:21px;outline:unset;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-filter-container.quick-ajax-theme button.qapl-button:focus{outline:0;text-decoration:none;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}.quick-ajax-filter-container.quick-ajax-theme button.qapl-button.active,.quick-ajax-filter-container.quick-ajax-theme button.qapl-button:hover{border:2px solid #1e1e1e;background-color:transparent;color:#1e1e1e;-webkit-box-shadow:0 0 14px rgba(0,0,0,.5);box-shadow:0 0 14px rgba(0,0,0,.5);-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-controls-container{display:-webkit-box;display:-ms-flexbox;display:flex;gap:10px}.quick-ajax-controls-container .quick-ajax-filter-container{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.quick-ajax-controls-container .quick-ajax-sort-options-container{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.quick-ajax-controls-container .quick-ajax-filter-container.quick-ajax-theme{text-align:left;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:start}.quick-ajax-sort-options-container.quick-ajax-theme{margin-left:auto;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;position:relative}.quick-ajax-sort-options-container.quick-ajax-theme select{background-color:#1e1e1e;background-image:url('data:image/svg+xml;charset=US-ASCII,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 5"><path fill="%23ffffff" d="M2 5L0 3h4z"/></svg>');background-repeat:no-repeat;background-position:calc(100% - 20px) 8px;background-size:10px;padding:5px 40px 5px 20px;min-height:40px;font-weight:500;text-align:center;outline:0;cursor:pointer;position:relative;-webkit-appearance:none;-moz-appearance:none;appearance:none}.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper select:hover,.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper:hover select{background-color:transparent;background-image:url('data:image/svg+xml;charset=US-ASCII,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 5"><path fill="%231e1e1e" d="M2 5L0 3h4z"/></svg>');background-repeat:no-repeat;background-position:calc(100% - 20px) 8px;background-size:10px;border:2px solid #1e1e1e;color:#1e1e1e;-webkit-box-shadow:0 0 14px rgba(0,0,0,.5);box-shadow:0 0 14px rgba(0,0,0,.5);-webkit-transition:background-color .3s ease;transition:background-color .3s ease}.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper select:focus{background-color:transparent;background-image:url('data:image/svg+xml;charset=US-ASCII,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 5"><path fill="%231e1e1e" d="M2 0L0 2h4z"/></svg>');background-repeat:no-repeat;background-position:calc(100% - 20px) 16px;background-size:10px;color:#1e1e1e;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-sort-options-container.quick-ajax-theme .quick-ajax-sort-option-wrapper select option{background-color:#fff;color:#1e1e1e;font-weight:500;padding:10px;text-align:center}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-posts-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;width:calc(100% + 2rem);margin-left:-1rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-no-posts-found{display:block;width:100%;text-align:center}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-end-message-container{display:block;width:100%;text-align:center;opacity:0;-webkit-animation:qapl-fade-in .3s ease forwards;animation:qapl-fade-in .3s ease forwards;-webkit-animation-delay:.5s;animation-delay:.5s}.quick-ajax-posts-container.quick-ajax-theme .qapl-load-more-button{display:block;width:auto;margin:0 auto}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;width:100%;padding:1rem}.quick-ajax-posts-container.quick-ajax-theme .col-qty-2 .qapl-post-item{width:calc(100% / 2)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-3 .qapl-post-item{width:calc(100% / 3)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-4 .qapl-post-item{width:calc(100% / 4)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-5 .qapl-post-item{width:calc(100% / 5)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-6 .qapl-post-item{width:calc(100% / 6)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-7 .qapl-post-item{width:calc(100% / 7)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-8 .qapl-post-item{width:calc(100% / 8)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-9 .qapl-post-item{width:calc(100% / 9)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-10 .qapl-post-item{width:calc(100% / 10)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-11 .qapl-post-item{width:calc(100% / 11)}.quick-ajax-posts-container.quick-ajax-theme .col-qty-12 .qapl-post-item{width:calc(100% / 12)}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item a:focus{outline:0;text-decoration:none;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item a>div{position:relative;display:block;width:100%}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item a{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;width:100%}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a{background-color:#fff;-webkit-box-shadow:0 0 10px rgba(0,0,0,.2);box-shadow:0 0 10px rgba(0,0,0,.2);text-decoration:none;border-radius:6px;text-decoration:none;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a:focus img{outline:0}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a:hover{-webkit-box-shadow:0 0 10px rgba(0,0,0,.5);box-shadow:0 0 10px rgba(0,0,0,.5);-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a>div{opacity:1;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default a:hover>div{opacity:.8;-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-image{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-image img{width:100%;max-width:100%;-o-object-fit:cover;object-fit:cover;-o-object-position:center;object-position:center;border-top-right-radius:6px;border-top-left-radius:6px}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-date{position:absolute;top:1rem;left:1rem;z-index:1;background-color:rgba(255,255,255,.6);display:-webkit-box;display:-ms-flexbox;display:flex;width:auto;border-radius:6px}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-date span{line-height:1;padding:.5rem;font-size:14px;font-weight:700;color:#1e1e1e}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-title{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;padding:.5rem 1rem 1rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-title,.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-title>*{color:#1e1e1e}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-no-image+.qapl-post-title{margin-top:3rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-description{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3;padding:0 1rem 1rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-description,.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-post-description *{color:#1e1e1e}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-read-more{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4;text-align:right;padding:0 1rem 1rem;color:#1e1e1e;margin-top:auto}.quick-ajax-posts-container.quick-ajax-theme .qapl-post-item.qapl-post-item-default .qapl-read-more p{margin-bottom:0}.quick-ajax-posts-container.quick-ajax-theme.loading{margin-bottom:0}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-load-more-container{display:block;width:100%;opacity:1}.quick-ajax-posts-container.quick-ajax-theme.loading .quick-ajax-load-more-container{display:none;opacity:0}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-load-more-container .qapl-load-more-wrapper{margin-top:1rem}.quick-ajax-posts-container.quick-ajax-theme .qapl-load-more-button{display:block;width:auto;margin:0 auto}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-load-more-container .qapl-load-more-button{display:block;padding:10px 20px;font-size:18px;line-height:1;border:2px solid #1e1e1e;background-color:#1e1e1e;color:#fff;-webkit-box-shadow:0 0 22px rgba(0,0,0,.2);box-shadow:0 0 22px rgba(0,0,0,.2);border-radius:21px;outline:unset;-webkit-transition:all .3s;transition:all .3s}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-load-more-container .qapl-load-more-button:hover{border:2px solid #1e1e1e;background-color:transparent;color:#1e1e1e;-webkit-box-shadow:0 0 14px rgba(0,0,0,.5);box-shadow:0 0 14px rgba(0,0,0,.5);-webkit-transition:all .3s ease;transition:all .3s ease}.quick-ajax-posts-container .quick-ajax-load-more-container.infinite-scroll{visibility:hidden}.quick-ajax-posts-container .quick-ajax-loader-container{visibility:hidden;opacity:0;height:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.quick-ajax-posts-container.loading .quick-ajax-loader-container{visibility:visible;opacity:1;height:auto;-webkit-transition:opacity .3s ease;transition:opacity .3s ease}.quick-ajax-posts-container.quick-ajax-theme .quick-ajax-loader-container{display:-webkit-box;display:-ms-flexbox;display:flex;margin:0 auto 0}.quick-ajax-posts-container.quick-ajax-theme.loading .quick-ajax-loader-container{display:-webkit-box;display:-ms-flexbox;display:flex;min-height:42px;height:auto}.qapl-loader-default{border:8px solid #ebeaea;border-top:8px solid #fff;border-radius:50%;width:60px;height:60px;margin:1rem auto 1rem;-webkit-animation:loader-one-spin 2s linear infinite;animation:loader-one-spin 2s linear infinite}@-webkit-keyframes loader-one-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loader-one-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.qapl-loader-dot{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin:1rem auto 1rem}.qapl-loader-dot .dot{width:15px;height:15px;background:#fff;border-radius:50%;margin:5px;-webkit-animation:dotPulse 1.2s infinite ease-in-out both;animation:dotPulse 1.2s infinite ease-in-out both}.qapl-loader-dot .dot:nth-child(1){-webkit-animation-delay:-.24s;animation-delay:-.24s}.qapl-loader-dot .dot:nth-child(2){-webkit-animation-delay:-.12s;animation-delay:-.12s}.qapl-loader-dot .dot:nth-child(3){-webkit-animation-delay:0;animation-delay:0}@-webkit-keyframes dotPulse{0%,100%{-webkit-transform:scale(.8);transform:scale(.8);opacity:.7}50%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes dotPulse{0%,100%{-webkit-transform:scale(.8);transform:scale(.8);opacity:.7}50%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.qapl-loader-wave{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin:1rem auto 1rem}.qapl-loader-wave .wave{width:5px;height:30px;background:rgba(255,255,255,.1);margin:0 2px;-webkit-animation:wave 1.2s infinite ease-in-out;animation:wave 1.2s infinite ease-in-out}.qapl-loader-wave .wave:nth-child(1){-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.qapl-loader-wave .wave:nth-child(2){-webkit-animation-delay:-1s;animation-delay:-1s}.qapl-loader-wave .wave:nth-child(3){-webkit-animation-delay:-.9s;animation-delay:-.9s}.qapl-loader-wave .wave:nth-child(4){-webkit-animation-delay:-.8s;animation-delay:-.8s}.qapl-loader-wave .wave:nth-child(5){-webkit-animation-delay:-.7s;animation-delay:-.7s}@-webkit-keyframes wave{0%,100%,40%{-webkit-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);transform:scaleY(1);background:#fff}}@keyframes wave{0%,100%,40%{-webkit-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);transform:scaleY(1);background:#fff}}@-webkit-keyframes qapl-fade-in{from{opacity:0}to{opacity:1}}@keyframes qapl-fade-in{from{opacity:0}to{opacity:1}}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img{position:relative;overflow:hidden;color:#fff}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img a{text-decoration:none}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-image{position:absolute;top:0;left:0;width:100%;height:100%;-o-object-fit:cover;object-fit:cover;border-radius:4px;-o-object-position:center;object-position:center;object-fit:cover;z-index:1}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-no-image{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.6);border-radius:4px;z-index:0}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .post-content{position:relative;z-index:2;background-color:rgba(0,0,0,.6);padding:20px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;height:100%;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;overflow:hidden}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .post-content::before{content:'';position:absolute;top:0;left:-200%;width:200%;height:100%;background:linear-gradient(45deg,rgba(0,0,0,.9) 0,rgba(0,0,0,.1) 65%,rgba(0,0,0,0) 70%,rgba(0,0,0,0) 100%);opacity:0;z-index:-1;border-top-left-radius:4px;border-top-right-radius:4px;-webkit-transition:all .6s ease;transition:all .6s ease}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img a:hover>.post-content::before{left:0;opacity:1;-webkit-transition:all .6s ease;transition:all .6s ease}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-date{position:relative;background:0 0;line-height:1;margin-bottom:20px;font-size:14px;font-weight:600}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-date span{padding:0;margin-bottom:.5rem;color:#fff;text-decoration:none}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-title{padding-top:3rem;margin-top:auto}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-title,.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-title *{color:#fff;text-decoration:none}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-description,.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-post-description *{color:#fff;text-decoration:none}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-read-more{text-align:right;font-weight:600;color:#fff;text-decoration:none;background:rgba(0,0,0,.4);display:inline-block;margin-top:1rem;margin-left:auto;margin-bottom:0;padding:6px 20px 8px;text-transform:uppercase;border-radius:7px;line-height:1;opacity:0;-webkit-transition:all .6s ease;transition:all .6s ease}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img .qapl-read-more p{margin-bottom:0}.quick-ajax-posts-container .qapl-post-item.qapl-post-item-bg-img a:hover .qapl-read-more{opacity:1;background:rgba(0,0,0,.6);-webkit-transition:all .6s ease;transition:all .6s ease}
  • quick-ajax-post-loader/trunk/inc/actions.php

    r3269883 r3275104  
    4949
    5050
    51         $container_settings = [
    52             'quick_ajax_id' => $ajax_class->attributes['quick_ajax_id'],
    53             'template_name' => $ajax_class->attributes['post_item_template'],
    54         ];
    55         $qapl_post_template = QAPL_Post_Template_Factory::get_template($container_settings);
    56         QAPL_Post_Template_Context::set_template($qapl_post_template);
     51
    5752        $query = new WP_Query($args);
    5853
    5954        ob_start();       
    6055        if ($query->have_posts()) {
     56            $container_settings = [
     57                'quick_ajax_id' => $ajax_class->attributes['quick_ajax_id'],
     58                'template_name' => $ajax_class->attributes['post_item_template'],
     59            ];
     60            $qapl_post_template = QAPL_Post_Template_Factory::get_template($container_settings);
     61            QAPL_Post_Template_Context::set_template($qapl_post_template);
    6162            while ($query->have_posts()) {
    6263                $query->the_post();
    6364                $template_path = $qapl_helper->plugin_templates_post_item_template(esc_attr($ajax_class->attributes[QAPL_Quick_Ajax_Helper::layout_post_item_template()]));
    64                 if ($template_path && file_exists($template_path)) {
    65                     include $template_path;
    66                 } else {
     65                if (!$template_path || !file_exists($template_path)) {
    6766                    wp_send_json_error(['message' => 'Quick Ajax Post Loader: Template file not found']);
    6867                }
    69             }         
    70            
     68                include $template_path;
     69            }
     70            QAPL_Post_Template_Context::clear_template();
    7171        } else {
    7272            // No posts found
     73            $container_settings = [
     74                'quick_ajax_id' => $ajax_class->attributes['quick_ajax_id'],
     75                'template_name' => 'no-post-message',
     76            ];
     77            $qapl_no_post_template = QAPL_Post_Template_Factory::get_template($container_settings);
     78            QAPL_Post_Template_Context::set_template($qapl_no_post_template);
    7379            $no_posts_template = $qapl_helper->plugin_templates_no_posts();
    74             if ($no_posts_template && file_exists($no_posts_template)) {
    75                 include $no_posts_template;
    76             } else {
    77                 wp_send_json_error(['message' => 'Quick Ajax Post Loader: No posts template file not found']);
     80            if (!$no_posts_template || !file_exists($no_posts_template)) {
     81                wp_send_json_error(['message' => 'Quick Ajax Post Loader: Template file not found']);
    7882            }
     83            include $no_posts_template;
     84            QAPL_Post_Template_Context::clear_template();
    7985        }
    8086        wp_reset_postdata();
     
    8490        $show_end_message = $ajax_class->render_end_of_posts_message($ajax_class->attributes['show_end_message'], $load_more, esc_attr($query->max_num_pages), esc_attr($ajax_class->attributes['quick_ajax_id']));
    8591       
    86         QAPL_Post_Template_Context::clear_template();
     92
    8793        //$output = $ajax_class->replace_placeholders($output);
    8894        wp_send_json_success([
  • quick-ajax-post-loader/trunk/inc/class-ajax.php

    r3269883 r3275104  
    541541            echo '<div class="quick-ajax-posts-wrapper '.esc_attr($container_inner_class).'">';
    542542           
    543             $container_settings = [
    544                 'quick_ajax_id' => $this->quick_ajax_id,
    545                 'template_name' => $this->attributes['post_item_template'],
    546             ];
    547             $qapl_post_template = QAPL_Post_Template_Factory::get_template($container_settings);
    548             QAPL_Post_Template_Context::set_template($qapl_post_template);
     543
    549544            if ($query->have_posts()) {
     545                $container_settings = [
     546                    'quick_ajax_id' => $this->quick_ajax_id,
     547                    'template_name' => $this->attributes['post_item_template'],
     548                ];
     549                $qapl_post_template = QAPL_Post_Template_Factory::get_template($container_settings);
     550                QAPL_Post_Template_Context::set_template($qapl_post_template);
    550551                if ($this->ajax_initial_load) {
    551552                    echo '<div class="qapl-initial-loader" data-button="quick-ajax-filter-button" style="display:none;" data-action="' . esc_attr(wp_json_encode($this->args)) . '" data-attributes="' . esc_attr(wp_json_encode($this->attributes)) . '"></div>';
     
    556557                    }
    557558                }
     559                QAPL_Post_Template_Context::clear_template();
    558560            } else {
     561                // No posts found
     562                $container_settings = [
     563                    'quick_ajax_id' => $ajax_class->attributes['quick_ajax_id'],
     564                    'template_name' => 'no-post-message',
     565                ];
     566                $qapl_no_post_template = QAPL_Post_Template_Factory::get_template($container_settings);
     567                QAPL_Post_Template_Context::set_template($qapl_no_post_template);
    559568                include($this->helper->plugin_templates_no_posts());
    560             }
    561             QAPL_Post_Template_Context::clear_template();           
     569                QAPL_Post_Template_Context::clear_template();
     570            }
     571                       
    562572            echo '</div>';
    563573            do_action(QAPL_Hooks::HOOK_LOADER_BEFORE, $this->quick_ajax_id);
  • quick-ajax-post-loader/trunk/inc/class-helper.php

    r3269883 r3275104  
    1515    public static function get_plugin_info() {
    1616        return [
    17             'version' => '1.6.3',
     17            'version' => '1.6.4',
    1818            'name' => 'Quick Ajax Post Loader',
    1919            'text_domain' => 'quick-ajax-post-loader',
     
    2121            'minimum_php_version' => '7.4',
    2222            'minimum_wp_version' => '5.6',
    23             'tested_wp_version' => '6.7.2'
     23            'tested_wp_version' => '6.8'
    2424        ];
    2525    }
     
    574574        return self::admin_page_global_options_name().'[load_more_label]';
    575575    }
     576    public static function global_options_field_set_no_post_message(){
     577        return self::admin_page_global_options_name().'[no_post_message]';
     578    }
    576579    public static function global_options_field_set_end_post_message(){
    577580        return self::admin_page_global_options_name().'[end_post_message]';
    578     }
    579     public static function global_options_field_set_no_post_message(){
    580         return self::admin_page_global_options_name().'[no_post_message]';
    581581    }
    582582
     
    12311231        return $field_properties;
    12321232    }
     1233    public static function get_global_options_field_set_no_post_message() {
     1234        $field_properties = array(
     1235            'name' => QAPL_Quick_Ajax_Helper::global_options_field_set_no_post_message(),
     1236            'label' => __('Set "No Posts Found" Message', 'quick-ajax-post-loader'),
     1237            'type' => 'text',
     1238            'options' => '', // Not required for text field
     1239            'default' => __('No posts found', 'quick-ajax-post-loader'),
     1240            'placeholder' => __('Enter message for no posts found', 'quick-ajax-post-loader'),
     1241            'description' => __('Customize the message shown when no posts match the selected filters. Examples: "No posts found", "Nothing to display", or "Try adjusting your filters".', 'quick-ajax-post-loader')
     1242        );
     1243        return $field_properties;
     1244    }   
    12331245    public static function get_global_options_field_set_end_post_message() {
    12341246        $field_properties = array(
     
    12371249            'type' => 'text',
    12381250            'options' => '', // Not required for text field
    1239             'default' => __('No more posts to load.', 'quick-ajax-post-loader'),
     1251            'default' => __('No more posts to load', 'quick-ajax-post-loader'),
    12401252            'placeholder' => __('Enter message for end of posts', 'quick-ajax-post-loader'),
    12411253            'description' => __('Customize the message that appears when there are no more posts to load. Examples: "No more posts", "You have reached the end", or "That\'s all for now".', 'quick-ajax-post-loader')
    12421254        );
    12431255        return $field_properties;
    1244     }
    1245     public static function get_global_options_field_set_no_post_message() {
    1246         $field_properties = array(
    1247             'name' => QAPL_Quick_Ajax_Helper::global_options_field_set_no_post_message(),
    1248             'label' => __('Set "No Posts Found" Message', 'quick-ajax-post-loader'),
    1249             'type' => 'text',
    1250             'options' => '', // Not required for text field
    1251             'default' => __('No posts found.', 'quick-ajax-post-loader'),
    1252             'placeholder' => __('Enter message for no posts found', 'quick-ajax-post-loader'),
    1253             'description' => __('Customize the message shown when no posts match the selected filters. Examples: "No posts found", "Nothing to display", or "Try adjusting your filters".', 'quick-ajax-post-loader')
    1254         );
    1255         return $field_properties;
    1256     }   
     1256    }
    12571257    public static function get_global_options_field_set_post_date_format() {
    12581258        $field_properties = array(
     
    13881388    const HOOK_TEMPLATE_POST_ITEM_READ_MORE = 'qapl_template_post_item_read_more';
    13891389    const HOOK_TEMPLATE_LOAD_MORE_BUTTON = 'qapl_template_load_more_button';
     1390    const HOOK_TEMPLATE_NO_POST_MESSAGE = 'qapl_template_no_post_message';
    13901391    const HOOK_TEMPLATE_END_POST_MESSAGE = 'qapl_template_end_post_message';
    13911392}
  • quick-ajax-post-loader/trunk/inc/class-template-hooks.php

    r3269883 r3275104  
    3333}
    3434
     35interface QAPL_No_Post_Message_Interface {
     36    public function render_no_post_message();
     37}
     38
    3539function qapl_output_template_post_date() {
    3640    $template = QAPL_Post_Template_Context::get_template();
     
    6771    if ($template && method_exists($template, 'render_load_more_button')) {
    6872        echo wp_kses_post($template->render_load_more_button());
     73    }
     74}
     75function qapl_output_template_no_post_message() {
     76    $template = QAPL_Post_Template_Context::get_template();
     77    if ($template && method_exists($template, 'render_no_post_message')) {
     78        echo wp_kses_post($template->render_no_post_message());
    6979    }
    7080}
     
    8595            'read_more_label'  => null,                // Read more label;
    8696            'load_more_label'  => null,                // Load more label;
     97            'no_post_message' => null,                 // No post message;
    8798            'end_post_message' => null,                // End post message;
    8899        ];
     
    124135            $this->config->set('load_more_label', !empty($global_options['load_more_label']) ? $global_options['load_more_label'] : __('Load More', 'quick-ajax-post-loader'));
    125136        }
     137        if ($this->config->get('no_post_message') === null) {
     138            $this->config->set('no_post_message', !empty($global_options['no_post_message']) ? $global_options['no_post_message'] : __('No posts found', 'quick-ajax-post-loader'));
     139        }
    126140        if ($this->config->get('end_post_message') === null) {
    127             $this->config->set('end_post_message', !empty($global_options['end_post_message']) ? $global_options['end_post_message'] : __('No more posts to load.', 'quick-ajax-post-loader'));
     141            $this->config->set('end_post_message', !empty($global_options['end_post_message']) ? $global_options['end_post_message'] : __('No more posts to load', 'quick-ajax-post-loader'));
    128142        }
    129143             
     
    221235
    222236class QAPL_Quick_Ajax_Template_Load_More_Button extends QAPL_Quick_Ajax_Template_Base implements QAPL_Load_More_Interface {
    223 
    224237    public function render_load_more_button() {   
    225238        $label = $this->config->get('load_more_label');
     
    230243
    231244class QAPL_Quick_Ajax_Template_End_Post_Message extends QAPL_Quick_Ajax_Template_Base implements QAPL_End_Post_Message_Interface {
    232 
    233245    public function render_end_post_message() {   
    234246        $end_post_message = $this->config->get('end_post_message');
    235247        $output = '<p>' . esc_html($end_post_message) . '</p>';
    236248        return apply_filters(QAPL_Hooks::HOOK_TEMPLATE_END_POST_MESSAGE, $output, $this->quick_ajax_id);
     249    }
     250}
     251
     252class QAPL_Quick_Ajax_Template_No_Post_Message extends QAPL_Quick_Ajax_Template_Base implements QAPL_No_Post_Message_Interface {
     253    public function render_no_post_message() {   
     254        $no_post_message = $this->config->get('no_post_message');
     255        $output = '<p>' . esc_html($no_post_message) . '</p>';
     256        return apply_filters(QAPL_Hooks::HOOK_TEMPLATE_NO_POST_MESSAGE, $output, $this->quick_ajax_id);
    237257    }
    238258}
     
    246266    public function render_read_more() { return ''; }
    247267    public function render_load_more_button() { return ''; }
     268    public function render_no_post_message() { return ''; }
    248269    public function render_end_post_message() { return ''; }
    249270}
     
    255276        'post-item-qapl-full-background-image' => QAPL_Quick_Ajax_Template_Post_Item_Qapl_Full_Background_Image::class,
    256277        'load-more-button' => QAPL_Quick_Ajax_Template_Load_More_Button::class,
     278        'no-post-message' => QAPL_Quick_Ajax_Template_No_Post_Message::class,
    257279        'end-post-message' => QAPL_Quick_Ajax_Template_End_Post_Message::class,
    258280
  • quick-ajax-post-loader/trunk/quick-ajax-post-loader.php

    r3269883 r3275104  
    55* Text Domain: quick-ajax-post-loader
    66* Domain Path: /languages
    7 * Version: 1.6.3
     7* Version: 1.6.4
    88* Description: Supercharge post loading with Quick Ajax Post Loader. Enhance user experience and optimize site performance using AJAX technology.
    99* Author: Pawel Grzelkowski
     
    1212* Requires PHP: 7.4
    1313* Requires at least: 5.6
    14 * Tested up to: 6.7.2
     14* Tested up to: 6.8
    1515*/
    1616if (!defined('ABSPATH')) {
  • quick-ajax-post-loader/trunk/readme.txt

    r3269883 r3275104  
    44Tags: ajax-load-more, infinite-scroll, category-filter, load-more, ajax
    55Requires at least: 5.6
    6 Tested up to: 6.7.2
    7 Stable tag: 1.6.3
     6Tested up to: 6.8
     7Stable tag: 1.6.4
    88Requires PHP: 7.4
    99License: GPLv2 or later
     
    106106== Changelog ==
    107107
     108= 1.6.4 - 2025-04-16 =
     109- Added a new global option to define a custom "No Posts Found" message.
     110- Updated the "No Posts Found" template and added the `qapl_template_no_post_message` filter hook to allow developers to customize the message.
     111- Fixed an issue where the loader icon did not appear correctly in some configurations.
     112- Fixed problems with text labels not displaying as expected.
     113- Tested and confirmed compatibility with WordPress 6.8.
     114
    108115= 1.6.3 - 2025-04-09 =
    109116- Added a new option to display an "End Message" when there are no more posts to load via AJAX.
    110   - The message can now be set via a global option in the plugin settings, customized in the template, or controlled using a filter hook for full flexibility.
     117  - The message can now be set via a global option in the plugin settings, customized in the template, or modified using the `qapl_template_end_post_message` filter hook for full flexibility.
    111118- Improved CSS styling to ensure better compatibility with a wider range of WordPress themes.
    112119- Updated Polish translations for improved clarity and consistency.
     
    246253== Upgrade Notice ==
    247254
     255= 1.6.4 =
     256This update adds a new global option and filter hook to customize the "No Posts Found" message.
     257
     258**Important:**
     259- Developers can use the `qapl_template_no_post_message` filter to modify the output.
     260- Includes fixes for loader display and label issues.
     261
     262Fully tested with WordPress 6.8.
     263
     264= 1.6.3 =
     265This update adds support for an "End Message" that appears when there are no more posts to load.
     266
     267**Important:**
     268- The message can be set globally, customized in templates, or modified using the `qapl_template_end_post_message` filter hook.
     269- This improves user experience but may require adjustments to your template or CSS.
     270
     271Recommended update for improved usability and developer flexibility.
     272
    248273= 1.6.0 =
    249274This update introduces an Infinite Scroll feature and an improved Help section within the plugin settings.
  • quick-ajax-post-loader/trunk/templates/post-items/no-posts.php

    r3238174 r3275104  
    55?>
    66<div class="qapl-no-posts-found">
    7 <p><?php echo esc_html__('No posts found', 'quick-ajax-post-loader') ?></p>
     7<?php qapl_output_template_no_post_message(); ?>
    88</div>
Note: See TracChangeset for help on using the changeset viewer.