We use cookies to make your viewing experience better. By accepting you consent, you agree to our Cookie policy

Accept
Improve your Craft CMS skills

The Ultimate Guide To Craft CMS Table Fields

10 min read
Guide To Craft CMS Table Fields

Struggling to wrangle complex product data, charts, or events into Craft's flexible but sometimes limited native structures? This guide will explain how table fields enable storing flexible tabular datasets directly in Craft CMS, unlocking relational data modeling, enhanced content editing, and powerful templating capabilities. We'll cover everything from configuration best practices to optimizing performance for seamless data-driven experiences.

Table fields in Craft CMS enable storing flexible, tabular datasets directly within content. This provides relational data modeling and enhanced editing capabilities compared to basic entries. Configure columns and rows for structured data. Output data through Twig templates. Optimize performance through indexing, caching, and selective loading for seamless data-driven experiences.

Understanding Table Fields in Craft CMS

What are Table Fields

Table fields in Craft CMS provide a flexible way to store tabular datasets within your content. They allow you to define columns and rows to hold related data, similar to tables in a database.

For example, you could use a table field to store product specifications, with columns for features, dimensions, materials etc. Or to capture data like a nutrition chart, a tournament bracket, or an image gallery. The rows represent each record, and the columns define the attributes for that record.

Compared to other field types like Entries or Categories, table fields are optimized for storing structured tabular data, rather than freeform content. The key difference is that with table fields, your content editors can add, edit and delete rows in a tabular interface.

So anytime you need to store repeatable, structured data records - product specs, charts, advanced matrices etc - table fields are the way to go in Craft. They provide much more convenient editing than cramming all that data into basic Entries.

Benefits of Using Table Fields

There are several key advantages to using table fields for structured and relational data in Craft:

  • They allow storing complex, structured datasets without complicating your content modeling. Rather than creating a bunch of interrelated Entries, you can capture all related data in one handy table field.

  • Table fields provide a simpler editing experience for content editors, with a familiar spreadsheet-style data entry rather than separate Entry forms.

  • You can display the tabular data elegantly on the front-end using Twig, with full control over markup and styling. Much easier than wrangling Entry models in Twig templates.

  • Related data is stored conveniently within one field, making it easier to query, sort and display. The data structure is optimized for Tabular rather than hierarchical content.

  • Table fields enable managing repeating, relational data like product variations,matrices and charts as a single field rather than multiple complex Entries models.

  • You can easily reuse fields across multiple content types. Just create your desired columns once as a Table field, then add it wherever needed.

For any use case involving structured, tabular data, table fields will simplify your content modeling and provide a more robust data structure than basic Entries. They bring the power of relational databases to Craft's flexible content.

Limitations of Table Fields

However, table fields aren't without limitations. Some key considerations:

  • Large, complex datasets can impact performance. Table fields are optimized for convenience rather than massive data volumes. For large data, a custom database solution may be better.

  • There are restrictions around the maximum number of rows per table - currently 100 by default. Workarounds exist, but very large datasets are better handled elsewhere.

  • No relationships or linked fields between table rows. Each row is separate, so no relational data across records.

  • Can't directly integrate table field data with Entries or Categories. You need custom Twig to output the data.

  • No built-in user permissions for rows - user access needs to be handled with Twig.

  • Table fields prioritize data entry over a polished UI. The editing interface is functional but basic.

So while table fields are extremely useful for many purposes, they aren't a complete replacement for a proper database. For some use cases like huge product catalogs, custom database integration may be more appropriate than table fields. But for most purposes, they provide an excellent balance of flexibility, performance and convenience.

Creating Table Fields in Craft CMS

Setting Up Table Columns

When creating a new table field in Craft CMS, the first step is configuring your columns - these define the structure of your data.

You can add as many columns as needed for your particular dataset by clicking the "New column" button. Give each column a descriptive handle and label, like "productName" and "Product Name".

The column type specifies what sort of data it will hold, like Plain Text, Number or Assets. Choose the appropriate type for each column. Certain types like Dropdown and Radio Buttons allow pre-defining options.

You can toggle columns on and off - this allows removing columns later without deleting data. Disable irrelevant columns without losing them.

