007AJ Tables – Documentation

Version 1.0.3

GPLv2 or later · by 007AJ · one plugin, nothing else to install

007AJ Tables Full is a complete table and chart plugin. It builds responsive, sortable and searchable tables and Chart.js charts with a spreadsheet-style editor, imports CSV, Excel and JSON, and embeds them with a shortcode or a block. On top of that it brings:

  • live data sources: Google Sheets, JSON APIs, MySQL, posts and WooCommerce;
  • column filters and conditional formatting;
  • formula columns;
  • server-side processing;
  • front-end editing;
  • fixed header and fixed columns;
  • master-detail;
  • Excel and PDF export;
  • folders, a REST API and webhooks.

There is no account to create and no tracking. The plugin only connects to the URLs and services that you configure.

Contents

  1. Installation
  2. Already using the free 007AJ Tables plugin?
  3. Creating a table
  4. The editor
  5. Table settings
  6. Importing data
  7. Charts
  8. Embedding
  9. What visitors see
  10. Permissions
  11. Developer hooks
  12. Data sources
  13. Filters and cascading filters
  14. Conditional formatting
  15. Formula columns
  16. Server-side processing
  17. Front-end editing
  18. Fixed header and columns
  19. Master-detail
  20. Excel and PDF export
  21. Folders
  22. REST API
  23. Webhooks
  24. Security notes
  25. FAQ
  26. Background refresh
  27. Privacy
  28. Limits and requirements
  29. Support

1. Installation

  1. Go to Plugins → Add New → Upload Plugin, upload 007aj-tables-pro.zip, and turn it on.
  2. A 007AJ Tables menu appears in the admin sidebar with All Tables, Add New, Integrations and Documentation.
  3. Create your first table under 007AJ Tables → Add New, or connect a service under Integrations.

Nothing else needs to be installed. Requirements: WordPress 6.2+ and PHP 7.4+. Excel (.xlsx) import needs the PHP zip extension, and private Google Sheets need the PHP OpenSSL extension; most hosts have both.

2. Already using the free 007AJ Tables plugin?

007AJ Tables Full contains everything in the free 007AJ Tables plugin and uses the same storage, so your existing tables, charts, shortcodes, blocks and settings carry over with no import or migration.

  1. Install and turn on 007AJ Tables Full. It takes over straight away: the free plugin’s menus, block, shortcodes and scripts stand down, so nothing runs twice.
  2. A notice suggests deactivating 007AJ Tables, with a one-click link. Do that; your tables stay exactly as they are.
  3. You can then delete the free plugin. If 007AJ Tables Full is active at that moment, it keeps your tables and settings safe while the free plugin removes itself.

The same works in either order: if the free plugin is turned on while 007AJ Tables Full is active, Full keeps running your tables and shows the same notice.

3. Creating a table

Go to 007AJ Tables → Add New. Start from a blank table, a template, or an import. The built-in templates are Blank, Pricing comparison, Feature comparison, Weekly schedule, Product list and Monthly sales (with chart).

The All Tables screen lists every table with its shortcode. From there you can edit, duplicate, export or delete each one.

4. The editor

The grid works like a spreadsheet.

Action How
Edit a cell Click the cell and type. Tab and the arrow keys move between cells.
Select a range Click and drag, or Shift+click.
Add or remove rows and columns Use the toolbar buttons.
Merge cells Select a range, then click Merge. Click Unmerge to split it again.
Formatting Bold, italic, underline (Ctrl/Cmd+B, I, U), alignment, text colour and background colour for the selected cells.
Links and media Link adds a hyperlink. Media inserts an image from the Media Library.
Undo / redo Ctrl/Cmd+Z and Ctrl/Cmd+Y (or Shift+Z).
Save Click Save table or press Ctrl/Cmd+S.

Cell content allows safe inline HTML only: links, images, bold/italic, line breaks and similar tags. Scripts and unsafe attributes are removed when you save.

