I'm looking to create a .txt file with table field data taken from an entry on the fly. All entries would have their own designated files. It's for video chapters with JW Player. They ask for a .vtt file but with testing a .txt seems to work.

I've had a good search but can't seem to find much. I guess the worst case scenario is uploading them via FTP, but preferably not! Thanks.

2 Answers 2


An alternative to using a plugin to write an actual text file to the local filesystem is to create a dynamic route that looks like your entry URL format, except with .txt at the end (e.g. news/{slug}.txt), and point that route to a template called text.html or the like.

Inside the text.html template, you'll need to pull the entry using the slug token:

{%- spaceless -%}

    {# Get the entry #}
    {% set entry = craft.entries.section('news').slug(slug).first() %}

    {% if not entry %}
        {% exit 404 %}
    {% endif %}

    {# Set some headers #}
    {% header "Content-Type: text/plain; charset=utf-8" %}
    {% header "Access-Control-Allow-Origin: *" %}

    {# Print the table #}
    {% for row in entry.tableField %}
    {% endfor %}

{%- endspaceless -%}

The idea is that with the above, you'll be able to just append .txt to your existing entry URLs to serve a text version of each entry – I have no idea if JW Player can be configured to use such a setup, but there it is.

Caveat: This solution will have a slightly larger overhead than simply serving an actual text file, since you'll be invoking Craft and hitting the database for each request.


You can write a plugin that listens to the onSaveEntry event.

When that event fires, you can grab any of the data you need for the text file from any of the custom fields and your plugin can write it out to the filesystem at whatever place it needs for JW Player to consume.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.