diff --git a/crouton.php b/crouton.php index 7459e8e..f79dc84 100644 --- a/crouton.php +++ b/crouton.php @@ -5,7 +5,7 @@ Description: A tabbed based display for showing meeting information. Author: bmlt-enabled Author URI: https://bmlt.app -Version: 3.15.3 +Version: 3.16.0 */ /* Disallow direct access to the plugin file */ if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { @@ -21,6 +21,7 @@ class Crouton public $options = array(); public $croutonBlockInitialized = false; public static $HOUR_IN_SECONDS = 3600; + public $has_handlebars = false; public $themes = [ "asheboro", "florida-nights", @@ -83,6 +84,9 @@ class Crouton "show_map" => '0', "max_zoom_level" => 15, "language" => 'en-US', + 'strict_datafields' => false, + 'meeting_details_href' => '', + 'virtual_meeting_details_href' => '', "auto_tz_adjust" => '0', "base_tz" => null, "sort_keys" => 'start_time', @@ -146,6 +150,10 @@ public function __construct() &$this, "serviceBodyNames" )); + add_shortcode('bmlt_handlebar', array( + &$this, + "bmltHandlebar" + )); } // Content filter add_filter('the_content', array( @@ -335,7 +343,14 @@ public function tabbedUi($atts, $content = null) { return sprintf('%s
%s
', $this->sharedRender(), $this->renderTable($atts)); } - + public function bmltHandlebar($atts, $template = null) + { + if (!$this->has_handlebars) { + add_action("wp_footer", [$this,'handlebarFooter']); + } + $this->has_handlebars = true; + return sprintf('
%s
Fetching...
', htmlspecialchars($template)); + } public function croutonMap($atts, $content = null) { return sprintf('%s
%s
', $this->sharedRender(), $this->renderMap($atts)); @@ -409,7 +424,26 @@ public function serviceBodyNames($atts) $random_id = rand(10000, 99999); return $this->getInitializeCroutonBlock($this->getCroutonJsConfig($atts)) . ""; } - + public function handlebarFooter() + { + if (!isset($_GET['meeting-id'])) { + return; + } + $meetingId = $_GET['meeting-id']; + $attr = ['custom_query' => '&meeting_ids[]='.$meetingId, + 'strict_datafields' => false]; + $config = $this->getCroutonJsConfig($attr); + ?> + + options['root_server'] = $_POST['root_server']; $this->options['service_body_1'] = $_POST['service_body_1']; + $this->options['time_format'] = $_POST['time_format']; + $this->options['language'] = $_POST['language']; + $this->options['strict_datafields'] = isset($_POST['strict_datafields']); + $this->options["int_start_day_id"] = intval($_POST["int_start_day_id"]); + $this->options['native_lang'] = trim($_POST['native_lang']); + $this->options['meeting_details_href'] = trim($_POST['meeting_details_href']); + $this->options['virtual_meeting_details_href'] = trim($_POST['virtual_meeting_details_href']); $this->options['custom_query'] = $_POST['custom_query']; $this->options['custom_css'] = isset($_POST['custom_css']) ? str_replace('\\', '', $_POST['custom_css']) : ""; $this->options['meeting_data_template'] = isset($_POST['meeting_data_template']) ? str_replace('\\', '', $_POST['meeting_data_template']) : ""; @@ -481,7 +522,24 @@ public function adminOptionsPage() $this->saveAdminOptions(); echo ""; } - + if (!isset($this->options['time_format']) || strlen(trim($this->options['time_format'])) == 0) { + $this->options['time_format'] = 'h:mm a'; + } + if (!isset($this->options['language']) || strlen(trim($this->options['language'])) == 0) { + $this->options['language'] = 'en-US'; + } + if (!isset($this->options['native_lang'])) { + $this->options['native_lang'] = ''; + } + if (!isset($this->options['meeting_details_href'])) { + $this->options['meeting_details_href'] = ''; + } + if (!isset($this->options['virtual_meeting_details_href'])) { + $this->options['virtual_meeting_details_href'] = ''; + } + if (!isset($this->options['strict_datafields'])) { + $this->options['strict_datafields'] = true; + } if (!isset($this->options['extra_meetings_enabled']) || $this->options['extra_meetings_enabled'] == "0" || strlen(trim($this->options['extra_meetings_enabled'])) == 0) { $this->options['extra_meetings_enabled'] = 0; } @@ -571,6 +629,62 @@ public function adminOptionsPage() +
+