5. Table settings

Setting What it does
Header row / footer row Uses the first row as the header and the last row as the footer.
Sorting Visitors click a column header to sort. Numbers, dates and text are detected automatically.
Search Adds an instant search box.
Pagination / rows per page Splits long tables into pages.
Responsive mode Scroll scrolls the table sideways on small screens. Stack turns each row into a card on phones.
Theme Default, Minimal, Bold header, Dark or Pricing columns.
Striped / hover Zebra rows and a highlight when the pointer is over a row.
Caption / show title Text shown above the table.
CSV button / Print button Lets visitors download the table as CSV or print it.

6. Importing data

On Add New, choose Import and upload a file in one of these formats:

  • CSV: comma, semicolon or tab separators are detected automatically, and UTF-8 is expected.
  • Excel (.xlsx): the first worksheet is imported.
  • JSON: an array of arrays (rows), or an array of objects (the keys become the header).

You can also export any table as CSV from the All Tables list.

7. Charts

In the editor, open the Chart panel and tick Enable chart. Then set:

  • the chart type: bar, line, pie, doughnut, radar or polar area;
  • the label column and the data columns;
  • the title, height, colours and legend.

The chart uses the table’s data, so it updates whenever the table changes. Chart.js is bundled with the plugin, and nothing is loaded from a CDN.

To show the chart, use [ajtb_chart id="12"], or set the block’s Display option to Chart.

8. Embedding

Shortcode: [ajtb_table id="12"]. Copy it from the editor or from the table list.

Block: in the block editor, add the 007AJ Table block and pick a table from the dropdown.

9. What visitors see

Sorting, search and pagination run in the browser and need no page reloads. The tables are keyboard accessible: sortable headers are buttons and expose aria-sort. Scripts and styles load only on pages that contain a table.

10. Permissions

Managing tables requires the ajtb_manage_tables capability. Administrators always have it. You can grant it to other roles or users, for example Editors, with any role editor plugin. Granted users can manage tables without any other admin rights.

11. Developer hooks

Hook Type Purpose
ajtb_table_data filter Change the rows before rendering. Arguments: ($data, $table, $context).
ajtb_default_settings / ajtb_sanitize_settings filter Add your own table settings.
ajtb_cell_attributes filter Add attributes to a cell. Arguments: ($attrs, $row, $col, $value, $table).
ajtb_wrapper_classes, ajtb_column_classes filter Add CSS classes.
ajtb_front_config filter Change the JSON config passed to the front-end script.
ajtb_templates, ajtb_sources filter Register templates and data sources.
ajtb_table_saved, ajtb_table_deleted action Fired after a table is saved or deleted.
ajtb_editor_panels, ajtb_admin_menu action Add panels to the editor or items to the admin menu.

The front-end script exposes window.AJTB.onInit( function ( instance ) { … } ) and fires the ajtb:refresh event on the table wrapper.

12. Data sources

In the editor, open the Data source panel and pick a source. Click Sync now to load or preview the data.

Results are cached. Use Refresh cache every (minutes) to control how often the source is fetched again.

Google Sheets (public)

Share the sheet as Anyone with the link can view, then paste the sheet link. To read a specific tab, use a link that contains gid=.

Google Sheets (private, service account)

  1. In Google Cloud, create a service account, enable the Google Sheets API, and download a JSON key.
  2. Under 007AJ Tables → Integrations → Google service account, paste the JSON key and save. The key is stored encrypted and is never shown again.
  3. Share your sheet with the service account’s email address. Viewer access is enough.
  4. In the table, choose Private and enter a range such as Sheet1!A1:F200.

Size limits for Google Sheets: a response larger than 10 MB, or a sheet with more than 5,000 rows (header included) or 60 columns, is not loaded. Instead you get a clear error in the editor, on the Integrations screen and in an admin notice, telling you to choose a smaller tab or range. Nothing is cut off silently.

JSON API / URL

