From b7e34cd0679b4f892ac89ff0b7d7b9c5035a59fa Mon Sep 17 00:00:00 2001 From: Phillip Gray Date: Wed, 8 Jul 2020 16:29:13 +1200 Subject: [PATCH] initial --- .gitignore | 1 + README.markdown | 18 ++++++ assets/publish_blocks.publish.css | 24 +++++++ assets/publish_blocks.publish.js | 47 ++++++++++++++ extension.driver.php | 68 ++++++++++++++++++++ extension.meta.xml | 20 ++++++ fields/field.publish_blocks.php | 103 ++++++++++++++++++++++++++++++ 7 files changed, 281 insertions(+) create mode 100644 .gitignore create mode 100644 README.markdown create mode 100644 assets/publish_blocks.publish.css create mode 100644 assets/publish_blocks.publish.js create mode 100644 extension.driver.php create mode 100644 extension.meta.xml create mode 100644 fields/field.publish_blocks.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..0b724bf --- /dev/null +++ b/README.markdown @@ -0,0 +1,18 @@ +# Publish Blocks + +## Purpose + +Nicely organise primary and secondary content into blocks. Similar behaviour to the Publish Tabs extension, but it stacks content instead of hiding it. + +## Installation + +1. Upload the `/publish_blocks` folder to your Symphony `/extensions` folder +2. Enable it by selecting "Publish Blocks" in the list, choose Enable from the with-selected menu, then click Apply +3. When creating or editing a section you can add the "Publish Block" field + + +## Usage + +Add one or more Publish Block field(s) to a section. Give each a sensible label. Save. + +When you add a Publish Block field to a section, any fields that appear *after* this field in the field order will become part of that Block (both left and right columns). \ No newline at end of file diff --git a/assets/publish_blocks.publish.css b/assets/publish_blocks.publish.css new file mode 100644 index 0000000..b358103 --- /dev/null +++ b/assets/publish_blocks.publish.css @@ -0,0 +1,24 @@ +.block-group-wrapper:after { + display: block; + content: attr(data-label); + background-color: #ffffff; + padding-right: 10px; + + position: absolute; + top: 3px; + left: 0; + + font-weight: 700; +} + +.block-group-wrapper:before { + display: block; + content: ''; + height: 4px; + margin-bottom: 15px; + background-color: #333; +} + +.block-group-wrapper:not(:last-of-type) { + margin-bottom: 50px; +} \ No newline at end of file diff --git a/assets/publish_blocks.publish.js b/assets/publish_blocks.publish.js new file mode 100644 index 0000000..8d581f8 --- /dev/null +++ b/assets/publish_blocks.publish.js @@ -0,0 +1,47 @@ +(function ($, undefined) { + 'use strict'; + + $(function() { + var body = $('body'), + block_fields = $('.field-publish_blocks'), + publish_blocks = Symphony.Context.get('publish-blocks'); + + // thy shalt not pass if no Publish Block fields exist + if (!block_fields.length) return; + + for(var i in publish_blocks) { + var main_fields = '', + sidebar_fields = '', + publish_blocks_field = $('#field-' + publish_blocks[i]['block_id']); + + for(var field in publish_blocks[i].main) main_fields += '#' + publish_blocks[i].main[field] + ', '; + for(var field in publish_blocks[i].sidebar) sidebar_fields += '#' + publish_blocks[i].sidebar[field] + ', '; + + main_fields = main_fields.replace(/, $/,''); + sidebar_fields = sidebar_fields.replace(/, $/,''); + + $(main_fields).wrapAll(`
`); + $(sidebar_fields).wrapAll(`
`); + + // var tab_field = $('#field-' + publish_blocks[i]['block_id']).remove(); + publish_blocks_field.remove(); + } + + // unwrap default primary/secondary columns + body.find('.primary, .secondary').contents().unwrap(); + + body.find('.block-group-main').each(function () { + var self = $(this), + // Wrap each block group into a fieldset container + fieldset = self.wrap('
').removeAttr('data-label').parent(), + // Locate any secondary columns + secondary = body.find('.block-group-secondary[data-id="' + self.data('id') + '"]'); + + // Make this block group the primary + self.addClass('primary column'); + // Update secondary classes and append to this fieldset + if (secondary.length) secondary.addClass('secondary column').appendTo(fieldset); + }) + }); + +})(jQuery); \ No newline at end of file diff --git a/extension.driver.php b/extension.driver.php new file mode 100644 index 0000000..c254777 --- /dev/null +++ b/extension.driver.php @@ -0,0 +1,68 @@ +query("DROP TABLE `tbl_fields_publish_blocks`"); + } + + public function install() { + Symphony::Database()->query( + "CREATE TABLE IF NOT EXISTS `tbl_fields_publish_blocks` ( + `id` int(11) NOT NULL auto_increment, + `field_id` int(11) NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;" + ); + return true; + } + + public function getSubscribedDelegates() { + return array( + array( + 'page' => '/backend/', + 'delegate' => 'InitaliseAdminPageHead', + 'callback' => 'initializeAdmin' + ), + ); + } + + public function initializeAdmin($context) { + $page = Administration::instance()->Page; + $context = $page->getContext(); + + $callback = Administration::instance()->getPageCallback(); + + // only proceed on New or Edit publish pages + if ($page instanceof contentPublish and in_array($context['page'], array('new', 'edit'))) { + $page->addStylesheetToHead(URL . '/extensions/publish_blocks/assets/publish_blocks.publish.css', 'screen', 9001); + $page->addScriptToHead(URL . '/extensions/publish_blocks/assets/publish_blocks.publish.js', 9002); + + include_once(TOOLKIT . '/class.sectionmanager.php'); + + $section_id = SectionManager::fetchIDFromHandle($callback['context']['section_handle']); + $section = SectionManager::fetch($section_id); + + if( !$section instanceof Section ) return; + + $blocks = array(); + $index = -1; + + foreach($section->fetchFieldsSchema() as $i => $field) { + if ($field['type'] == 'publish_blocks') { + $blocks[++$index]['block_id'] = $field['id']; + } else { + $blocks[$index][$field['location']][] = 'field-' . $field['id']; + } + } + + $page->addElementToHead(new XMLElement( + 'script', + "Symphony.Context.add('publish-blocks', " . json_encode($blocks) . ")", + array('type' => 'text/javascript') + ), 9003); + } + + } + + } diff --git a/extension.meta.xml b/extension.meta.xml new file mode 100644 index 0000000..81a618d --- /dev/null +++ b/extension.meta.xml @@ -0,0 +1,20 @@ + + + Publish Blocks + Add block groups to entry edit forms + https://github.com/pixelninja/publish_blocks + https://github.com/pixelninja/publish_blocks/issues + + Interface + + + + Phillip Gray + phill@thebold.nz + https://www.thebold.nz + + + + + + diff --git a/fields/field.publish_blocks.php b/fields/field.publish_blocks.php new file mode 100644 index 0000000..cfb5cf6 --- /dev/null +++ b/fields/field.publish_blocks.php @@ -0,0 +1,103 @@ +_name = __('Publish Block'); + $this->_required = false; + $this->set('hide', 'no'); + } + + /*------------------------------------------------------------------------- + Setup: + -------------------------------------------------------------------------*/ + + public function createTable(){ + return Symphony::Database()->query( + "CREATE TABLE IF NOT EXISTS `tbl_entries_data_" . $this->get('id') . "` ( + `id` int(11) unsigned NOT NULL auto_increment, + `entry_id` int(11) unsigned NOT NULL, + `value` double default NULL, + PRIMARY KEY (`id`), + KEY `entry_id` (`entry_id`), + KEY `value` (`value`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;" + ); + } + + /*------------------------------------------------------------------------- + Settings: + -------------------------------------------------------------------------*/ + + public function commit(){ + if(!parent::commit()) return false; + + $id = $this->get('id'); + + if($id === false) return false; + + $fields = array(); + $fields['field_id'] = $id; + + return FieldManager::saveSettings($id, $fields); + } + + /*------------------------------------------------------------------------- + Publish: + -------------------------------------------------------------------------*/ + + public function displayPublishPanel(XMLElement &$wrapper, $data = NULL, $flagWithError = NULL, $fieldnamePrefix = NULL, $fieldnamePostfix = NULL, $entry_id = NULL){ + $wrapper->setValue($this->get('label')); + } + + public function processRawFieldData($data, &$status, &$message = NULL, $simulate = false, $entry_id = NULL) { + $status = self::__OK__; + + return array( + 'value' => '' + ); + } + + /*------------------------------------------------------------------------- + Output: + -------------------------------------------------------------------------*/ + + public function fetchIncludableElements() { + return null; + } + + public function appendFormattedElement(XMLElement &$wrapper, $data, $encode = false, $mode = NULL, $entry_id = NULL) { + + } + + public function prepareReadableValue($data, $entry_id = NULL, $truncate = false, $defaultValue = NULL) { + return $this->prepareTableValue($data, null, $entry_id); + } + + public function prepareTableValue($data, XMLElement $link=NULL, $entry_id=NULL) { + // build this entry fully + $entries = EntryManager::fetch($entry_id); + + if ($entries === false) return parent::prepareTableValue(NULL, $link, $entry_id); + + $entry = reset(EntryManager::fetch($entry_id)); + + // get the first field inside this tab + $field_id = Symphony::Database()->fetchVar('id', 0, "SELECT `id` FROM `tbl_fields` WHERE `parent_section` = '".$this->get('parent_section')."' AND `sortorder` = ".($this->get('sortorder') + 1)." ORDER BY `sortorder` LIMIT 1"); + + if ($field_id === NULL) return parent::prepareTableValue(NULL, $link, $entry_id); + + $field = FieldManager::fetch($field_id); + + // get the first field's value as a substitude for the tab's return value + return $field->prepareTableValue($entry->getData($field_id), $link, $entry_id); + } + + }