Default Values

+

These values will be used when the attributes are not defined in the shortcode

+ +
+
+

Meeting Detail Pages

+

Link to pages where the [bmlt_handlebar] tag is used to insert information about a particular meeting, in more detail and in an + easier to read format than is possible in the crouton table. Use the partial {{> meetingLink this}} to insert into a template. +

+ +

Include Extra Meetings

@@ -768,7 +882,12 @@ public function getAllMeetings($root_server) public function getCroutonJsConfig($atts) { - $params = shortcode_atts($this->shortCodeOptions, $atts); + // Pulling simple values from options + $defaults = $this->shortCodeOptions; + foreach ($defaults as $key => $value) { + $defaults[$key] = (isset($this->options[$key]) ? $this->options[$key] : $value); + } + $params = shortcode_atts($defaults, $atts); // Pulling from querystring foreach ($params as $key => $value) { @@ -839,7 +958,6 @@ public function getCroutonJsConfig($atts) $params['service_body'] = $service_body; $params['exclude_zip_codes'] = (!is_null($params['exclude_zip_codes']) ? explode(",", $params['exclude_zip_codes']) : array()); - $params['root_server'] = $params['root_server'] != '' ? $params['root_server'] : $this->options['root_server']; if ($legacy_force_recurse) { $params['recurse_service_bodies'] = true; @@ -879,6 +997,9 @@ public function getCroutonJsConfig($atts) } $params['extra_meetings'] = $extra_meetings_array; + + $params['force_rootserver_in_querystring'] = ($params['root_server'] !== $this->options['root_server']); + // TODO add default language and root_server return json_encode($params); } } @@ -889,4 +1010,4 @@ public function getCroutonJsConfig($atts) if (class_exists("Crouton")) { $BMLTTabs_instance = new Crouton(); } -?> +?> \ No newline at end of file diff --git a/croutonjs/src/js/crouton-core.js b/croutonjs/src/js/crouton-core.js index 1f922c1..0383c67 100644 --- a/croutonjs/src/js/crouton-core.js +++ b/croutonjs/src/js/crouton-core.js @@ -55,6 +55,9 @@ function Crouton(config) { service_body: [], // Array of service bodies to return data for. formats: '', // Return only meetings with these formats (format shared-id, not key-string) venue_types: '', // Return only meetings with this venue type (1, 2 or 3) + strict_datafields: true, // Only get the datafields that are mentioned in the templates + meeting_details_href: '', // Link to the meeting details page + virtual_meeting_details_href: '', // Link to the virtual meeting details page exclude_zip_codes: [], // List of zip codes to exclude extra_meetings: [], // List of id_bigint of meetings to include native_lang: '', // The implied language of meetings with no explicit language specied. May be there as second language, but it still doesn't make sense to search for it. @@ -66,11 +69,15 @@ function Crouton(config) { int_start_day_id: 1, // Controls the first day of the week sequence. Sunday is 1. view_by: "weekday", // TODO: replace with using the first choice in button_filters as the default view_by. show_qrcode: false, // Determines whether or not to show the QR code for virtual / phone meetings if they exist. + force_rootserver_in_querystring: true, // Set to false to shorten generated meeting detail query strings + force_timeformat_in_querystring: true, // Set to false to shorten generated meeting detail query strings + force_language_in_querystring: true, // Set to false to shorten generated meeting detail query strings theme: "jack", // Allows for setting pre-packaged themes. Choices are listed here: https://github.com/bmlt-enabled/crouton/blob/master/croutonjs/dist/templates/themes meeting_data_template: croutonDefaultTemplates.meeting_data_template, metadata_template: croutonDefaultTemplates.metadata_template, observer_template: croutonDefaultTemplates.observer_template, - meeting_count_template: croutonDefaultTemplates.meeting_count_template + meeting_count_template: croutonDefaultTemplates.meeting_count_template, + meeting_link_template: croutonDefaultTemplates.meeting_link_template, }; self.setConfig(config); @@ -205,9 +212,12 @@ function Crouton(config) { self.mutex = false; }); }; - self.mutex = true; - - self.meetingSearch = function() { + self.addDatafieldsToQuery = function() { + if (!self.config.strict_datafields) { + self.all_data_keys = []; + self.queryable_data_keys = []; + return ''; + } var base_data_field_keys = [ 'location_postal_code_1', 'duration_time', @@ -278,8 +288,13 @@ function Crouton(config) { self.collectDataKeys(self.config['observer_template']); var unique_data_field_keys = arrayUnique(self.queryable_data_keys); + return '&data_field_key=' + unique_data_field_keys.join(','); + } + self.mutex = true; + + self.meetingSearch = function() { var url = '/client_interface/jsonp/?switcher=GetSearchResults&get_used_formats&lang_enum=' + self.config['short_language'] + - '&data_field_key=' + unique_data_field_keys.join(','); + self.addDatafieldsToQuery(); if (self.config['formats']) { url += self.config['formats'].reduce(function(prev,id) { @@ -546,7 +561,11 @@ function Crouton(config) { } } }; - + self.toFarsinNumber = function( n ) { + const farsiDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; + + return n.replace(/\d/g, x => farsiDigits[x]); + } self.enrichMeetings = function (meetingData, filter) { var meetings = []; @@ -554,6 +573,7 @@ function Crouton(config) { crouton_Handlebars.registerPartial("metaDataTemplate", self.config['metadata_template']); crouton_Handlebars.registerPartial("observerTemplate", self.config['observer_template']); crouton_Handlebars.registerPartial("meetingCountTemplate", self.config['meeting_count_template']); + crouton_Handlebars.registerPartial("meetingLink", self.config['meeting_link_template']); for (var m = 0; m < meetingData.length; m++) { meetingData[m]['formatted_comments'] = meetingData[m]['comments']; @@ -570,6 +590,10 @@ function Crouton(config) { .add(duration[0], 'hours') .add(duration[1], 'minutes') .format(self.config['time_format']); + if (self.config.language === 'fa-IR') { + meetingData[m]['start_time_formatted'] = self.toFarsinNumber(meetingData[m]['start_time_formatted']); + meetingData[m]['end_time_formatted'] = self.toFarsinNumber(meetingData[m]['end_time_formatted']); + } // back to bmlt day meetingData[m]['day_of_the_week'] = meetingData[m]['start_time_raw'].isoWeekday() === 7 ? 1 : meetingData[m]['start_time_raw'].isoWeekday() + 1; @@ -625,6 +649,7 @@ function Crouton(config) { meetingData[m]['serviceBodyPhone'] = serviceBodyInfo["helpline"]; meetingData[m]['serviceBodyName'] = serviceBodyInfo["name"]; meetingData[m]['serviceBodyDescription'] = serviceBodyInfo["description"]; + meetingData[m]['serviceBodyContactEmail'] = serviceBodyInfo["contact_email"]; meetingData[m]['serviceBodyType'] = self.localization.getServiceBodyType(serviceBodyInfo["type"]); var parentBodyInfo = self.getServiceBodyDetails(serviceBodyInfo["parent_id"]); @@ -636,6 +661,19 @@ function Crouton(config) { meetingData[m]['parentServiceBodyType'] = self.localization.getServiceBodyType(parentBodyInfo["type"]); } + meetingData[m]['meeting_details_url'] = ''; + if (self.config.meeting_details_href) { + meetingData[m]['meeting_details_url'] = self.config.meeting_details_href; + if (meetingData[m]['venue_type'] === 2 && self.config.virtual_meeting_details_href ) { + meetingData[m]['meeting_details_url'] = self.config.virtual_meeting_details_href; + } + meetingData[m]['meeting_details_url'] += ('?meeting-id=' + meetingData[m]['id_bigint'] + + '&language=' + self.config.language + + '&time_format=' + encodeURIComponent(self.config.time_format) + + (self.config.force_rootserver_in_querystring ? '&root_server=' + encodeURIComponent(self.config.root_server) : '') + ); + } + meetings.push(meetingData[m]) } @@ -769,6 +807,81 @@ Crouton.prototype.getServiceBodyDetails = function(serviceBodyId) { } } +Crouton.prototype.doHandlebars = function() { + var elements = document.getElementsByTagName('bmlt-handlebar'); + if (elements.length === 0) { + self.showMessage('No tags found'); + return; + }; + var self = this; + self.lock(function() { + if (self.isEmpty(self.meetingData)) { + self.showMessage("No meetings found for parameters specified."); + return; + } + var promises = [self.getServiceBodies(self.meetingData[0]['service_body_bigint'])]; + Promise.all(promises) + .then(function(data) { + hbs_Crouton['localization'] = self.localization; + self.active_service_bodies = []; + self.all_service_bodies = []; + var service_body = data[0][0]; + self.all_service_bodies.push(service_body); + var enrichedMeetingData = self.enrichMeetings(self.meetingData); + var customStartupTemplate = crouton_Handlebars.compile('{{startup}}'); + customStartupTemplate(enrichedMeetingData); + var customEnrichTemplate = crouton_Handlebars.compile('{{enrich this}}'); + customEnrichTemplate(enrichedMeetingData[0]); + var parser = new DOMParser(); + + while (elements.length > 0) { + var element = elements.item(0); + if (!element.firstChild) { + console.log(' tag must have at least one child'); + element.remove(); + continue; + } + var templateString = ''; + if (element.firstChild.nodeType === 1) { + if (!element.firstChild.firstChild || element.firstChild.firstChild.nodeType !== 3) { + console.log(' tag: cannot find textnode'); + element.remove(); + continue; + } + templateString = element.firstChild.firstChild.textContent; + } else if (element.firstChild.nodeType === 3) { + if (!element.firstChild.nodeType !== 3) { + console.log(' tag: cannot find textnode'); + element.remove(); + continue; + } + templateString = element.firstChild.textContent; + } + + var template = crouton_Handlebars.compile(templateString); + var handlebarResult = template(enrichedMeetingData[0]); + var htmlDecode = parser.parseFromString(''+handlebarResult+'', "text/html"); + if (!htmlDecode.body || !htmlDecode.body.firstChild) { + console.log(' tag: could not parse the Handlebars result'); + element.remove(); + continue; + } + var firstPart = htmlDecode.body.firstChild; + var brothers = []; + var thisPart = firstPart; + var nextPart = null; + while (nextPart = thisPart.nextSibling) { + thisPart = nextPart; + brothers.push(thisPart); + } + element.replaceWith(firstPart); + if (brothers) firstPart.after(...brothers); + } + }); + }); + +}; + Crouton.prototype.render = function() { var self = this; self.lock(function() { diff --git a/croutonjs/src/js/crouton-default-templates.js b/croutonjs/src/js/crouton-default-templates.js index 61284ce..a4aa21d 100644 --- a/croutonjs/src/js/crouton-default-templates.js +++ b/croutonjs/src/js/crouton-default-templates.js @@ -4,7 +4,7 @@ var croutonDefaultTemplates = { "{{#isTemporarilyClosed this}}", "
{{temporarilyClosed this}}
", "{{/isTemporarilyClosed}}", - "
{{this.meeting_name}}
", + "
{{> meetingLink this}}
", "
{{this.location_text}}
", "
{{this.formatted_address}}
", "
{{this.formatted_location_info}}
", @@ -55,6 +55,13 @@ var croutonDefaultTemplates = { "{{#if this.config.has_meeting_count}}", "{{getWord 'meeting_count'}} {{this.meetings.meetingCount}}", "{{/if}}" - ].join('\n') + ].join('\n'), + meeting_link_template: [ + "{{#if this.meeting_details_url}}", + "{{this.meeting_name}}", + "{{else}}", + "{{this.meeting_name}}", + "{{/if}}" + ].join('\n') } diff --git a/croutonjs/src/js/crouton-localization.js b/croutonjs/src/js/crouton-localization.js index edb3cb2..7396a9e 100644 --- a/croutonjs/src/js/crouton-localization.js +++ b/croutonjs/src/js/crouton-localization.js @@ -40,6 +40,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "de-DE":{ "days_of_the_week": ["", "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], @@ -78,6 +80,8 @@ function CroutonLocalization(language) { }, "share": "Teilen", "no_meetings_for_this_day": "Keine Meetings an diesem Tag.", + 'css-textalign': '', + 'css-floatdirection': '' }, "en-AU": { "days_of_the_week" : ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], @@ -116,6 +120,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "en-CA": { "days_of_the_week" : ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], @@ -154,6 +160,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "en-NZ": { "days_of_the_week" : ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], @@ -192,6 +200,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "en-UK": { "days_of_the_week" : ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], @@ -230,6 +240,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "en-US": { "days_of_the_week" : ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], @@ -268,6 +280,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "es-US": { "days_of_the_week" : ["", "Domingo", " Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"], @@ -306,6 +320,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "fa-IR": { "days_of_the_week" : ["", 'یَکشَنب', 'دوشَنبه', 'سه‌شنبه', 'چهار شنبه', 'پَنج شَنبه', 'جُمعه', 'شَنبه'], @@ -344,6 +360,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': 'style="text-align:right;"', + 'css-floatdirection': 'style="float:right;"' }, "fr-CA": { "days_of_the_week" : ["", "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"], @@ -382,6 +400,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "it-IT": { "days_of_the_week" : ["", "Domenica", " Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"], @@ -420,6 +440,8 @@ function CroutonLocalization(language) { }, "share": "Condividi", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "nl-NL": { "days_of_the_week" : ["", "Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag"], @@ -458,6 +480,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "pl-PL": { "days_of_the_week" : ["", "Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"], @@ -496,6 +520,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "pt-BR": { "days_of_the_week" : ["", "Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"], @@ -534,6 +560,8 @@ function CroutonLocalization(language) { }, "share": "Compartilhar", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "ru-RU": { "days_of_the_week" : ["", "Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"], @@ -572,6 +600,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' }, "sv-SE": { "days_of_the_week" : ["", "Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"], @@ -610,6 +640,8 @@ function CroutonLocalization(language) { }, "share": "share", "no_meetings_for_this_day": "No meetings for this day.", + 'css-textalign': '', + 'css-floatdirection': '' } }; } diff --git a/croutonjs/src/templates/byday.hbs b/croutonjs/src/templates/byday.hbs index 675f770..5dc3ea6 100644 --- a/croutonjs/src/templates/byday.hbs +++ b/croutonjs/src/templates/byday.hbs @@ -5,7 +5,7 @@ {{#unless this.hide}} {{#greaterThan this.meetings.length 0}} - {{this.day}} + {{this.day}} {{/greaterThan}} {{/unless}} diff --git a/croutonjs/src/templates/byfield.hbs b/croutonjs/src/templates/byfield.hbs index 3020ddc..c1e3dd0 100644 --- a/croutonjs/src/templates/byfield.hbs +++ b/croutonjs/src/templates/byfield.hbs @@ -2,7 +2,7 @@ {{#each this}} - + {{> meetings }} diff --git a/croutonjs/src/templates/header.hbs b/croutonjs/src/templates/header.hbs index 57c5cfa..a41979c 100644 --- a/croutonjs/src/templates/header.hbs +++ b/croutonjs/src/templates/header.hbs @@ -168,9 +168,9 @@ {{#if this.config.has_tabs}} {{#ifEquals this.config.view_by "weekdays"}} - -
{{@key}}
+
{{this.formatted_day}}
{{#ifEquals this.duration_time "24:00:00"}}
{{this.start_time_formatted}}
@@ -44,7 +44,7 @@
{{formatLink this.formatted_comments}}
{{> (selectObserver) }}
+
{{> meetingDataTemplate }}
diff --git a/partials/_instructions.php b/partials/_instructions.php index d70f152..710a2d7 100644 --- a/partials/_instructions.php +++ b/partials/_instructions.php @@ -9,6 +9,7 @@
  • [meeting_count]
  • [group_count]
  • [service_body_names]
  • +
  • [bmlt_handlebar]
  • Example: There are currently [group_count] groups, offering a total of [meeting_count] meetings per week.

    Hints: you can only have one occurrence of [bmlt_tabs] on a page -- if you want two lists, @@ -85,6 +86,13 @@

    weekday = view meetings by Weekdays (default)

    Another example could be "location_municipality", which would show city if it were available as a button.

    +

    View By Language or Common Need

    +
    +

    With this parameter you can initially view meetings by Weekday or any other field, as long as the button_filters_option was added ahead of time.

    +

    [bmlt_tabs view_by="weekday"]

    +

    weekday = view meetings by Weekdays (default)

    +

    Another example could be "location_municipality", which would show city if it were available as a button.

    +

    Exclude City Button

    With this parameter you can exclude the City button.

    @@ -99,6 +107,13 @@

    [bmlt_tabs button_filters_option="City:location_municipality"]

    You can also include multiple buttons with a comma after each pair. Keep in mind that the first part is the word for the button. If using multilingual option, that word must have a translation.

    +

    Show Format Filter Buttons

    +
    +

    With this parameter you can include specific buttons.

    +

    [bmlt_tabs button_format_filters_option="Common Needs:FC3"]

    +

    [bmlt_tabs button_format_filters_option="Languages:LANG"]

    +

    You can also include multiple buttons with a comma after each pair. Keep in mind that the first part is the word for the button. If using multilingual option, that word must have a translation.

    +

    Tabs or No Tabs

    With this parameter you can display meetings without weekday tabs.

    @@ -132,9 +147,9 @@

    Dropdowns

    With this parameter you can show or hide the dropdowns.

    -

    [bmlt_tabs has_days='0|1' has_cities='0|1' has_groups='0|1' has_areas='0|1' has_regions='0|1' has_locations='0|1' has_sub_province='0|1' has_states='0|1' has_zip_codes='0|1' has_formats='0|1' has_neighborhoods='0|1' has_venues='0|1']

    -

    0 = hide dropdown

    -

    1 = show dropdown (default)

    +

    [bmlt_tabs has_days='0|1' has_cities='0|1' has_groups='0|1' has_areas='0|1' has_regions='0|1' has_locations='0|1' has_sub_province='0|1' has_states='0|1' has_zip_codes='0|1' has_formats='0|1' has_neighborhoods='0|1' has_venues='0|1' has_languages='0|1' has_common_needs='0|1']

    +

    0 = hide dropdown (default, for has_languages and has_common_needs)

    +

    1 = show dropdown (default, for all options other than has_languages and has_common_needs)

    Dropdown Filters

    @@ -225,6 +240,20 @@

    Multiple formats require the use of brackets `[]` which can break shortcodes. Replace brackets with `%5B%5D`.

    This can be overridden using a querystring parameter as well, but use must URL encode the query. Example: http://localhost:8080/?page_id=5&custom_query=%26meeting_key%3Dlocation_sub_province%26meeting_key_value%3DSampson

    +

    Query: Select by venue type

    +
    +

    With this parameter you can add restrictions to root server query, as an alternative to specifying a custom query. +

    [bmlt_tabs venues="1|2|3"]

    +

    Where

    • 1 = In-Person Meetings
    • 2 = Virtual Meetings
    • 3 = Hybrid Meetings
    +

    The values can also be negative, which means that the venue type should be excluded from the results. To specify more the one type, use a comma separated list.

    +
    +

    Query: Select by format

    +
    +

    With this parameter you can add restrictions to root server query, as an alternative to specifying a custom query. +

    [bmlt_tabs formats="123"]

    +

    Where the number specified is the shared id code for the format. Use the semantic workshop to look up format codes. +

    The values can also be negative, which means that the meetings with that format should be excluded from the results. To specify more the one format, use a comma separated list.

    +

    Companion Map

    With this parameter you can have crouton display a companion map of all the meetings.

    @@ -247,6 +276,50 @@

    [crouton_map map_search_zoom="10"] - specifies the starting zoom level on the map (default: 10).

    [crouton_map map_search_width="-50"] - specifies how many meetings to return, a positive integer means how many miles or kilometers to search. A negative integer indicates the closest number of meetings from that point with no distance limits. (default: -50 [the fifty closest meetings to the point selected]).

    The Google API Key must be entered on the crouton settings page for this to work. You must have the 'Google Maps JavaScript API' enabled on your key. For more information on setting up and configuring a Google Maps API key check out this blog article https://bmlt.app/google-api-key/

    +
    +

    Create Meeting-Detail Pages

    +
    +

    With this shortcode you can insert a HandlebarJS template into your page. +

    [bmlt_handlebar]

    +

    If the page is called with a query string including "meeting-id=your meeting here" + the default BMLT root server will be accessed to obtain the meeting information used when evaluating the template. The Meeting Data template, and all other templates and helpers + used by Crouton are also available for use within the [bmlt-handlebar] tag.

    +

    For instance, to put the meeting name as the title of the page, you could have + [bmlt_handlebar]<H1>{{this.meeting_name}}</H1>[/bmlt_handlebar] +

    +

    +

    In addition to the fields returned by the root server, the following fields are calculated and made available as part of the meeting data. +

      +
    • start_time_formatted
    • +
    • end_time_formatted
    • +
    • formatted_day
    • +
    • formats_expanded - which contains: +
        +
      • id
      • +
      • key
      • +
      • name
      • +
      • description
      • +
      • type
      • +
      +
    • +
    • venue_type
    • +
    • venue_type_name
    • +
    • formatted_address
    • +
    • formatted_location_info
    • +
    • serviceBodyUrl
    • +
    • serviceBodyPhone
    • +
    • serviceBodyName
    • +
    • serviceBodyDescription
    • +
    • serviceBodyContactEmail (must be comfigured in root server)
    • +
    • serviceBodyType
    • +
    +

    +
    +

    Extending Crouton

    +
    +

    Handlebars is the template system used by Crouton. You can add Helpers and Partials to Handlebars, and use + them in your templates, or to modify meeting data. An sample for doing this is available here. +

    Multilingual Support

    diff --git a/readme.txt b/readme.txt index c838be6..a7e5f6d 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: na, meeting list, meeting finder, maps, recovery, addiction, webservant, b Requires at least: 4.0 Required PHP: 5.6 Tested up to: 6.2.2 -Stable tag: 3.15.3 +Stable tag: 3.16.0 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html crouton implements a Tabbed UI for BMLT. @@ -36,6 +36,20 @@ https://demo.bmlt.app/crouton == Changelog == += 3.16.0 = +* New shortcode [bmlt_handlebar]: the contents of the shortcode are interpreted as a handlebarjs template. + The meeting that will be used when executing the template is determined from the page's query_string, eg, + query string "?meeting-id=123" means that meeting 123 will supply the data. Multiple uses of the shortcode are + allowed on the page. These pages can be used to provide a detailed web presence for the meeting. +* New partial "> meetingLink" will generate a link to the meeting details page. The next for the link is the + meeting name. +* Am API has been added for creating custom partials and helpers for use in Handlebars templates, or to customise + the enrichment of meeting data. +* Special-Interest Dropdown. This is basically just a filter of the formats dropdown, but because there are so many formats, the formats dropdown is pretty unusable. +* View-By Language and View-By Special-Interest buttons. Like the view-by city option, but for these format codes. +* 'has_meeting_count' flag, adding a meeting count to the table without the use of an additional [meeting_count] shortcode. +* 'venue_type' added to the [bmlt_tabs] shortcode, to allow for easy filtering of meetings without needing a custom query. + = 3.15.3 = * Fixed German translation for Friday.