FORGEBOX Enterprise 🚀 - Take your ColdFusion (CFML) Development to Modern Times! Learn More...

PresideCMS Extension: Twitter API

v0.7.3 Public

Twitter API Integration for Preside

This extension allows you to configure multiple Twitter accounts in your Preside application, and to interact with the Twitter API.


  • Custom rendering of timelines and individual tweets: tweets can be placed and formatted however desired
  • Speed of rendering: tweets are rendered as part of the page (and can be cached if desired), with no external requests to Twitter
  • Indexing: tweets can be indexed and searched both locally and by search engines
  • No tracking: because no 3rd-party widgets are being rendered by your page, no 3rd-party tracking is happening either


Because of the nature of Twitter statuses, which will very often include emojis, you MUST have your MySQL database set up to use the utf8mb4 character set.

(This is probably best practice these days anyway, especially if your application is going to be storing any user-supplied data.)

You should also be running Preside v10.11.0 or greater.

Getting started

  1. Add one (or more) Twitter accounts through Data Manager > Twitter > Twitter accounts. You will need to set up API access at Twitter in order to obtain the required access credentials.
  2. You may configure a "start date" for each account - this will be the date from which your tweet history will be imported.
  3. In Task Manager > Twitter, run the Get new tweets task (or wait for it to run on schedule).

The twitter_status Preside object will now hold a local history of all your tweets, and new tweets will continually be added to this.

NOTE: the twitter_status object uses Twitter's own status ID as its ID property

Scheduled tasks

In addition to the Get new tweets task, there are other tasks in the Task Manager:

  • Re-render tweets: this will re-render the body and media content of each local tweet using the default context (see below for more information) and store the result in the twitter_status object
  • Update counts/deletions: these run at different frequencies to update like/retweet counts, and remove from the local system any tweets that have since been deleted. Out of the box, every 10 minutes it will check tweets that were posted in the past day; every 2 hours it will check tweets from the past 30 days; and once a day it will check all locally-stored tweets.

Rendering tweets

A number of default renderers are provided which take the raw data from the API and render it into a formatted tweet that can be included on a web page. This includes linking users, hashtags and URLs, and embedding media items.

The entity renderers provided are:

  • tweet_hashtags
  • tweet_symbols
  • tweet_urls
  • tweet_user_mentions
  • tweet_media_photo
  • tweet_media_video
  • tweet_media_animated_gif

The tweet markup renderers are:

  • tweet_header
  • tweet_in_reply_to
  • tweet_body
  • tweet_media
  • tweet_footer

Finally, there is a tweet renderer which combines the text and media into one formatted HTML block.

Each of these renderers has a default context, which provides a good basis to render tweets for general display. You can override these in your application and style the result as you desire.

By adding alternate contexts for some or all of these renderers, you can create different layouts for your tweets for different display purposes. For example, you might create a featured context which renders some (or all) aspects of the tweet differently.


There is a simple Twitter feed widget provided. This accepts a few settings (account(s), number of tweets to show, optional title) and renders a Twitter feed to your page.

The resulting HTML output looks like this:

<div class="twitter-feed-widget">
	<h2>Widget title (if supplied)</h2>

	<div class="twitter-feed-widget-tweets">
		A collection of rendered tweets

Helper methods

A number of helper methods are supplied, which proxy to the TwitterRenderingService.


The renderTweet() helper retrieves an individual tweet from the database and renders it in the specified context (or default context if not supplied):

// Supply a tweet ID
rendered = renderTweet( id=tweetId, context="featured" );


The renderTweets() helper will render a collection of tweets based on the arguments provided. The method accepts all valid selectData() arguments, which it uses to retrieve relevant tweet records, as well as an optional context:

tweets = renderTweets(
	, filter  = {
		  "account.screen_name" = "sebduggan"
		, is_retweet            = false
		, is_reply              = false
	, maxRows = 20
	, orderBy = "date_posted desc"
	, context = "default"


The renderTweetDate() helper will take a date and format it for display in a tweet header, according to a few simple rules:

  • Datetimes in the past hour will be displayed as a number of minutes (e.g. 32m)
  • Datetimes in the past 24 hours will be displayed as a number of hours (e.g. 14h)
  • Datetimes in the current year will be displayed as date and month (e.g. 12 Jan)
  • Datetimes older than that will be also have a year appended (e.g. 24 Nov, 2019)

The date format automatically renders according to the locale of Lucee (or the current request). The minute suffix (m) and hour suffix (h) can be localised in i18n/

Default styling and behaviours


The default renderers will produce a tweet formatted something like this. Note some elements may be absent where not applicable:

<article class="tweet">

	<div class="tweet-header">
		<div class="tweet-header-retweeter">
			Details of whether this is a retweet

		<div class="tweet-header-meta">
			The name/account of the poster, and the date posted

	<div class="tweet-body">
		<div class="tweet-in-reply-to">
			Linked list of users to whom this tweet is replying

		The processed body of the tweet

	<div class="tweet-media">
		Attached media - either 1-4 photos, or a video/animated gif

	<article class="tweet tweet-quoted">
		The tweet being quoted. This will have the same structure as the parent tweet element (but without the footer)

	<div class="tweet-footer">
		Action buttons and counts



Default styling is provided for the default tweet renderers. This is provided both as Sass and compiled CSS files.

The default styling has been kept as simple as possible to make it easy to customise it for your own site. Tweets will fill the width and inherit the base font size of their containing element, and may need very little extra custom styling.

You can include the compiled CSS using Sticker:

event.include( "/css/twitter/" );

Alternatively, you could incorporate and modify these styles in your own site's stylesheets. If using Sass on your website, you could import the Sass source files directly into your own master stylesheet:

@import "../../../application/extensions/preside-ext-twitter-api/assets/css/twitter/twitter";

And, if using Dart Sass (recommended!), you can use @use to import the styles and override the default variables that are set in /assets/css/twitter/twitter.scss. For example, the following would override the aspect ratio of the media items grid so it is displayed as a square:

@use "../../../application/extensions/preside-ext-twitter-api/assets/css/twitter/twitter" (
	$mediaRatio: 100%

NOTE: These import paths are relative to the location of the Sass file in your own site which is doing the importing.


Javascript is provided to handle some default interactions. This includes a simple lightbox (with no library dependencies) for viewing media items, and opening of Twitter intents (like, retweet, reply) in a popup window.

These can be included using Sticker (although it is automatically included by the default Tweet renderer):

event.include( "/js/twitter/" );

SVG icons

There are a number of SVG icons used by the default renderers which are provided in a single SVG sprite collection. This should be included on any page on which you are rendering tweets (it's not very big, so there's no reason not to simply drop it into the bottom of your site's main layout):

renderViewlet( "twitter.includeSvgs" )

Dependencies (0)

Dev Dependencies (1)



  • Add default ids to twitter-feed form


  • Ensure correct encoding of API params in http call
  • Log API connection errors


  • Better handling of line breaks in rendered tweets


  • Add postStatus() method to allow posting of Tweets
  • Rework percentEncode() to work with high-codepoint unicode characters


  • Fix typo in documentation
  • Include JS in default tweet renderer


  • Add documentation for the Twitter feed widget


  • Add simple twitter feed widget


  • Hide included SVG sprites


  • Attempt to fix sync error


  • Fix regression in TwitterRequest
  • Remove debug code
  • Add nested rendering of quoted tweets


  • Add documentation to the public service methods
  • Add tweet background as Sass variable
  • Add icon & link to "replying to" element
  • Add avatar to tweet user element


  • Remove debug code...


  • Minor tweet layout changes
  • Remove check for site's http/s status: Twitter redirects all requests to https anyway...
  • Add rendering for separate "Replying to..." component


  • Unique IDs for each rendered tweet's media
  • Add error handling to API calls and tasks


  • Better rendering of retweets
  • Display datetimes in the past hour as minutes


  • Change summary to shortDescription in box.json


  • Fix query filter in rerender tweets task
  • Better logging in rerender task


  • Sort tweet data grid by date_posted
  • Add indexes to twitter_status object


  • Store IDs as strings, sort tweets by date_posted


  • Update documentation
  • Set summary for Forgebox


  • Move display text to i18n properties
  • Localise formatted date display
  • Accessibility improvements (ARIA)


  • Refactor CSS source structure
  • Refactor public rendering methods


  • Add web intents for user links
  • Add SVG icons for tweet actions
  • Refactor tweet renderers for better customisation


  • Add styles for the default rendered tweets
  • Add metadata and Twitter actions to default renderers
  • Add lightbox for viewing media items
  • Add JS interaction for Twitter intent actions


  • Rework entity replacement to prevent potential double-replacements


  • Replace newlines with HTML line breaks in default tweet renderer


  • Release of initial functionality
    • Configure multiple Twitter accounts with credentials
    • Scheduled tasks to import existing tweets, and run regularly to pick up new ones
    • Scheduled tasks to update like/retweet counts, and to remove deleted tweets
    • Default renderers to convert the API data into a fully-rendered tweet (currently no default styling or interaction handling)
    • Manual task to re-render all saved tweets (e.g. if the renderers have changed)


$ box install preside-ext-twitter-api

No collaborators yet.
  • {{ getFullDate("Nov 02 2020 09:11 AM GMT") }}
  • {{ getFullDate("Nov 02 2020 09:11 AM GMT") }}
  • 752
  • 1,991
  • 645