For text columns, set the formatting like whether Rich Text is enabled. For all columns, set validation rules if needed, like Unique or Required.

The width setting is useful for controlling column widths when displayed in the Control Panel or front-end. You can also rearrange the column order by dragging.

Group related columns together under common headings. For example, group shipping and billing address columns together under an "Address" heading. This organizies complex datasets.

So in summary, carefully name, type, configure and arrange your columns based on the data requirements when first creating your table field.

Configuring Table Settings

In addition to columns, some key settings to configure when creating a new table field include:

Static vs Dynamic Rows

Static rows means a fixed number of rows. Dynamic allows unlimited rows to be added. Choose static if the data is predictably fixed, like a small menu. Use dynamic for scales datasets like products.

Min/Max Rows

Set the minimum and maximum allowed rows. Use min to require certain rows. Max avoids overly large datasets. Leave unlimited if flexible.

Initial Rows

Sets the number of rows to start with. Good for pre-populating usable dummy data.

Table Heading and Footer

Display headings or footers above/below the table data for visual organization.

Row Index Column

Auto-add a column showing row numbers. Enabled by default, disable to remove. Helps identify rows.

Row Layout

Choose between vertical columns or horizontal rows for data entry and display. Depends on how you want to structure your datasets.

There are also settings to control front-end display like CSS classes. Enable as needed for your particular implementation.

Think through how editors will interact with your field and configure the settings accordingly for the best UX. Standardize settings across similar table fields.

Organizing Table Structure

Some tips for effectively structuring your table data:

  • Use clear, consistent naming conventions for column handles and labels. Helps editors understand the data.

  • Group related columns together into sub-headings or sections. Break up large tables into logical chunks.

  • Use nested columns to create tree-like hierarchies or parent-child relationships between fields.

  • Reorder columns by clicking and dragging to place important columns first. Put commonly used columns on the left.

  • Set appropriate column widths so data is clearly visible within the available space.

  • Disable irrelevant columns but don't delete them to retain the data. Hide unneeded columns.

  • Rename, retype or reconfigure columns over time as needs change rather than starting fresh. Build iteratively.

Taking the time to thoughtfully organize your table fields will pay dividends in usability and maintainability down the road. Structure the data how editors will use it, not how it may work internally. Standardize patterns across table fields for consistency. Revisit and refine the structure as table requirements evolve.

Working with Table Data in Craft CMS

Displaying and Outputting Table Data

Once you've populated table fields with data, displaying it on the front-end requires outputting it in your Twig templates.

You can access the whole table dataset using the field handle, e.g. entry.tableName. Loop through the rows with a for tag:

{% for row in entry.tableName %}

{{ row.columnHandle }}

{% endfor %}

Access individual rows, columns and cell values using dot notation - row.columnName. You can output the data in customized HTML and CSS.

Conditionally check column values to only display certain rows or columns as needed:

{% if row.stockStatus == "In Stock" %}

<p>{{ row.productTitle }} is available!</p>

{% endif %}

You can also access table data directly in Twig for programmatic processing before display.

Overall, Twig provides full control over dynamically outputting table data on the front-end. Use variables, loops and conditionals to access the data and customize display.

Manipulating and Querying Table Data

In addition to basic output, you can further manipulate and query table data for more complex implementations:

  • sort - Sort rows in ASC or DESC order on a column

  • slice - Limit the number of rows

  • shuffle - Randomize row order

  • filter - Filter rows on a column value

  • search - Search rows for keyword matches

You can also query related elements and eager load table relations for better performance.

For example:

{% set products = entry.productsTable

| sort('stockStatus')

| slice(10)

| eagerload(elements = [{with: ['categories', 'variants']}]) %}

This eager loads related categories and variants for each row, sorts by stock status, and limits to 10 products.

For complex datasets, optimize front-end querying to avoid loading unneeded data. Craft Query syntax like id, status, relatedTo etc can be used to filter and manipulate table data before display.

Eager Loading and Caching Table Data