Enter the URL and, if needed, a Path to the list in dot notation, for example data.items. Nested objects become columns with dotted names, such as address.city.

You can limit and order the output with Columns to show. An optional Authorization header value is stored encrypted and is never displayed again. Type - to clear it.

MySQL query (visual builder)

This source is for administrators only. Quick start: if the builder says no tables are allowed yet, open 007AJ Tables → Integrations → MySQL tables, tick the tables you want to use and save — this allow-list is a security feature, not an error. First, an administrator chooses which database tables are allowed under Integrations → MySQL tables. WordPress user, option and session tables are never offered.

In the editor, pick a table, columns, conditions, order and limit. The builder generates a read-only SELECT, and all values are passed as prepared parameters. Columns whose names look like passwords, tokens or keys are hidden.

WordPress posts / custom post types

Choose a post type and fields: image, title, date, updated, author, excerpt, categories, tags, type, link and public custom fields. Only published, public posts that are not password-protected are listed.

WooCommerce products

Fields are image, product, SKU, category, short description, price, stock and an add-to-cart button. This source needs WooCommerce to be active.

13. Filters and cascading filters

In the Filters panel, give a column a filter type:

  • Dropdown (select);
  • Text (contains);
  • Range (min–max for numbers).

Tick Cascading to make each dropdown list only the values that still match the other filters. For example, choosing a Region narrows the City list. A Reset button clears all filters.

14. Conditional formatting

Add rules in the form column + operator + value → background, text colour, bold. The operators are >, ≥, <, ≤, equals, not equals, contains, does not contain, empty and not empty.

Each rule styles either the matching cell or the whole row. When several rules match, they are applied in order.

15. Formula columns

Formula columns are computed columns added to the right of the table. Refer to other columns by their header in braces:

{Seats} * {Unit price}
ROUND({Revenue} - {Costs}, 2)
IF({Stock} < 5, 1, 0)

The supported operators are + - * / % and parentheses. The supported functions are SUM, AVG, MIN, MAX, ROUND, ABS, IF; any other name is rejected.

Currency symbols and thousands separators in cells are ignored when values are read. You can set decimals, a prefix and a suffix for the result. Formulas are evaluated by a safe parser, and no PHP eval is used.

16. Server-side processing

When this is enabled, the page only receives the visible rows. Sorting, search, filters and pagination are handled by the server through the REST endpoint ajtb-pro/v1/tables/{id}/rows.

For MySQL tables, paging is done in SQL. Use server-side processing for tables with thousands of rows.

17. Front-end editing

Tick Allow front-end editing and choose which roles may edit. Users who can manage tables can always edit.

Allowed signed-in users double-click a cell, type, and press Enter to save, or Esc to cancel. The change is saved instantly through the REST API with a nonce, and a cell.updated webhook fires.

Users without the table capability can only save plain text. Header cells and formula columns cannot be edited. Front-end editing applies to manual tables; tables with external sources are read-only.

18. Fixed header and columns

Fixed header keeps the header row visible while the table scrolls inside a box of the height you set. Fixed columns pins the first 1–5 columns while the visitor scrolls sideways.

19. Master-detail

With master-detail on, clicking a row (or pressing Enter on it) opens an accessible dialog that shows the whole record. You can mark some columns as detail-only: they are hidden in the table and shown only in the dialog, which is ideal for long notes or contact details.

20. Excel and PDF export

Enable Excel button and/or PDF button to let visitors download the table as .xlsx or as a landscape A4 PDF. Downloads contain exactly the rows the visitor currently sees: the same search, column filters and sort, across all pages (not only the current page), together with formula columns and detail-only columns. With no search or filter, the whole table is downloaded. This works for manual tables and every data source, with server-side processing on or off.

The CSV button of the table and the CSV export in the admin protect against spreadsheet formulas: a cell that starts with =, +, -, @, a tab or a carriage return is written with a leading apostrophe so spreadsheet apps show it as text (for example =1+1 or =HYPERLINK(…) stay literal). Plain numbers such as -12, -1,234.50 or -15% are kept as numbers.

