12 Step Meeting List plugin (WordPress)

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen

There seems to exist only one current publicly available plugin for listing 12 Step meetings on WordPress websites: 12 Step Meeting List (TSML) plugin. The documentation on the plugin's Wordpress.org, seems promising.

There are surely lots of non-public plugins or other solutions for listing 12 Step meetings on WordPress websites. One of these is MeoModo Meeting Finder. This plugin was custom developed for Alcoholics Anonymous in The Netherlands. As far as I am concerned, it is not supported anymore.


wp-admin » Plugins after installing the 12 Step Meeting List plugin
After installation, a new admin menu item Meetings becomes available
wp plugin install 12-step-meeting-list --activate

E.g., 2023.05.13:

$ wp plugin install 12-step-meeting-list --activate

Installing 12 Step Meeting List (3.14.14)
Downloading installation package from https://downloads.wordpress.org/plugin/12-step-meeting-list.3.14.14.zip...
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Activating '12-step-meeting-list'...
Plugin '12-step-meeting-list' activated.
Success: Installed 1 of 1 plugins.

Where are meetings displayed?

Follow the link below to the meetings page

Wp-admin » Meetings » Import & Export » Where's My Info? » "right here"


  • By default, it seems to be at /meetings
  • I have the impression that you cannot directly edit this page
  • I also don't know how to change the slug
  • MeoModo's Meeting Finder seems to use the same slug, so you can't see them at the same time, it seems.


Change this by setting variable $tsml_slug in file functions.php [1]. E.g.:

$tsml_slug = 'non-meeting-meeting-page';

Data model

There are several tables:

  1. Groups
  2. Meetings ← This is the main object
  3. Locations.

                                     | Types =        |
                                     | $tsml_programs |
                                 +-∞-| Type code (PK) |
+----------------------------+   |   | Description    |
| Meetings: posts where      |   |   +----------------+
| post_type = "tsml_meeting" |   |
+----------------------------+   |    
| post_id (PK)               | ∞-+   +--------------------------+
| Group (post_meta?)         | ∞---1 | Groups: posts where      |
+----------------------------+       | post_type = "tsml_group" |
                                     | post_id (PK)             |
                                     | ...                      |

Meetings - Fields

Meetings objects have the following fields:


Meeting start time

End Time

Meeting end time


One element from {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sonday}


A slug should be unique.


  • Name of the location
  • Optional.


  • Strongly encouraged
  • Corrected through Google, so it might look differently afterwards

City, State, Country

  • Optional
  • Not needed, if Address is complete.


  • Freeform notes.

Conference URL

  • For online meetings: The direct link to the meeting (not to an intermediary page)
  • E.g., Zoom or Skype


  • The name of the group
  • {Meetings} and {Groups} are related through this field


Meetings can be associated with types, which are like tags. Types should be provided as a comma-separated list. E.g.:

Closed, Women


Babysitting Available, Birthday, Open, Wheelchair Access

You probably can only use Types that are already defined. When you include unknown Types, I suspect they will be ignored. I'm quite sure they will not be added to the system.

For the current list of types:

wp-admin » Meetings » Add new » Types » View all

Working with Types

  • types are like tags: A meeting can be associated with 0, 1 or more of these Types
  • The default list is hardcoded as an array in file wp-content/plugins/12-step-meetinglist/includes/variables.php
  • For each fellowship, there is a separate list. That's why you would find the same type multiple times, when doing a search like through grep -rn . -e "Transgender".

Default list - 2023.05

  • 11th Step Meditation
  • 12 Steps & 12 Traditions
  • As Bill Sees It
  • Babysitting Available
  • Big Book
  • Birthday
  • Breakfast
  • Candlelight
  • Child-Friendly
  • Closed
  • Concurrent with Al-Anon
  • Concurrent with Alateen
  • Cross Talk Permitted
  • Daily Reflections
  • Digital Basket
  • Discussion
  • Dual Diagnosis
  • English
  • Fragrance Free
  • French
  • Gay
  • Grapevine
  • Hebrew
  • Indigenous
  • Italian
  • Japanese
  • Korean
  • Lesbian
  • Literature
  • Living Sober
  • Location Temporarily Closed
  • Meditation
  • Men
  • Native American
  • Newcomer
  • Non-Binary
  • Online Meeting
  • Open
  • Outdoor Meeting
  • People of Color
  • Polish
  • Portuguese
  • Professionals
  • Punjabi
  • Russian
  • Secular
  • Seniors
  • Sign Language
  • Smoking Permitted
  • Spanish
  • Speaker
  • Step Meeting
  • Tradition Study
  • Transgender
  • Wheelchair Access
  • Wheelchair-Accessible Bathroom
  • Women
  • Young People

Hardcoded array - AA

This is the part of the array with types for AA meetings:

'aa' => [
	'abbr' => __('AA', '12-step-meeting-list'),
	'flags' => ['M', 'W', 'TC', 'ONL'], //for /men and /women at end of meeting name (used in tsml_format_name())
	'name' => __('Alcoholics Anonymous', '12-step-meeting-list'),
	'type_descriptions' => [
		'C' => __('Closed meetings are for A.A. members only, or for those who have a drinking problem and “have a desire to stop drinking.”', '12-step-meeting-list'),
		'O' => __('Open meetings are available to anyone interested in Alcoholics Anonymous’ program of recovery from alcoholism. Nonalcoholics may attend open meetings as observers.', '12-step-meeting-list'),
	'types' => [
		'11' => __('11th Step Meditation', '12-step-meeting-list'),
		'12x12' => __('12 Steps & 12 Traditions', '12-step-meeting-list'),
		'ABSI' => __('As Bill Sees It', '12-step-meeting-list'),
		'BA' => __('Babysitting Available', '12-step-meeting-list'),
		'B' => __('Big Book', '12-step-meeting-list'),
		'H' => __('Birthday', '12-step-meeting-list'),
		'BRK' => __('Breakfast', '12-step-meeting-list'),
		'CAN' => __('Candlelight', '12-step-meeting-list'),
		'CF' => __('Child-Friendly', '12-step-meeting-list'),
		'C' => __('Closed', '12-step-meeting-list'),
		'AL-AN' => __('Concurrent with Al-Anon', '12-step-meeting-list'),
		'AL' => __('Concurrent with Alateen', '12-step-meeting-list'),
		'XT' => __('Cross Talk Permitted', '12-step-meeting-list'),
		'DR' => __('Daily Reflections', '12-step-meeting-list'),
		'DB' => __('Digital Basket', '12-step-meeting-list'),
		'D' => __('Discussion', '12-step-meeting-list'),
		'DD' => __('Dual Diagnosis', '12-step-meeting-list'),
		'EN' => __('English', '12-step-meeting-list'),
		'FF' => __('Fragrance Free', '12-step-meeting-list'),
		'FR' => __('French', '12-step-meeting-list'),
		'G' => __('Gay', '12-step-meeting-list'),
		'GR' => __('Grapevine', '12-step-meeting-list'),
		'HE' => __('Hebrew', '12-step-meeting-list'),
		'NDG' => __('Indigenous', '12-step-meeting-list'),
		'ITA' => __('Italian', '12-step-meeting-list'),
		'JA' => __('Japanese', '12-step-meeting-list'),
		'KOR' => __('Korean', '12-step-meeting-list'),
		'L' => __('Lesbian', '12-step-meeting-list'),
		'LIT' => __('Literature', '12-step-meeting-list'),
		'LS' => __('Living Sober', '12-step-meeting-list'),
		'LGBTQ' => __('LGBTQ', '12-step-meeting-list'),
		'TC' => __('Location Temporarily Closed', '12-step-meeting-list'),
		'MED' => __('Meditation', '12-step-meeting-list'),
		'M' => __('Men', '12-step-meeting-list'),
		'N' => __('Native American', '12-step-meeting-list'),
		'BE' => __('Newcomer', '12-step-meeting-list'),
		'NB' => __('Non-Binary', '12-step-meeting-list'),
		'ONL' => __('Online Meeting', '12-step-meeting-list'),
		'O' => __('Open', '12-step-meeting-list'),
		'OUT' => __('Outdoor Meeting', '12-step-meeting-list'),
		'POC' => __('People of Color', '12-step-meeting-list'),
		'POL' => __('Polish', '12-step-meeting-list'),
		'POR' => __('Portuguese', '12-step-meeting-list'),
		'P' => __('Professionals', '12-step-meeting-list'),
		'PUN' => __('Punjabi', '12-step-meeting-list'),
		'RUS' => __('Russian', '12-step-meeting-list'),
		'A' => __('Secular', '12-step-meeting-list'),
		'SEN' => __('Seniors', '12-step-meeting-list'),
		'ASL' => __('Sign Language', '12-step-meeting-list'),
		'SM' => __('Smoking Permitted', '12-step-meeting-list'),
		'S' => __('Spanish', '12-step-meeting-list'),
		'SP' => __('Speaker', '12-step-meeting-list'),
		'ST' => __('Step Meeting', '12-step-meeting-list'),
		'TR' => __('Tradition Study', '12-step-meeting-list'),
		'T' => __('Transgender', '12-step-meeting-list'),
		'X' => __('Wheelchair Access', '12-step-meeting-list'),
		'XB' => __('Wheelchair-Accessible Bathroom', '12-step-meeting-list'),
		'W' => __('Women', '12-step-meeting-list'),
		'Y' => __('Young People', '12-step-meeting-list'),

Change in functions.php

  • You can change these tags, but be careful: If you're getting too creative, or change an existing type, you might loose compatibility with the meeting app, and your types won't show up
  • Don't change the existing variable mentioned above, because you will loose changes upon updating. Rather, overwrite it in theme file functions.php

There are different ways to edit your function.php file:

  1. Files (on your webserver) » wp-content » themes » active theme or child theme » functions.php
  2. wp-admin » Appearance » Theme File Editor: Handy to verify if you have multiple themes and subthemes on your site, and you aren't sure which one to edit.

When you edit the list through functions.php, the change is immediate.

According to https://wordpress.org/plugins/12-step-meeting-list/#faq-header, ther are are least two functions for updating Types: tsml_custom_descriptions() and tsml_custom_types(). However: Only the latter seems to work for me, and only to delete descriptions (but keep the actual Type ID)


As mentioned, this only seems to delete the description, not the actual Type:

if (function_exists('tsml_custom_types')) {
        'BA' => '',
        'BRK' => '',
        'CAN' => '',


To add a type:

if (function_exists('tsml_custom_types')) {
        'XYZ' => 'My Custom Type',

Update description

I have no idea why you would want to update a description - but you can:

if (function_exists('tsml_custom_types')) {
        'KOR' => 'Juhu! Our first Korean meeting!',

See also