For best performance when working with large table datasets:

  • Eager load-related elements using the with parameter to avoid N+1 query issues.

  • Cache the table data to avoid heavy front-end querying each request.

  • Use lazy loading for lighter requests, only loading more rows as needed with JavaScript.

  • Limit and paginate results, only displaying a portion of rows at once.

Eager loading is faster than lazy loading entire datasets for each request. But caching is ideal for heavy front-end usage, storing pre-queried table data in cache tags or memcache.

Also, optimize indexes and database queries that populate the table behind the scenes.

Proper indexing, caching and selective querying can overcome performance challenges with complex table fields. Plan table data optimizations early to avoid front-end slowdowns.

Relating and Interconnecting Table Fields

Relating Tables to Entries and Other Elements

Table fields don't exist in isolation - often you need to relate them to other elements in your content structure.

The most common relationship is between table fields and Entries. For example, an "Events" Entry might have a table field for the event sessions.

To access a table from the related Entry in Twig:

{% set sessions = entry.sessionsTableFieldHandle %}

You can also link assets, categories, tags and other elements into table fields using relational field types like Assets, Categories or Entries. This allows reusing the same table across multiple elements.

For example, add an "Related Entry" column type to your table. Then select which Entry should be related from an Edit Entry screen.

Defining these relationships makes it easier to query and display related data for Entries and tables. You can eager load these relations to avoid N+1 queries.

Overall, relate table fields to Entries and other elements using relational columns or separate relational fields to connect multi-row datasets with broader content.

Linking Tables using Foreign Keys

More advanced relational data modeling involves linking tables together directly using foreign keys.

A foreign key is a column that references the primary key of another table. For example, an Order table may have a foreign key pointing to the primary key of a Products table.

This allows interacting with multiple tables through foreign key joins in database queries.

However, Craft doesn't natively support foreign key constraints or table relationships.

Solutions exist like the Freeform plugin which adds true relational linking between tables. Or define foreign keys through your database schema rather than Table fields.

Foreign keys enable much more complex relational data modeling between tables. But require custom handling versus native Table field relations in Craft.

Interconnecting Multiple Tables

For advanced content modelling, you can interconnect multiple table fields together:

  • Reference IDs between tables through foreign keys or relational columns

  • Link secondary tables to primary tables which connect to Entries

  • Create junction tables to join two tables without direct connections

  • Nest tables within cells of a parent table for hierarchical structures

  • Build a network of interconnected tables for complex relational data

Follow principles like:

  • Favour lookup tables over duplicating data across tables

  • Balance usability and performance when nesting related data

  • Limit chaining extensive table relations which can impact performance

While Craft Tables don't enforce strict database norms, thoughtful modelling helps manage complexity as inter-table relations grow.

Aim for clear, maintainable structures over academic relational purity. Use the best concepts from databases, without over-engineering.

Use Cases and Examples of Table Fields

Product Data Tables

Table fields provide an excellent way to manage complex product data in a structured format convenient for editors and flexible for developers. Rather than cramming product details like titles, descriptions, specs, options, variants, etc across multiple Channel Entries or custom fields, all related product information can be consolidated in a single table field.

For example, you may create columns in a table field for properties like SKU, price, weight, inventory count, product photos, and any other attributes needed to fully describe a product. The rows in the table would represent each individual product, with the columns populated with the respective spec values. On the front-end, looping through the table rows in Twig provides complete access to display the product information in customized templates, while the back-end table interface enables editors to conveniently enter and update all specs for each product in one place.


This standardized structure keeps product data portable and reusable across products, while optimizing the editing experience for product managers and providing structured data for developers. Tables remove the clutter of scattering product details across multiple models, streamlining product data maintenance and display.

Charts, Graphs and Tabular Data

Table fields lend themselves well to managing the datasets behind charts, graphs, and other data visualizations. For example, you may create columns in a reusable table field for properties like chart labels, data values, colours, etc. Then editors can populate the table with the exact datasets needed for each specific chart, with a row for each data point.

In Twig templates, looping through the rows provides easy access to build JSON or array structures to feed into javascript charting libraries. By housing each self-contained dataset in reusable table fields, you keep chart data portable and the frontend charting logic clean. The table structure standardizes how editors input and manage the datasets, avoiding scattered or inconsistent data.