Both files are generated by the plugin itself, with no external services and no extra PHP extensions.

Characters in PDF files. PDF downloads embed Unicode fonts, so text keeps its characters and stays searchable and copyable: Latin with all accents (for example Łódź, Ünïcödé), Greek (Ελλάδα), Cyrillic (Привет), common symbols, and Chinese, Japanese and Korean (漢字, かな, 한국어). Chinese, Japanese and Korean are covered for about 14,000 commonly used characters (the GB 2312, JIS X 0208, KS X 1001 and Big5 level 1 sets, kana and Hangul jamo); a rarer character, or a script outside these (for example Arabic, Hebrew, Thai or Indic scripts and emoji), is shown as an empty box in the PDF and never as a question mark. Excel downloads keep every character exactly. Each PDF contains only the glyphs it uses, so files stay small. The fonts are DejaVu Sans and WenQuanYi Zen Hei; their licences are in assets/fonts.

21. Folders

Create folders under Integrations → Folders, assign a folder in the table editor, and filter the All Tables list by folder.

22. REST API

The namespace is /wp-json/ajtb-pro/v1. Authentication uses normal WordPress methods: cookie with nonce, or Application Passwords.

Route Method Access
/tables GET, POST Users with ajtb_manage_tables. Lists or creates tables.
/tables/{id} GET, PUT/PATCH, DELETE Users with ajtb_manage_tables. MySQL tables are administrators only.
/tables/{id}/rows GET Public only when server-side processing is on for that table. Parameters: page, len, search, sort, dir, filters (JSON).
/tables/{id}/cell POST Users allowed to edit that table. Body: {r, c, value}.
/tables/{id}/export?format=xlsx|pdf|csv|json GET Public for the formats enabled on the table; managers can use all formats.

Example:

curl -u admin:APPLICATION_PASSWORD https://example.com/wp-json/ajtb-pro/v1/tables

Secrets such as JSON authorization headers are never returned by the API; they show as (set).

23. Webhooks

Under Integrations → Webhooks, add an HTTPS URL and choose events: table.saved, table.deleted and cell.updated. You can add up to 20 webhooks. Each request is a JSON POST.

Delivery, retries and log. Events are queued and sent after the page has been delivered (or by WP-Cron), so saving a table never waits for your URL. Each request has a 5-second timeout and at most 60 deliveries are sent per minute. If the URL cannot be reached or answers 408, 429 or a 5xx error, the delivery is retried up to 6 times in total: after 1 minute, 5 minutes, 15 minutes, 1 hour and 6 hours (a longer Retry-After is respected). Other 4xx answers fail at once. Every delivery appears in the Delivery log with its status, attempts and last result, and failed ones have a Retry button. Each request carries X-AJTB-Delivery (a delivery ID, the same on every retry) and X-AJTB-Attempt, so your endpoint can ignore duplicates. Finished deliveries are kept for 30 days (newest 1,000).

If you set a secret, every request carries the header X-AJTB-Signature: sha256=<HMAC of body>. Verify it like this:

$sig = 'sha256=' . hash_hmac( 'sha256', file_get_contents( 'php://input' ), $secret );
if ( ! hash_equals( $sig, $_SERVER['HTTP_X_AJTB_SIGNATURE'] ) ) { http_response_code( 401 ); exit; }

Use Send test event to send a sample event right away; the result shows on screen and in the log.

24. Security notes

  • All admin actions check capabilities and nonces. Service-account keys, JSON auth headers and webhook secrets are encrypted at rest (AES-256 with HMAC) using your site’s salts.
  • Remote requests use WordPress’s safe HTTP API, which blocks requests to local or private addresses, and responses have a size limit.
  • MySQL tables are read-only, administrator-only, limited to the allowed database tables, and always use prepared queries.
  • Tables are stored in a custom database table, {prefix}ajtb_tables. Deleting 007AJ Tables Full from the Plugins screen removes its tables, options, cached data, scheduled events and webhook delivery log on every site. If the free 007AJ Tables plugin is still installed, the tables and their settings are kept for it.

