TableOn
Показує записи WordPress і користувацькі типи записів як таблиці з сортуванням і фільтрами, побудовані з конструктора стовпців.
- Перший реліз
- Активні встановлення
- 200+
- Рейтинг
- Читати відгуки
Про мене
TableOn рендерить записи будь-якого типу як таблицю. Адміністратор будує таблиці з наперед визначених стовпців (заголовок, мініатюра, автор, дати, кількість коментарів, таксономії, галерея) та з мета-полів запису, додає форму фільтра, наперед задані підмножини й скіни та розміщує результат шорткодом, у спливному вікні або всередині іншого сайту через iframe.
З інженерного погляду це дві частини. На сервері один публічний ajax-ендпоінт перетворює визначення таблиці та стан фільтра на WP_Query і повертає рядки як JSON. У браузері клас таблиці без залежностей розбиває на сторінки, сортує й шукає, або через ajax, або за вже завантаженими даними, і перемикається на компактний вигляд на вузьких екранах.
Складні частини — це перетворення одного налаштовуваного визначення таблиці на WP_Query для будь-якого типу записів, типізація мета-полів, які WordPress зберігає як рядки, і збереження незалежності кількох таблиць з різними скінами та мовами на одній сторінці.
TableOn · таблиця записів
що розв'язано
Профілі стовпців і ендпоінт запиту
shipped · 2020Що це даєПерсонал вирішує, які стовпці показує таблиця і які записи вона включає, а кожен стовпець можна сортувати й фільтрувати однаково.
- Проблема
- Один ajax-ендпоінт віддає рядки для кожної таблиці: будь-який тип записів, мета-стовпці, визначені адміністратором, фільтри, наперед задані підмножини й порядки сортування. Те саме поле має відображати клітинку, сортувати запит і діяти як фільтр.
- Рішення
Таблицю описує профіль: масив ключів полів, кожен із замиканнями для значення клітинки, аргументів запиту та даних віджета фільтра. Запитані стовпці шукаються в цьому профілі за ключем.
- Стек
Одне визначення поля має керувати клітинкою, сортуванням і фільтромЗапитані поля лише індексують профіль; кожен ключ приносить власні замикання
TABLEON_Default::action() повертає профіль: для кожного ключа заголовок, замикання 'action', що рендерить клітинку, а для ключів, які можна фільтрувати, get_filter_query_args і get_filter_draw_data. get_table_data() проходить по запитаних полях і викликає $profile[$field]['action'] лише коли ключ існує, тож невідома назва поля ігнорується. Кожен рядок також несе pid, який використовують дії клітинок на фронтенді.
Мета-поля, визначені адміністратором, потребують типізованої поведінки запитуМета-рядки мають тип text, number або calendar; кожен тип будує власний meta_query
assemble_meta_for_system() перетворює рядок мета-таблиці на запис профілю. Text використовує LIKE і текстове поле. Number використовує BETWEEN з типом numeric зі значення 'min:max', повзунок діапазону й сортування meta_value_num. Calendar порівнює або як unix-мітку часу (числово), або як DATETIME, на вибір для кожного поля, бо такі плагіни, як ACF, зберігають рядки дат, а інші зберігають мітки часу.
Деякі порядки сортування не виражаються аргументами WP_QueryТимчасове замикання posts_orderby для post_status, що знімається одразу після запиту
Сортування за post_status виконується замиканням, підключеним до posts_orderby на час одного WP_Query і знятим після нього, тож воно не впливає на інші запити на сторінці. Значення випадного списку сортування, як-от title-desc або <meta_key>-desc, відображаються на orderby/order, з meta_value_num для мета-полів типу number.
Таблиці, обмежені вибраною підмножиною записівПравила передвизначення стають post__in, post__not_in, author__in і tax_query
Кожна таблиця може зберігати правила: ID записів, виключені ID, автори, терміни для включення чи виключення. get_table_data() застосовує їх перед фільтрами відвідувача, з приведенням ID до цілих чисел. Атрибут шорткоду author=N вбудовується в ті самі правила (коментар у коді датований 16-09-2020).
Конфігурація таблиці погано вписується в post metaЧотири власні таблиці через dbDelta: таблиці, стовпці, мета-поля, словник
Стовпці — це рядки з table_id, field_key, pos_num, is_active, show_on_mobile і параметрами в JSON, проіндексовані за table_id та is_active, тож активні стовпці таблиці — це один індексований запит. Уся конфігурація експортується одним JSON-документом; імпорт очищає кожну таблицю й вставляє рядки заново, за перевіркою ролі.
Форма фільтра над записами та мета-даними
shipped · 2020Що це даєВідвідувачі звужують таблиці за текстом, категоріями, діапазонами чисел і датами. Межі повзунків відповідають реальним даним, тож персоналу не потрібно вводити їх вручну.
- Проблема
- Форма фільтра генерується з того самого профілю для будь-якого типу записів: текстовий пошук, дерева таксономій, числові діапазони й діапазони дат. У плагіна немає власного індексу, тож межі й опції мають надходити з живих даних.
- Рішення
Кожен ключ фільтра надає дані для відображення (межі, опції, підписи) і побудовник запиту. Числові межі беруться із запитів MIN/MAX, якщо їх не задав адміністратор. Умови, які WP_Query виразити не може, проходять через posts_where: текстові значення екрануються й готуються, дати форматуються через date(), а кількості приводяться через intval().
- Стек
Текстовий пошук по вибраних стовпцях, без урахування регістру, безпечнийposts_where з LOWER(field) LIKE; поля з білого списку, значення підготовлені та пропущені через esc_like
Стовпці для пошуку беруться з атрибута шорткоду tableon_text_search_by, але фільтруються до post_title, post_content і post_excerpt, тож назва стовпця ззовні ніколи не потрапляє в SQL поза цим списком. Пошуковий вираз переводиться в нижній регістр допоміжною функцією з підтримкою багатобайтових символів, екранується через esc_like() і прив'язується через $wpdb->prepare().
Повзункам діапазону потрібні межі, яких адміністратор не вводивТипові межі — MIN/MAX від CAST(meta_value AS UNSIGNED) для мета-ключа
get_field_drawing_data() використовує збережені min/max таблиці, коли вони задані; інакше запитує wp_postmeta за ключем із числовим приведенням, тож числа, збережені як текст, порівнюються як числа. Межі кількості коментарів — це MIN/MAX за wp_posts для типу записів таблиці.
Одне поле дати потребує двох полів введення: від і доНамалювати парний ключ із суфіксом ---to; провайдер маршрутизує його за прапорцем напрямку
draw_filter_form_data() дублює поле calendar як <key>---to з підписами 'From:' і 'To:'. Такого ключа в профілі немає, тож provider() розпізнає суфікс, відсікає його й викликає побудовник запиту початкового поля з is_calendar_dir_to = true, що перевертає >= на <=.
Множинний вибір таксономії потребує IN, NOT IN або AND для кожної таблиціОператор зберігається для кожної таблиці й перевіряється за білим списком перед tax_query
Опція mselect-logic читається з параметрів фільтра таблиці й замінюється на IN, якщо вона не є одним із IN, NOT IN, AND. ID термінів потрапляють у tax_query за term_id.
Ієрархічні списки термінів з наборами include та excludeРекурсивне дерево для кожного батьківського терміна з префіксом глибини, відфільтроване за списками ID
build_taxonomy_tree() проходить терміни батьківський за батьківським, пропускає виключені ID, залишає лише включені ID, коли цей список задано, і додає до заголовків по одному тире на рівень, щоб плоский select показував ієрархію. Він виконує один виклик get_terms() на кожного батька з hide_empty.
Інші плагіни фільтрів мають мати змогу керувати тією самою таблицеюХук-провайдер tableon_filter_provider_{name} переписує аргументи WP_Query
Запит називає провайдера фільтра; get_table_data() передає аргументи запиту, дані фільтра й аргументи шорткоду через відповідний фільтр. Вбудована форма — це провайдер 'default'. Taxonomy Chain Menu використовує клієнтську частину цього, записуючи filter_data у таблицю й просячи її перемалюватися.
Клієнтський рушій таблиць
shipped · 2020Що це даєРозбиття на сторінки, сортування й пошук працюють швидко, бо вже завантажені дані використовуються повторно, а широкі таблиці на телефонах перемикаються на компактний вигляд.
- Проблема
- Таблиці працюють на сторінках, у спливних вікнах та iframe і мають розбиватися на сторінки, сортуватися й шукати, не чекаючи сервера на кожен клік. Швидкі кліки призводять до того, що відповіді приходять у неправильному порядку, а широкі таблиці не вміщуються на телефонах.
- Рішення
Клас JavaScript без залежностей із трьома режимами даних, вбудованим у браузер SQL-рушієм для завантажених рядків, кешем на кожен запит, скасуванням запитів і компактним виглядом нижче налаштовуваної ширини.
- Стек
Повільна раніша відповідь не повинна перезаписувати новішу сторінкуAbortController скасовує попередній fetch перед стартом нового запиту
Кожен ajax-запит зберігає свій AbortController; новий запит спершу перериває незавершений, тож малюється лише найостанніший стан сторінки, сортування чи фільтра.
Сортувати й розбивати на сторінки дані, які вже є в браузеріРежим json виконує AlaSQL SELECT, ORDER BY і LIMIT над завантаженими рядками
У режимі json рядки приходять вбудованими в сторінку. Пошук за заголовком, підрахунок, ORDER BY і LIMIT/OFFSET будуються як SQL-рядки й виконуються AlaSQL над масивом у пам'яті, тож розбиття на сторінки та сортування не потребують запитів.
Завантажити через ajax один раз, а потім більше не робити звернень до сервераРежим to_json: перша ajax-відповідь стає локальними даними, а режим перемикається на json
to_json стартує як ajax із прапорцем перемикання. Після першої відповіді рядки зберігаються як table_data, а режим стає json. На сервері режими json запитують усі відповідні записи (posts_per_page = -1), що код позначає як ризик для пам'яті, тож цей режим підходить для малих і середніх наборів.
Повторні запити сторінок, які вже бачилиКешувати відповіді за 32-бітним хешем JSON-об'єкта запиту
set_cache() і get_cache() ключують відповіді за __hash_object(request_data), рядковим хешем над JSON.stringify від усього запиту (сторінка, порядок, фільтри). Повернення на вже бачену сторінку обслуговується з пам'яті. Кеш вимкнено в режимах json, to_json і load-more, де дані й так локальні.
Широкі таблиці на телефонахКомпактний вигляд нижче заданої ширини, приховування окремих стовпців на мобільних, обмежена за частотою обробка зміни розміру
Нижче compact_view_width рядки малюються як складені клітинки, а заголовки приховуються. Обробник зміни розміру перемальовує лише тоді, коли компактний стан справді змінюється, і блокує себе на 999 мс між запусками. Стовпці можна прибрати на мобільних (hide_on_mobile) або приховати нижче ширини в пікселях згенерованими правилами @media. Рядки будуються в DocumentFragment і вставляються один раз.
Вбудовування, ізоляція та доступ до адмінки
у продуктіЩо це даєКілька по-різному оформлених таблиць можуть ділити сторінку, таблиці можна показувати на інших сайтах, підписи відповідають мові сайту, а керувати ними можуть вибрані ролі персоналу.
- Проблема
- Кілька таблиць із різними скінами можуть ділити одну сторінку, таблицю можна вбудувати в інший сайт, підписи мають відповідати мові сайту, а керування таблицями не обмежується адміністраторами.
- Рішення
CSS обмежується HTML-ідентифікатором кожної таблиці під час рендерингу, віддалене вбудовування йде через згенерований скрипт-завантажувач, підписи проходять через таблицю перекладів, а екрани адмінки закриваються налаштуванням ролей.
- Стек
Кілька таблиць із різними скінами на одній сторінціCSS скіна використовує заповнювач 'tid', що замінюється HTML-ідентифікатором таблиці, а потім мінімізується
get_theme_css() спершу завантажує скін з теки tableon-skins теми, потім із плагіна, замінює tid на HTML-ідентифікатор таблиці, прибирає коментарі й пробіли. Стилі окремих стовпців і власний CSS таблиці також мають префікс #<table id>, тож правила однієї таблиці не зачіпають іншу.
Показати таблицю на сайті, що не є WordPressСкрипт-завантажувач будує лінивий iframe на сторінку, що використовує порожній шаблон плагіна
Запит із tableon-remote-page і anchor повертає JavaScript замість сторінки: налаштування як змінні плюс remote.js, який створює лінивий iframe у вказаному контейнері. Сторінка всередині використовує порожній шаблон, який реєструє плагін, тож оформлення теми не показується.
Вбудована JSON-конфігурація не повинна виходити за межі свого HTML-контейнераjson_encode з JSON_HEX_TAG, JSON_HEX_QUOT і JSON_HEX_AMP у прихованому div
Налаштування таблиці та, у режимі json, усі рядки виводяться в сторінку. Кодування <, >, лапок і & як unicode-екранування означає, що заголовки записів чи значення мета-полів не можуть закрити елемент або впровадити розмітку.
Рядки інтерфейсу кількома мовами без файлів .poТаблиця словника зіставляє рядок зі значеннями для кожної мови, завантажується один раз за запит
TABLEON_Vocabulary читає всю таблицю один раз у статичний масив; get() повертає значення для поточної локалі або початковий рядок. Поточна мова проходить через фільтр tableon_current_lang, який також перемикає WPML, тож ajax-запити рендеряться мовою відвідувача.
Таблицями керують редактори, а не лише адміністраториcan_manage_data(): адміністратор або ролі з налаштувань, плюс nonce на кожне збереження
Екрани адмінки реєструються лише для користувачів, які проходять can_manage_data(), що приймає адміністраторів і ролі, перелічені в налаштуванні user_roles_can. Обробники збереження, створення й видалення кожен перевіряють nonce 'tableon'.
Цифри
wordpress.org- Активні встановлення 200+ лічильник wordpress.org.
- Відгуки 15 Середня оцінка: 4.6 з 5.
- Років підтримки 6 З 2 листопада 2020 р., останнє оновлення 12 червня 2026 р..