Combined with Craft's flexible templating, table fields enable dynamic and customizable charting and data visualization capabilities, while optimizing the content editing experience for non-technical users. The table field handles the data structure, and Twig handles the presentation layer and client-side behavior.

Calendars and Event Listings

Table fields shine for content types like events calendars and schedules by allowing detail-rich event or listing data to be stored consistently. Rather than managing each event through separate Channel entries, details like date, time, title, description, location, speaker, image etc can be handled through columns in a table field.

The rows in the table would represent each unique calendar event or listing. On the frontend, the table structure provides an optimized data model for looping through and outputting events, making it easy to build calendars, schedules and other listings. Relationships between the events, sessions, speakers and other detailed data can also be modelled through nested table fields.

This approach keeps event data organized and portable for reusability across calendars and listings. Editors can focus on populating event details rather than wrestling with complex Calendar Channel structures. And the table data model eases displaying events and connected data on the front-end. For managing events, listings or schedules, table fields elevate a Channel-centric approach.

Optimizing Table Field Performance

Indexing Table Columns

As table fields scale to large datasets, indexing key columns becomes critical to optimize performance for filtering, searching, sorting and lookups. Without indexes, Craft must linearly scan every row in the table when querying by a column value, resulting in slow response times as the data grows. Indexes address this by creating auxiliary data structures that allow Craft to directly lookup rows matching a specific column value.

It is considered a best practice to index columns that will be commonly filtered or searched against, especially lengthy text fields. For example, a product name column would be a prime candidate for indexing to allow fast product lookups. Numeric columns used for sorting or joining data can benefit as well. Some ways to add indexes include using the "searchable" and "unique" column attributes when defining the schema, which automatically create indexes on those columns. Or you can directly add database indexes through raw SQL schemas for more granular control over index types, lengths, etc.

Care should be taken to only index essential columns to avoid overhead from over-indexing. General guidance is to be selective and resist the urge to make everything indexed by default. Indexes impose additional storage requirements and write overheads which can accumulate. Indexing very large text fields can also have diminishing returns. But used judiciously on key columns, indexing vastly improves the performance of queries, searches and lookups against large datasets stored in table fields.

Caching and Lazy Loading Strategies

Caching and selective, lazy loading are other important optimization strategies for table fields containing substantial amounts of data. Caching involves storing full table queries in cached elements to avoid re-running expensive queries each request. This can improve performance but requires properly invalidating caches when data changes. Lazy loading defers loading related data until specifically needed rather than upfront. For example, individual rows or nested relations can be loaded via AJAX as the user interacts rather than everything upfront.

Pagination is another useful technique where only a subset of rows are queried and rendered at once, with additional pages loaded on demand. Eager loading can prefetch defined relations in a single query while avoiding the N+1 problem of separate queries. Disabling search indexing on non-critical columns is another option to avoid expensive fulltext indexing. The core goal is to only query, join and process the minimal table data required for specific use cases, avoiding expensive unoptimized operations.

Limiting Rows and Nested Queries

When dealing with nested table relations, performance best practices include: limiting the number of rows in child tables to avoid unbounded growth, flattening nested data into separate tables when possible, eager loading defined nested data in a single query, and paginating large result sets. Deeply chained nested queries should be avoided in favor of selective, flattened data models where feasible. Disabling search indexing on non-critical nested columns can also help.

However, normalized data can sometimes result in more queries, so denormalization with nested, eagerly-loaded data may optimize performance by reducing overall query numbers. As with any optimization, tradeoffs exist between priorities like normalized vs denormalized data and different access patterns. Highly complex, interrelated data may ultimately require the relational structure of a custom database over Craft's more convenient table fields. But for reasonably sized datasets, the aforementioned optimizations can provide excellent performance for most table field use cases.

Shape April 2022 HR 202
Andy Golpys
- Author

Andy has scaled multiple businesses and is a big believer in Craft CMS as a tool that benefits both Designer, Developer and Client. 

Share
Feedback
Show us some love
Email Us
We usually reply within 72 hours
Agency Directory
Submit your agency
Affiliate Partners
Let's chat