Plugin Directory

Changeset 3234297


Ignore:
Timestamp:
02/03/2025 09:56:47 PM (13 months ago)
Author:
dmrhn
Message:
  • New: Added more filters to better management
  • New: Filters are updated via the posts/pages current table
  • New: JS has been rewritten from scratch, now even faster
  • Improvement: UI changes for better management
Location:
blocks-scanner
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • blocks-scanner/trunk/blocks-scanner.php

    r3083768 r3234297  
    11<?php
    22/*
    3 * Plugin Name:       Blocks Scanner
     3* Plugin Name:       Blocks Scanner – Find and Manage Blocks Across Your Site
    44* Plugin URI:        https://github.com/tdmrhn/blocks-scanner
    5 * Description:       Easily scan and list the Gutenberg blocks used on your site. Quickly edit or view the posts that use the blocks.
    6 * Version:           0.9.1
     5* Description:       Easily find and scan blocks used in posts and pages. Quickly access and edit these posts and pages to efficiently manage block usage.
     6* Version:           1.0
    77* Requires at least: 5.2
    88* Requires PHP:      7.2
     
    1313*/
    1414
    15 if ( ! defined( 'ABSPATH' ) ) exit;
     15if (!defined('ABSPATH')) exit;
    1616
    1717add_action('admin_menu', function () {
     
    3131        $nonce = wp_create_nonce('blocks_scanner_nonce');
    3232        $url = admin_url('tools.php?page=blocks_scanner&blocks_scanner_wpnonce=' . $nonce);
    33             if ( ! isset( $_POST['blocks_scanner_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash ( $_POST['blocks_scanner_nonce'] ) ) , 'blocks_scanner_nonce' ) ) {
    34             $plugin_data = get_plugin_data( __FILE__ );
    35             $plugin_version = $plugin_data['Version'];
     33        if (!isset($_POST['blocks_scanner_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['blocks_scanner_nonce'])), 'blocks_scanner_nonce')) {
     34            $plugin_data = get_plugin_data(__FILE__);
     35            $plugin_version = $plugin_data['Version'];
    3636            wp_enqueue_script('blocks-scanner-script', plugin_dir_url(__FILE__) . 'build/script.min.js', array(), $plugin_version, true);
    3737            wp_enqueue_style('blocks-scanner-style', plugin_dir_url(__FILE__) . 'build/styles.min.css', array(), $plugin_version);
     
    4848    $related_posts = $data['related_posts'];
    4949   
     50    // Get unique post types and titles
     51    $post_types = array();
     52    $post_titles = array();
     53    foreach ($related_posts as $block_posts) {
     54        foreach ($block_posts as $post) {
     55            $post_type = get_post_type($post);
     56            $post_types[$post_type] = isset($post_types[$post_type]) ? $post_types[$post_type] + 1 : 1;
     57            $post_titles[$post->ID] = array(
     58                'title' => $post->post_title,
     59                'count' => isset($post_titles[$post->ID]) ? $post_titles[$post->ID]['count'] + 1 : 1
     60            );
     61        }
     62    }
     63   
    5064    echo '<div class="wrap blocks_scanner">';
     65    echo '<div class="content-wrap">';
     66    echo '<div>';
    5167    echo '<h1>' . esc_html__('Blocks Scanner', 'blocks-scanner') . '</h1>';
    52     echo '<nav class="nav-tab-wrapper">';   
     68    // Filters section
     69    echo '<div class="content-nav">';
     70   
     71    // Block Categories filter
     72    echo '<div class="dhn-group">';
     73        echo '<div class="head">';
     74    echo '<span>' . esc_html__('Block Plugin', 'blocks-scanner') . '</span>';
     75    echo '<span>' . esc_html__('Blocks', 'blocks-scanner') . '</span>';
     76        echo '</div>';
     77        echo '<ul>';
    5378    $processed_categories = array();
    54    
    5579    foreach ($blocks as $block => $count) {
    5680        $block_category = substr($block, 0, strpos($block, '/'));
    57         $block_parts = explode('-', str_replace('_', '-', $block_category));
    58         $block_name = reset($block_parts);
    59        
    60         if ($block_name === "wp") {
    61             $block_name = $block_name . "-" . $block_parts[1];
    62         }
     81        $block_parts = explode('-', str_replace('_', '-', $block_category));
     82        $block_name = reset($block_parts);
     83        if ($block_name === "wp") {
     84            $block_name = $block_name . "-" . $block_parts[1];
     85        }
    6386        if (!in_array($block_name, $processed_categories)) {
    64             $block_name_show = str_replace('-', ' ', $block_name);
    65             $block_name_show = ucwords(strtolower($block_name_show));
    66             echo '<a href="#' . esc_attr($block_name) . '-blocks" class="nav-tab">' . esc_html( $block_name_show ) . ' ' . esc_html__('Blocks', 'blocks-scanner') . '</a>';
     87            $block_name_show = str_replace('-', ' ', $block_name);
     88            $block_name_show = ucwords(strtolower($block_name_show));
     89            echo '<li class="filter-item">';           
     90            echo '<input type="checkbox" id="category-' . esc_attr($block_name) . '" class="category-filter" value="' . esc_attr($block_name) . '">';
     91            echo '<label for="category-' . esc_attr($block_name) . '"><span>' . esc_html($block_name_show) . '</span> <span class="count">0</span></label>';
     92            echo '</li>';
    6793            $processed_categories[] = $block_name;
    6894        }
    6995    }
    70    
    71     echo '</nav>';
    72    
    73     foreach ($processed_categories as $category) {
    74         echo '<div id="' . esc_attr($category) . '-blocks" class="tab-content">';
    75         blocks_scanner_table($blocks, $related_posts, $category);
    76         echo '</div>';
    77     }
    78    
    79     echo '</div>';
    80 }
    81 
    82 function blocks_scanner_table($blocks, $related_posts, $category) {
    83     $table_id = $category;
    84 
    85     echo '<div class="content-wrap">';
    86     echo '<div class="content-nav">';
    87         echo '<div class="block-filter_head">';
     96    echo '</ul>';
     97    echo '</div>';
     98   
     99    // Post Types filter
     100    echo '<div class="dhn-group">';
     101        echo '<div class="head">';
     102    echo '<span>' . esc_html__('Post Type', 'blocks-scanner') . '</span>';
     103    echo '<span>' . esc_html__('Blocks', 'blocks-scanner') . '</span>';
     104        echo '</div>';
     105        echo '<ul>';
     106    foreach ($post_types as $type => $count) {
     107        echo '<li class="filter-item">';
     108        echo '<input type="checkbox" id="post-type-' . esc_attr($type) . '" class="postType-filter" value="' . esc_attr($type) . '">';
     109        echo '<label for="post-type-' . esc_attr($type) . '"><span>' . esc_html($type) . '</span> <span class="count">0</span></label>';
     110        echo '</li>';
     111    }
     112    echo '</ul>';
     113    echo '</div>';
     114   
     115    // Post/Page Titles filter
     116    echo '<div class="dhn-group">';
     117   
     118        echo '<div class="head">';
     119    echo '<span>' . esc_html__('Post/Page Title', 'blocks-scanner') . '</span>';
     120    echo '<span>' . esc_html__('Blocks', 'blocks-scanner') . '</span>';
     121        echo '</div>';
     122    echo '<input type="text" class="title-search" placeholder="' . esc_html__('Search titles...', 'blocks-scanner') . '">';
     123        echo '<ul class="titles-list">';
     124    foreach ($post_titles as $post_id => $data) {
     125        echo '<li class="filter-item">';
     126        echo '<input type="checkbox" id="title-' . esc_attr($post_id) . '" class="title-filter" value="' . esc_attr($post_id) . '">';
     127        echo '<label for="title-' . esc_attr($post_id) . '"><span>' . esc_html($data['title']) . '</span> <span class="count">0</span></label>';
     128        echo '</li>';
     129    }
     130    echo '</ul>';
     131    echo '</div>';
     132   
     133    // Block Names filter
     134    echo '<div class="dhn-group">';
     135   
     136        echo '<div class="head">';
    88137    echo '<span>' . esc_html__('Block Name', 'blocks-scanner') . '</span>';
    89138    echo '<span>' . esc_html__('Posts', 'blocks-scanner') . '</span>';
    90139        echo '</div>';
    91         echo '<ul class="block-filter">';
    92     foreach ($blocks as $block => $count) {
    93         $block_category = substr($block, 0, strpos($block, '/'));
    94         $block_parts = explode('-', str_replace('_', '-', $block_category));
    95         $block_name = reset($block_parts);
    96         if ($block_name === "wp") {
    97             $block_name = $block_name . "-" . $block_parts[1];
    98         }
    99         if ($block_name === $category) {
    100             echo '<li>';
    101             echo '<input type="checkbox" id="block-' . esc_attr($block) . '" class="block-checkbox" value="' . esc_attr($block) . '">';
    102             echo '<label for="block-' . esc_attr($block) . '">' . esc_html($block) . ' <span>' . esc_html($count) . '</span></label>';
    103             echo '</li>';
    104         }
    105     }
    106     echo '</ul>';
    107     echo '</div>';
     140    echo '<input type="text" class="block-name-search" placeholder="' . esc_html__('Search blocks...', 'blocks-scanner') . '">';
     141        echo '<ul class="block-names-list">';
     142    foreach ($blocks as $block => $count) {
     143        echo '<li class="filter-item">';
     144        echo '<input type="checkbox" id="block-' . esc_attr($block) . '" class="block-filter" value="' . esc_attr($block) . '">';
     145        echo '<label for="block-' . esc_attr($block) . '"><span>' . esc_html($block) . '</span> <span class="count">0</span></label>';
     146        echo '</li>';
     147    }
     148    echo '</ul>';
     149    echo '</div>';
     150   
     151    echo '</div>';
     152    echo '</div>'; // End filters-section
     153   
     154    // Table section
    108155    echo '<div class="content-table">';
    109     echo '<div class="content-table_top"><div><span class="row-count"></span> ' . esc_html__('rows', 'blocks-scanner') . '</div>';
    110     echo '<input type="text" id="dhn-filter' . '-' . esc_html($table_id) . '" class="dhn-filter" placeholder="' . esc_html__('Search Table', 'blocks-scanner') . '">';
    111     echo '</div>';
    112    
     156    echo '<div class="content-table_top">';
     157    echo '<div><span class="row-count">0</span> ' . esc_html__('rows', 'blocks-scanner') . '</div>';
     158    echo '<input type="text" class="table-search" placeholder="' . esc_html__('Search Table', 'blocks-scanner') . '">';
     159    echo '</div>';
     160   
    113161    echo '<div class="content-table_wrap">';
    114     echo '<table id="dhn-list' . '-' . esc_html($table_id) . '" class="wp-list-table widefat striped">';
     162    echo '<table class="wp-list-table widefat striped">';
    115163    echo '<thead>';
    116164    echo '<tr>';
     165    echo '<th id="post_id" data-type="number">' . esc_html__('ID', 'blocks-scanner') . '</th>';
    117166    echo '<th id="post_page_title" data-type="string">' . esc_html__('Post/Page Title', 'blocks-scanner') . '</th>';
    118167    echo '<th id="block_name" data-type="string">' . esc_html__('Block Name', 'blocks-scanner') . '</th>';
     
    123172    echo '</thead>';
    124173    echo '<tbody>';
    125 
     174   
     175    // Output all rows initially (they will be filtered by JavaScript)
    126176    foreach ($blocks as $block => $count) {
    127         $block_category = substr($block, 0, strpos($block, '/'));
    128         $block_parts = explode('-', str_replace('_', '-', $block_category));
    129         $block_name = reset($block_parts);
    130         if ($block_name === "wp") {
    131             $block_name = $block_name . "-" . $block_parts[1];
    132         }
    133         if ($block_name === $category) {
    134             $posts = isset($related_posts[$block]) ? $related_posts[$block] : array();
    135             if (!empty($posts)) {
    136                 foreach ($posts as $post) {
    137                     $post_type = get_post_type($post);
    138                     $block_count = blocks_scanner_count_blocks(parse_blocks($post->post_content), $block);
    139                     echo '<tr>';
    140                     echo '<td class="has-row-actions">';
    141                     echo '<strong><a href="' . esc_url(get_edit_post_link($post->ID)) . '">' . esc_html($post->post_title) . '</a></strong>';
    142                     echo '<div class="row-actions">';
    143                     echo '<span class="edit"><a href="' . esc_url(get_edit_post_link($post->ID)) . '">' . esc_html__('Edit', 'blocks-scanner') . '</a> | </span>';
    144                     echo '<span class="view"><a href="' . esc_url(get_permalink($post->ID)) . '">' . esc_html__('View', 'blocks-scanner') . '</a></span>';
    145                     echo '</div>';
    146                     echo '</td>';
    147                     echo '<td>' . esc_html($block) . '</td>';
    148                     echo '<td>' . esc_html($block_count) . ' ' . esc_html(_n('block', 'blocks', $block_count, 'blocks-scanner')) . '</td>';
    149                     echo '<td>' . esc_html($post_type) . '</td>';
    150                     echo '<td>' . esc_html(get_the_modified_date('', $post->ID)) . '</td>';
    151                     echo '</tr>';
     177        $posts = isset($related_posts[$block]) ? $related_posts[$block] : array();
     178        if (!empty($posts)) {
     179            foreach ($posts as $post) {
     180                $post_type = get_post_type($post);
     181                $block_count = blocks_scanner_count_blocks(parse_blocks($post->post_content), $block);
     182                $block_category = substr($block, 0, strpos($block, '/'));
     183                $block_parts = explode('-', str_replace('_', '-', $block_category));
     184                $category = reset($block_parts);
     185                if ($category === "wp") {
     186                    $category = $category . "-" . $block_parts[1];
    152187                }
    153             }
    154         }
    155     }
    156 
     188               
     189                echo '<tr data-block="' . esc_attr($block) . '" data-category="' . esc_attr($category) . '" data-post-type="' . esc_attr($post_type) . '">';
     190                echo '<td>' . esc_html($post->ID) . '</td>';
     191                echo '<td class="has-row-actions">';
     192                echo '<strong><a href="' . esc_url(get_edit_post_link($post->ID)) . '">' . esc_html($post->post_title) . '</a></strong>';
     193                echo '<div class="row-actions">';
     194                echo '<span class="edit"><a href="' . esc_url(get_edit_post_link($post->ID)) . '">' . esc_html__('Edit', 'blocks-scanner') . '</a> | </span>';
     195                echo '<span class="view"><a href="' . esc_url(get_permalink($post->ID)) . '">' . esc_html__('View', 'blocks-scanner') . '</a></span>';
     196                echo '</div>';
     197                echo '</td>';
     198                echo '<td>' . esc_html($block) . '</td>';
     199                echo '<td>' . esc_html($block_count) . ' ' . esc_html(_n('block', 'blocks', $block_count, 'blocks-scanner')) . '</td>';
     200                echo '<td>' . esc_html($post_type === 'wp_block' ? 'pattern' : $post_type) . '</td>';
     201                echo '<td>' . esc_html(get_the_modified_date('', $post->ID)) . '</td>';
     202                echo '</tr>';
     203            }
     204        }
     205    }
     206   
    157207    echo '</tbody>';
    158208    echo '</table>';
    159209    echo '</div>';
    160210    echo '</div>';
    161     echo '</div>';
     211   
     212    echo '</div>'; // End content-wrap
     213    echo '</div>'; // End wrap
    162214}
    163215
     216// Keep existing helper functions
    164217function blocks_scanner_count_blocks($blocks, $block_name) {
    165218    $block_count = 0;
     
    180233    $processed_posts = [];
    181234
    182     $post_types = get_post_types(array('public' => true), 'objects');
     235    $post_types = get_post_types([], 'objects');
    183236    $post_type_slugs = array_keys($post_types);
     237    $excluded_post_types = ['wp_navigation', 'attachment', 'nav_menu_item', 'revision', 'custom_css', 'customize_changeset', 'user_request', 'oembed_cache'];
     238    $post_type_slugs = array_diff($post_type_slugs, $excluded_post_types);
     239
     240
    184241    $args = array(
    185242        'post_type'      => $post_type_slugs,
  • blocks-scanner/trunk/build/script.min.js

    r3082273 r3234297  
    1 document.addEventListener("DOMContentLoaded",()=>{new class e{constructor(){this.blocksScannerWrapper=document.querySelector(".blocks_scanner"),this.tabWrapper=this.blocksScannerWrapper.querySelectorAll(".nav-tab-wrapper a"),this.tabContent=this.blocksScannerWrapper.querySelectorAll(".tab-content"),this.filterInputs=this.blocksScannerWrapper.querySelectorAll(".tab-content .dhn-filter, .tab-content .block-checkbox"),this.initialize()}toggleTab(e){event.preventDefault();let t=e.getAttribute("href").substring(1);this.tabWrapper.forEach(t=>t.classList.toggle("nav-tab-active",t===e)),this.tabContent.forEach(e=>e.classList.toggle("active",e.id===t))}updateRowCountAndFilter(){this.tabContent.forEach(e=>{let t=e.querySelector(".dhn-filter"),r=e.querySelectorAll(".block-checkbox"),a=e.querySelectorAll("tbody tr"),n=e.querySelector(".row-count"),o=t.value.trim().toLowerCase(),l=Array.from(r).filter(e=>e.checked).map(e=>e.value.toLowerCase()),i=0;a.forEach(e=>{let t=e.cells[1].textContent.trim().toLowerCase(),r=(0===l.length||l.includes(t))&&e.textContent.toLowerCase().includes(o);e.style.display=r?"":"none",r&&i++}),n.textContent=i})}sortGrid(e,t,r,a){let n;let o=e.querySelector("tbody"),l=Array.from(o.rows);switch(r){case"number":n=(e,r)=>Number(e.cells[t].innerHTML)-Number(r.cells[t].innerHTML);break;case"string":n=(e,r)=>{let a=e.cells[t].textContent.trim().toLowerCase(),n=r.cells[t].textContent.trim().toLowerCase();return a.localeCompare(n,void 0,{numeric:!0})};break;case"date":n=(e,r)=>new Date(e.cells[t].innerHTML)-new Date(r.cells[t].innerHTML)}"asc"===a?l.sort(n):l.sort((e,t)=>n(t,e)),o.innerHTML="",l.forEach(e=>o.appendChild(e))}initializeTableSorting(){this.tabContent.forEach(e=>{e.querySelectorAll("table").forEach(e=>{e.onclick=t=>{if("TH"!==t.target.tagName)return;let r=t.target,a=r.cellIndex,n=r.dataset.sortOrder||"asc";n="asc"===n?"desc":"asc",r.dataset.sortOrder=n,this.sortGrid(e,a,r.dataset.type,n)}})})}initialize(){this.tabWrapper.forEach(e=>e.addEventListener("click",()=>this.toggleTab(e))),this.tabWrapper[0].click(),this.filterInputs.forEach(e=>{e.addEventListener("input",()=>this.updateRowCountAndFilter()),e.addEventListener("change",()=>this.updateRowCountAndFilter())}),this.updateRowCountAndFilter(),this.initializeTableSorting()}}});
     1document.addEventListener('DOMContentLoaded',()=>{const table=document.querySelector('table tbody');const tableRows=Array.from(document.querySelectorAll('table tbody tr'));const rowCount=document.querySelector('.row-count');const searchInput=document.querySelector('.table-search');const titleSearchInput=document.querySelector('.title-search');const blockNameSearchInput=document.querySelector('.block-name-search');const filters=['category','postType','block','title'];const getSelectedValues=(filter)=>Array.from(document.querySelectorAll(`.${filter}-filter:checked`)).map(el=>el.value);const updateFilters=()=>{const searchText=searchInput.value.toLowerCase();let visibleRows=[];tableRows.forEach(row=>{const rowText=row.textContent.toLowerCase();const matchesFilters=filters.every(filter=>{const selectedValues=getSelectedValues(filter);if(!selectedValues.length)return!0;return filter==='title'?selectedValues.includes(row.querySelector('td:first-child').textContent.trim()):selectedValues.includes(row.dataset[filter])});const matchesSearch=!searchText||rowText.includes(searchText);const isVisible=matchesFilters&&matchesSearch;row.style.display=isVisible?'':'none';if(isVisible)visibleRows.push(row);});rowCount.textContent=visibleRows.length;filters.forEach(filter=>{document.querySelectorAll(`.${filter}-filter`).forEach(input=>{const value=input.value;const count=visibleRows.filter(row=>filter==='title'?row.querySelector('td:first-child').textContent.trim()===value:row.dataset[filter]===value).length;const filterItem=input.closest('.filter-item');filterItem.style.display=count===0&&!input.checked?'none':'';input.parentElement.querySelector('.count').textContent=count})})};const setupSearch=(searchInput,filterType)=>{searchInput.addEventListener('input',()=>{const searchText=searchInput.value.toLowerCase();document.querySelectorAll(`.${filterType}-filter`).forEach(input=>{const filterItem=input.closest('.filter-item');const label=input.parentElement.textContent.toLowerCase();if(label.includes(searchText)||input.checked){filterItem.style.display=''}else{filterItem.style.display='none'}})})};const setupSort=()=>{document.querySelectorAll('th').forEach(header=>{header.addEventListener('click',function(){const columnIndex=[...this.parentNode.children].indexOf(this);const type=this.dataset.type;const ascending=!this.classList.contains('asc');document.querySelectorAll('th').forEach(th=>th.classList.remove('asc','desc'));this.classList.add(ascending?'asc':'desc');const parseValue=(value)=>{if(type==='number')return parseFloat(value)||0;if(type==='date')return new Date(value);return value.toLowerCase()};[...table.rows].sort((a,b)=>{const aValue=parseValue(a.cells[columnIndex].textContent.trim());const bValue=parseValue(b.cells[columnIndex].textContent.trim());return ascending?aValue>bValue?1:-1:aValue<bValue?1:-1}).forEach(row=>table.appendChild(row))})})};searchInput.addEventListener('input',updateFilters);filters.forEach(filter=>document.querySelectorAll(`.${filter}-filter`).forEach(input=>input.addEventListener('change',updateFilters)));setupSearch(titleSearchInput,'title');setupSearch(blockNameSearchInput,'block');setupSort();updateFilters()})
  • blocks-scanner/trunk/build/styles.min.css

    r3082273 r3234297  
    1 .blocks_scanner .tab-content.active{display:block}.blocks_scanner .tab-content,.blocks_scanner .wp-list-table tr.hide:not(.main){display:none}.blocks_scanner th{cursor:pointer}.blocks_scanner th::after{content:"↑";color:#777;padding-left:5px}.blocks_scanner th[data-sort-order=desc]::after{content:"↓"}.blocks_scanner .content-wrap{display:grid;grid-template-columns:minmax(300px,1fr) minmax(0,4fr);gap:20px;margin-top:10px}.blocks_scanner .content-nav{display:flex;flex-direction:column;margin-top:40px;position:sticky;gap:5px;background:#fff;padding:0 20px 20px;border:1px solid #c3c4c7;top:50px;max-height:calc(100vh - 100px);overflow:auto}.blocks_scanner .content-table{display:flex;flex-direction:column;gap:10px}@media only screen and (max-width:768px){.blocks_scanner .content-wrap{grid-template-columns:minmax(0,1fr)}.blocks_scanner .content-nav{position:relative;top:0;margin-top:0;max-height:30vh}}.blocks_scanner .block-filter li label,.blocks_scanner .block-filter_head,.blocks_scanner .content-table_top{display:flex;width:100%;justify-content:space-between;align-items:center}.blocks_scanner .content-table_top .dhn-filter{max-width:300px;width:300px}.blocks_scanner .content-table_wrap{overflow:auto}.blocks_scanner .content-table_wrap>table{min-width:max-content}.blocks_scanner .content-table_wrap>table th{font-size:1em;font-weight:600!important;padding:10px}.blocks_scanner .block-filter_head{position:sticky;top:0;background:#fff;padding:10px 0;font-weight:600;border-bottom:1px solid #c3c4c7}.blocks_scanner .block-filter{display:grid;gap:5px}.blocks_scanner .block-filter li{display:flex;align-items:center;gap:5px}.blocks_scanner .block-filter li>input{margin:0}.blocks_scanner .block-filter li label span{font-size:12px;border-radius:3px;padding:3px 6px;background:#f6f7f7;font-weight:600;min-width:18px;justify-content:center;display:flex}.blocks_scanner .block-filter li:hover label span{color:#fafafa;background:#2271b1}
     1.blocks_scanner .wp-list-table tr.hide:not(.main){display:none}.blocks_scanner th{cursor:pointer}.blocks_scanner th::after{content:"↓";color:#777;padding-left:5px}.blocks_scanner th.asc::after{content:"↑"}.blocks_scanner .content-wrap{display:grid;grid-template-columns:minmax(300px,1fr) minmax(0,4fr);gap:20px;margin-top:10px}.blocks_scanner .content-wrap h1{padding:5px 0 5px}.blocks_scanner .content-nav{display:flex;flex-direction:column;position:sticky;gap:5px;background:#fff;border:1px solid #c3c4c7;border-top:0;top:55px;max-height:calc(100vh - 75px);overflow:auto}.blocks_scanner .content-table{display:flex;flex-direction:column;gap:10px}@media only screen and (max-width:768px){.blocks_scanner .content-wrap{grid-template-columns:minmax(0,1fr)}.blocks_scanner .content-nav{position:relative;top:0;margin-top:0;max-height:30vh}}.blocks_scanner .dhn-group .head,.blocks_scanner .dhn-group .filter-item label,.blocks_scanner .content-table_top{display:flex;justify-content:space-between;align-items:center}.blocks_scanner .content-table_top .dhn-filter{max-width:300px;width:300px}.blocks_scanner .content-table_wrap{overflow:auto}.blocks_scanner .content-table_wrap>table{min-width:max-content}.blocks_scanner .content-table_wrap>table th{font-size:1em;font-weight:600!important;padding:10px}.blocks_scanner .dhn-group .head{gap:5px;background:#f6f7f7;padding:10px;font-weight:600;border-bottom:1px solid #c3c4c7;border-top:1px solid #c3c4c7}.blocks_scanner .dhn-group ul{max-height:250px;overflow-y:auto;padding:0 20px}.blocks_scanner .dhn-group [class*="search"]{width:calc(100% - 40px);margin:.5rem 20px 0;padding:.2rem .5rem;border:1px solid #ddd;border-radius:4px}.blocks_scanner .dhn-group .filter-item{display:flex;align-items:center;gap:5px}.blocks_scanner .dhn-group .filter-item>input{margin:0}.blocks_scanner .dhn-group .filter-item label{width:100%}.blocks_scanner .dhn-group .filter-item label span:first-child{display:inline-block;align-self:center;max-width:200px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.blocks_scanner .dhn-group .filter-item label .count{font-size:12px;border-radius:3px;padding:3px 6px;background:#f6f7f7;font-weight:600;min-width:18px;max-height:18px;justify-content:center;display:flex}.blocks_scanner .dhn-group .filter-item:hover label .count{color:#fafafa;background:#2271b1}
  • blocks-scanner/trunk/readme.txt

    r3083768 r3234297  
    44Tags: gutenberg, blocks, editor, scan, find
    55Requires at least: 5.0
    6 Tested up to: 6.5
     6Tested up to: 6.7.1
    77Stable tag: 0.9.1
    88License: GPLv2 or later
     
    2424
    2525* Once activated, navigate to Tools > Blocks Scanner in your WordPress admin panel.
    26 * The plugin will automatically scan all posts, pages, and custom post types.
     26* The plugin will automatically scan all posts, pages, and custom post types and patterns.
    2727* You can then view the list of posts that utilize blocks on your site and take appropriate actions quickly.
    2828
     
    7272
    7373== Changelog ==
     74= 1.0 =
     75* New: Added more filters to better management
     76* New: Filters are updated via the posts/pages current table
     77* New: JS has been rewritten from scratch, now even faster
     78* Improvement: UI changes for better management
     79 
     80
    7481= 0.9.1 =
    7582* Fix: If the first word of the blocks set is WP, add the second word
Note: See TracChangeset for help on using the changeset viewer.