25. FAQ

Do I need any other plugin? No. 007AJ Tables Full is self-contained. If you already use the free 007AJ Tables plugin, see Already using the free 007AJ Tables plugin?

Is there a yearly renewal? No. It is a one-time purchase.

How often is Google Sheets / JSON data refreshed? When the cache expires (the interval you choose), when you click Sync now, and by the hourly background refresh described below.

Can visitors edit tables? Only signed-in users whose role you allow, and only on tables where front-end editing is enabled.

26. Background refresh

Every hour, WP-Cron refreshes every Google Sheets and JSON table, however many tables you have. It reads tables in batches of 50 and works for up to 20 seconds per run. If time runs out, it saves its place and the next run continues a minute later from the next table, until every table has been checked. Only one refresh runs at a time.

The schedule is created when you turn the plugin on (or after an update) and removed when you turn it off; turning it back on restores it and continues an unfinished pass.

If a table cannot be refreshed (for example the sheet is no longer shared), visitors keep seeing the last good copy for up to a day, an admin notice lists the failing tables with the error, and Integrations → Background refresh shows every failure, the last complete pass and the next run. The notice clears itself once the table refreshes again.

27. Privacy

Front-end editing saves only the new cell value in the table; it does not record who made the change. If you add a webhook for cell.updated, the editor’s user ID and the old and new cell text are sent to that URL and kept in the delivery log for up to 30 days so failed deliveries can be retried. These log entries are included in Tools → Export Personal Data and removed by Tools → Erase Personal Data. A suggested paragraph is added to the privacy policy guide.

28. Limits and requirements

  • WordPress 6.2 or newer and PHP 7.4 or newer. Excel (.xlsx) import needs the PHP zip extension. The PHP OpenSSL extension is required for saving secrets and for private Google Sheets. No other plugin is needed.
  • Number of tables: no limit. The block picker and the All Tables screen (20 per page, with page links and search) reach every table.
  • Import files: up to 10 MB (CSV, TSV, JSON or XLSX; the first worksheet of an Excel file). Larger imports or saves keep the first 5,000 rows and 60 columns and show a warning.
  • Merged ranges: up to 2,000 per table. Charts: up to 12 data columns. Rows per page on the front end: 1 to 500 (server-side tables always use pagination). Dropdown filter choices: up to 500 per column.
  • Rows and columns per table: up to 5,000 rows (header included) and 60 columns, from any source. Google Sheets larger than that give a clear error; other sources that return more rows show the first 5,000 and an admin notice says so.
  • Google Sheets and JSON responses: up to 10 MB each, with a 15-second timeout.
  • PDF downloads: Latin (with Latin Extended), Greek, Cyrillic and about 14,000 common Chinese, Japanese and Korean characters. Other scripts (for example Arabic, Hebrew, Thai, Indic scripts, emoji) and rare CJK characters appear as empty boxes in PDFs; Excel downloads keep all characters.
  • Webhooks: up to 20; 5-second timeout; at most 60 deliveries per minute; up to 6 attempts; log kept for 30 days (newest 1,000), 25 per page.
  • Background refresh: hourly; batches of 50 tables and 20 seconds per run, continuing until every table is done.
  • External services: Google Sheets (docs.google.com, sheets.googleapis.com, oauth2.googleapis.com) only for tables that use them; the JSON URLs you enter; and the webhook URLs you add. Nothing else.

29. Support

Email admin@007aj.com or send us a message through WPBay. Please include your WordPress and PHP versions, the data source involved, what you did, what you expected and what happened. The error text from the admin notice or the delivery log helps a lot.

Never send passwords, service-account keys or API keys. If we need access to look at something, we will tell you a safe way to give it.