├── PageBuilder ├── Images │ ├── edit.png │ └── stage.png ├── README.md ├── Edit.md ├── Edit │ ├── InputTypes.md │ └── Widgets.md ├── Modal.md ├── Overview.md ├── Stage.md ├── Config.md ├── Plugins.md ├── Walkthrough.md ├── Resources.md └── Hooks.md ├── PageBuilderBlocks ├── Images │ ├── type.png │ ├── design.png │ ├── content-fields.png │ ├── content-attributes.png │ ├── new-content-attribute.png │ └── new-content-attribute-label.png ├── ContentAttributes.md ├── Overview.md ├── StructuralContentAttributes.md └── CustomBlock.md ├── ContentApps └── ImagesSizes.md └── README.md /PageBuilder/Images/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genecommerce/Blue-Foot-Documentation/HEAD/PageBuilder/Images/edit.png -------------------------------------------------------------------------------- /PageBuilder/Images/stage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genecommerce/Blue-Foot-Documentation/HEAD/PageBuilder/Images/stage.png -------------------------------------------------------------------------------- /PageBuilderBlocks/Images/type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genecommerce/Blue-Foot-Documentation/HEAD/PageBuilderBlocks/Images/type.png -------------------------------------------------------------------------------- /PageBuilderBlocks/Images/design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genecommerce/Blue-Foot-Documentation/HEAD/PageBuilderBlocks/Images/design.png -------------------------------------------------------------------------------- /PageBuilderBlocks/Images/content-fields.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genecommerce/Blue-Foot-Documentation/HEAD/PageBuilderBlocks/Images/content-fields.png -------------------------------------------------------------------------------- /PageBuilderBlocks/Images/content-attributes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genecommerce/Blue-Foot-Documentation/HEAD/PageBuilderBlocks/Images/content-attributes.png -------------------------------------------------------------------------------- /PageBuilderBlocks/Images/new-content-attribute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genecommerce/Blue-Foot-Documentation/HEAD/PageBuilderBlocks/Images/new-content-attribute.png -------------------------------------------------------------------------------- /PageBuilderBlocks/Images/new-content-attribute-label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genecommerce/Blue-Foot-Documentation/HEAD/PageBuilderBlocks/Images/new-content-attribute-label.png -------------------------------------------------------------------------------- /PageBuilder/README.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | 3 | 1. [Overview](/PageBuilder/Overview.md) 4 | 2. [Walkthrough](/PageBuilder/Walkthrough.md) 5 | 3. [Resources](/PageBuilder/Resources.md) 6 | 4. [Hooks](/PageBuilder/Hooks.md) 7 | 5. [Plugins](/PageBuilder/Plugins.md) 8 | 6. [Modal](/PageBuilder/Modal.md) 9 | 7. [Config](/PageBuilder/Config.md) 10 | 8. [Stage](/PageBuilder/Stage.md) 11 | 9. [Edit](/PageBuilder/Edit.md) 12 | 1. [Input Types](/PageBuilder/Edit/InputTypes.md) 13 | 2. [Widgets](/PageBuilder/Edit/Widgets.md) 14 | -------------------------------------------------------------------------------- /PageBuilder/Edit.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Edit 3 | The edit panel is the sidebar that scrolls into the right whenever a user is editing content. 4 | 5 | ![alt text](Images/edit.png "Type") 6 | 7 | The panel is built up of multiple fields, or widgets. Each field or widget is responsible for the mark up and functionality of that particular field. The core system ships with all core Magento input types support, along with a number of extra widgets which can be assigned to [content attributes](/PageBuilderBlocks/ContentAttributes.md). 8 | 9 | [Input Types](/PageBuilder/Edit/InputTypes.md) 10 | 11 | [Widgets](/PageBuilder/Edit/Widgets.md) 12 | -------------------------------------------------------------------------------- /PageBuilderBlocks/ContentAttributes.md: -------------------------------------------------------------------------------- 1 | # Blue Foot: Page Builder Blocks 2 | ## Content Attributes 3 | Each block within the page builder is built up of content attributes. These follow the core Magento EAV structure. An attribute can be assigned to multiple page builder blocks. 4 | 5 | ### Admin Interface 6 | You can manage and create these via `System > BlueFoot > Content Attributes` 7 | 8 | ##### Manage Content Attributes 9 | ![alt text](Images/content-attributes.png "Manage Content Attributes") 10 | 11 | ##### Add Attribute 12 | ![alt text](Images/new-content-attribute.png "New Content Attribute") 13 | ![alt text](Images/new-content-attribute-label.png "New Content Attribute Label Tab") 14 | -------------------------------------------------------------------------------- /PageBuilder/Edit/InputTypes.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder Blocks 2 | ## Input Types 3 | Magneto implments a number of familiar input types, along with renderers within their form widgets. Our page builder implements these input types in JavaScript to align the page builder experience with the true capabilities of Magento. 4 | 5 | The input type classes are located within `component/core/edit/fields`. All input types and widgets extend the abstract class located within `abstract.js`. 6 | 7 | - `date.js`: Provides Magento date picker functionality. 8 | - `select.js`: Provides select and multi select functionality. 9 | - `text.js`: Provides simple text inputs. 10 | - `textarea.js`: Provides textarea functionality. 11 | 12 | Dynamic field types, such as the WYSIWYG editor, are driven by [widgets](Widgets.md) 13 | 14 | The system maps the Magento input fields within the `Gene_BlueFoot_Model_Stage_Data` class and the `_flattenAttributeData` function. 15 | -------------------------------------------------------------------------------- /PageBuilder/Modal.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Modal 3 | The modal system allows the system to present the user with attractive and user orientated messages. 4 | 5 | The functionality for the modal system can be found within the `modal.js` component. 6 | 7 | ### Calling the modal system 8 | The modal system is included early on in the applications initializing, this means you don't have to declare it as a dependency of the current file. 9 | 10 | To retrieve an instance of the modal file, you can call: 11 | ``` 12 | require('bluefoot/modal'); 13 | ``` 14 | 15 | However we would suggest you declare this as a depedency of the current file so it can be used multiple times. If you declare it as a depdency instead of using a require, you will use the variable you assign the instance to in place of the `require('bluefoot/modal')` code above. 16 | 17 | ``` 18 | define(['bluefoot/hook', 'bluefoot/modal'], function (Hook, Modal) { 19 | ... 20 | Modal.alert(..); 21 | ... 22 | }); 23 | ``` 24 | 25 | ### Alert 26 | If you're wanting to fire an alert you can do so by calling the following. 27 | 28 | ``` 29 | require('bluefoot/modal').alert('Your alert message', 'Window Title'); 30 | ``` 31 | 32 | Replacing the alert message, and window title with your prefence, you can ommit the window title and the system will fallback to the default. 33 | 34 | ### Confirm 35 | You can also fire a confirmation box requesting the users interaction. 36 | 37 | ``` 38 | require('bluefoot/modal').confirm('Confirmation Message', 'Window Title', function () { 39 | // The user has accepted the confirmation window 40 | }.bind(this)); 41 | ``` 42 | 43 | Again replacing the message and title with your preference. The callback function will be ran if the user accepts the confirmation window. 44 | -------------------------------------------------------------------------------- /PageBuilderBlocks/Overview.md: -------------------------------------------------------------------------------- 1 | # Blue Foot: Page Builder Blocks 2 | ## Overview 3 | The page builder is built up of a number of different page builder blocks. Each of these blocks represents a different bit of content. This could be a heading, textarea or even a slider. Each of these blocks are built up using Magento's built in EAV structure. A page builder block can have any number of fields and groups assigned to it. Allowing anyone to utilise BlueFoot to create reusable and beautiful blocks. 4 | 5 | ### Admin Interface 6 | To start you'll need to build up your blocks fields and structure. This can be done directly in the admin under `System > BlueFoot > Page Builder Blocks > Add Page Builder Block`. You'll be presented with the following 3 tabs. 7 | 8 | ##### Type 9 | The type tab allows you to configure the basic details around the page builder block. This includes whether or not this block can be used directly in the page builder. If a block is going to be a child block of another block then you may want it to be hidden from the left hand panel in the page builder. 10 | 11 | ![alt text](Images/type.png "Type") 12 | 13 | ##### Content Fields 14 | These are the attributes that are assigned into your block, you're able to add new fields via the `System > BlueFoot > Content Attributes`. These follow the same structure as product and category attributes in Magento. 15 | 16 | ![alt text](Images/content-fields.png "Content Fields") 17 | 18 | ##### Design 19 | The design tab allows you to configure the front-end block template and renderer. These dictate how the block should be rendered to your end users on the front-end of your store. The preview field is used within the page builder view when an admin preview template isn't configured. 20 | 21 | ![alt text](Images/design.png "design") 22 | -------------------------------------------------------------------------------- /ContentApps/ImagesSizes.md: -------------------------------------------------------------------------------- 1 | # Blue Foot: Image Sizes 2 | ## Existing Images 3 | Out of the box 3 images sizes exist within BlueFoot: 4 | 5 | - thumbnail (300 x 200) 6 | - medium (860 x 450) 7 | - large (1400 x 750) 8 | 9 | These can all be found in app/code/community/Gene/BlueFoot/etc/bluefoot/bluefoot.xml 10 | 11 | 12 | ### Using content app image sizes 13 | To use BlueFoots image sizes in a phtml template you should use our image helper 14 | ``` 15 | getEntity(); 17 | $_imageHelper = Mage::helper('gene_bluefoot/image'); 18 | ?> 19 | 20 | getFeaturedImage())): ?> 21 | <?php echo $_entity->getTitle(); ?> 22 | 23 | ``` 24 | In this example you can see the 'medium' image is used. 25 | 26 | ### Add custom image sizes 27 | Adding custom image sizes is simple. 28 | 29 | First you must add your own bluefoot.xml to your module (app/code/local/NAMESPACE/MODULE/etc/bluefoot/bluefoot.xml) 30 | 31 | Then add the following code: 32 | 33 | ``` 34 | 35 | 36 | 37 | 38 | 39 | WIDTH 40 | HEIGHT 41 | 42 | 43 | 44 | 45 | ``` 46 | In this example replace 'IMAGE_ALIAS' with your alias and the width and height you need. 47 | 48 | ### Custom image options 49 | You can use pass the following options to your image 50 | 51 | ``` 52 | 53 | 54 | 55 | 56 | 57 | 58 | ``` 59 | -------------------------------------------------------------------------------- /PageBuilder/Overview.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Overview 3 | The page builder provide drag and drop, sorting and editing functionality to any WYSIWYG editor within the Magento admin. It does this by including an 'Enable Blue Foot' button next to every WYSIWYG editor in the admin. 4 | 5 | Upon pressing this button you will be presetened with the Page Builder UI. The UI is split into two sections, the left being the panel and the right being the stages contents. Each instance of the page builder is refered to as a stage. 6 | 7 | ### Technologies 8 | We have included a number of technologies within the page builder system: 9 | 10 | - [jQuery](http://jquery.com) 11 | - [jQuery UI](https://jqueryui.com) 12 | - [DropzoneJS](http://www.dropzonejs.com) 13 | - [RequireJS](http://requirejs.org) 14 | - [MustacheJS](https://github.com/janl/mustache.js) 15 | 16 | These are all included using RequireJS, and will not pollute the window, so you're safe to use any other libraries outside of our systems without causing conflict. 17 | 18 | ### jQuery 19 | jQuery could be considered an unpopular solution for many developers, however we made the decision to use jQuery due to it's great browser support and for the interactions jQuery UI provides. When performance is critical we only use native JavaScript code to ensure our solution isn't going to cause performance issue for the end user. 20 | 21 | ### RequireJS 22 | RequireJS is a core component within the page builder and is used for all dependency loading, if you're planning on customization a part of the page builder you'll need to have a basic understanding of RequireJS. 23 | 24 | > RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code. 25 | 26 | ### MustacheJS 27 | Provides a logicless templating system in JavaScript. Allows us to define templates and build them easily using objects. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Developer Documentation 2 | 3 | [![Join the chat at https://gitter.im/DaveMacaulay/Blue-Foot-Documentation](https://badges.gitter.im/DaveMacaulay/Blue-Foot-Documentation.svg)](https://gitter.im/DaveMacaulay/Blue-Foot-Documentation?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | 5 | This documentation outlines the various way developers can extend & enhance the Blue Foot Magento module. The Blue Foot system has two main areas which can be extended, the page builder and content apps. Both are outlined in seperate sections which can be accessed below. 6 | 7 | For more information see: 8 | https://www.bluefootcms.com/ 9 | 10 | ## Magento 1 11 | 1. [Page Builder](PageBuilder/Overview.md) 12 | 1. [Overview](PageBuilder/Overview.md) 13 | 2. [Walkthrough](PageBuilder/Walkthrough.md) 14 | 3. [Resources](PageBuilder/Resources.md) 15 | 4. [Hooks](PageBuilder/Hooks.md) 16 | 5. [Plugins](PageBuilder/Plugins.md) 17 | 6. [Modal](PageBuilder/Modal.md) 18 | 7. [Config](PageBuilder/Config.md) 19 | 8. [Stage](PageBuilder/Stage.md) 20 | 9. [Edit](PageBuilder/Edit.md) 21 | 1. [Input Types](PageBuilder/Edit/InputTypes.md) 22 | 2. [Widgets](PageBuilder/Edit/Widgets.md) 23 | 2. [Page Builder Blocks](PageBuilderBlocks/Overview.md) 24 | 1. [Overview](PageBuilderBlocks/Overview.md) 25 | 2. [Content Attributes](PageBuilderBlocks/ContentAttributes.md) 26 | 3. [Creating a custom block](PageBuilderBlocks/CustomBlock.md) 27 | 4. [Creating a structural content attribute](PageBuilderBlocks/StructuralContentAttributes.md) 28 | 3. Content Apps 29 | 1. [Image sizes](ContentApps/ImagesSizes.md) 30 | 31 | ## Magento 2 32 | We are in the process of completing our Magento 2 documentation. These will be available shortly, if you have any questions regarding how to use Magento 2 please contact our support. 33 | 34 | ## Contributions or requests 35 | If you're wanting to make any contributions or changes to these docs, please feel free to conduct a pull request and it will be approved by one of our developers if it's deemed helpful. 36 | 37 | If you're unsure on how pull requests work, or wish to request more information around a certain topic please email documentation@bluefootcms.com 38 | -------------------------------------------------------------------------------- /PageBuilderBlocks/StructuralContentAttributes.md: -------------------------------------------------------------------------------- 1 | # Blue Foot: Page Builder Blocks 2 | ## Structural Content Attributes 3 | Content attributes for structural elements such as rows and columns cannot be added using the admin interface, these are defined in XML. You will see these defined within a structural handle in app/code/community/Gene/BlueFoot/etc/bluefoot/pagebuilder.xml. 4 | 5 | ##### Adding a Structural Content Attribute 6 | To add a structural content attribute you must first create a pagebuilder.xml within your module. 7 | 8 | app/code/community/[Namespace]/[Module]/etc/bluefoot/pagebuilder.xml 9 | 10 | From here you can add your own attribute. 11 | ``` 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ``` 26 | 27 | ELEMENT should be either row or column. 28 | 29 | To use a widget rather than a standard input pass 'widget' into the type argument and then define the widget as a separate argument. 30 | 31 | 32 | ##### Accessing your Attribute in a phtml file 33 | To access your new attribute within your phtml files you can simply pass the attribute code to the 'getFormData' function. 34 | 35 | ``` 36 | getFormData(ATTRIBUTE_CODE); ?> 37 | ``` 38 | 39 | 40 | ##### Example Code 41 | This example shows how to add the text attribute 'title' to columns. 42 | 43 | app/code/community/[Namespace]/[Module]/etc/bluefoot/pagebuilder.xml 44 | 45 | ``` 46 | 47 | 48 | 49 | 50 | 51 | 52 | <label><![CDATA['Title']]></label> 53 | <type>text</type> 54 | <code>title</code> 55 | 56 | 57 | 58 | 59 | 60 | ``` 61 | app/design/frontent/[Package]/[Theme]/template/gene/bluefoot/pagebuilder/structural/core/column.phtml 62 | 63 | ``` 64 |
getStyleAttributes(); ?>> 65 | getFormData('title')): ?> 66 |

67 | 68 | getRenderedChildHtml(); ?> 69 |
70 | ``` 71 | 72 | -------------------------------------------------------------------------------- /PageBuilder/Stage.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Stage 3 | The stage is one of the most important parts of the page builder. It's the area which houses all of your rows, columns & content. Along with allowing interactions between other components such as the left panel. 4 | 5 | ![alt text](Images/stage.png "Stage") 6 | 7 | ### Responsibilities 8 | The stage is responsible for the majority of the interactions which happen between the user and their content. The stage is the network of the system, allow various components to all communicate and interact deeply. 9 | 10 | #### Building & saving 11 | The system uses two dedicated classes for the building and saving of the content, these can be found at `component/core/stage/build.js` and `component/core/stage/save.js`. Each of these classes implement various methods to ensure the system can effectively save and build any content that's created within the page builder. 12 | 13 | ##### Saving 14 | The system iterates through all the rows, columns and entities on the page and creates objects which represent the data, along with any other extra data that would be required for the block to be rebuilt. Once it's created the nested object containing all of the pages data it turns this into a string and updates a hidden input above the stages interface. This system uses the `gene-bluefoot-stage-updated` hook to know when it needs to rebuild the object stored within the input, this ensures that the content will always be saved after any modification the user makes. 15 | 16 | > Instead of building this on form submission we wanted to ensure that the system could be used anywhere in Magento, including Ajax and forms with overridden submit actions. 17 | 18 | Server side this object is parsed and the contents are commited into the EAV structure associated with each individual block. The system then replaces the raw data with a pointer to the entity so it can load it directly from the database when the data is being rendered or rebuilt. 19 | 20 | ##### Building 21 | On load our system iterates through all of the textareas loaded upon the page, detecting whether or not they have an object attached to them. If they have an object, and it's a valid to be rebuilt the system will start iterating through the object, recreating each row, column or entity in the exact same position, with the correct associated data. As we want to avoid unnecessary loading of data the stored object will reference the store entity ID's for each page builder block. When the system loads the configuration from the server it will also pass the entity ID's to be loaded and returned in the configuration. 22 | 23 | This also allows other developers to hook into this action to include extra data that might not have been directly stored within the entity. 24 | -------------------------------------------------------------------------------- /PageBuilder/Config.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Config 3 | The page builder relies on a lot of data from Magento. It retrieves this via an Ajax request when the page builder is initialized. The request is defered until the user requests the page builder interface to ensure that we don't interupt their other interaction with the page. 4 | 5 | You may need to pass through server side information to your widget or plugin. Commonly this would be extra data, ajax URLs or configuration values. 6 | 7 | #### Observer event 8 | You can utilise the Magento `gene_bluefoot_stage_build_config` observer event to modify the build config for the stage. This is the configuration that is passed back to the system on initialize. 9 | 10 | You can see the following in the core `config.xml` 11 | ``` 12 | 13 | 14 | 15 | singleton 16 | gene_bluefoot/stage_widget_observer 17 | stageBuildConfig 18 | 19 | 20 | 21 | ``` 22 | 23 | On closer inspection of `gene_bluefoot/stage_widget_observer` we can see that the `Varien_Event_Observer` contains the configuration under the key `config`. 24 | 25 | To add new data into the config you'll need to retrieve the data, modify it and reset it back into the config `Varien_Object.` 26 | 27 | For instance: 28 | ``` 29 | public function stageBuildConfig(Varien_Event_Observer $observer) 30 | { 31 | /* @var $config Varien_Object */ 32 | $config = $observer->getEvent()->getConfig(); 33 | $pluginData = $config->getData('plugins'); 34 | 35 | // Send the upload path URL 36 | $pluginData['gene_testing']['config']['upload_url'] = Mage::helper('adminhtml')->getUrl('adminhtml/gene_testing/upload'); 37 | 38 | $config->setData('plugins', $pluginData); 39 | 40 | return $this; 41 | } 42 | ``` 43 | 44 | This will then add the above keys into the plugins section under the `gene_testing` plugin. 45 | 46 | #### Accessing extra configuration data 47 | When the system loads this config it stores it within the page builder's `config.js` file. There are various helper methods within this resource to help you obtain data. 48 | 49 | ##### Plugin data 50 | If you declare your extra configuration data within a plugin as above you can access it via the 51 | ``` 52 | Config.getPluginConfig('gene_testing', 'upload_url'); 53 | ``` 54 | 55 | Replacing the first parameter with the plugin name, and the second with the key within config. 56 | 57 | ##### Other data 58 | You're able to access any other data directly via the `getValue` function. We highly reccomend keeping your extra data within the plugin scope, so to not clutter the configuration. 59 | ``` 60 | Config.getValue('key'); 61 | ``` 62 | 63 | 64 | -------------------------------------------------------------------------------- /PageBuilder/Plugins.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Plugins 3 | You can declare a plugin to run specific code at a certain point within the page builder. This can be useful to attach a number of hooks, fire other hooks or modify aspects of the stage. 4 | 5 | ### Declaring a plugin 6 | We declare our plugin via the `plugins` section of the `pagebuilder.xml`. You can see the core module utilises this functionality often to include various aliases for widgets and other components. 7 | 8 | To create a new plugin you would declare the following 9 | ``` 10 | 11 | ... 12 | 13 | ... 14 | 15 | example 16 | component/local/gene/example/plugin 17 | onPageLoad 18 | 19 | ... 20 | 21 | ... 22 | 23 | ``` 24 | 25 | - **alias**: How the JavaScript file can be called as a dependency in RequireJS. 26 | - **path**: The path to the JS file, as you're creating a new custom resource this should reside in the local folder. 27 | - **load** (optional): At which point should the system initialize your file. This can be either on the page load (`onPageLoad`) or when the stage is initialized (`onStageInit`). 28 | 29 | For the example above we must create `plugin.js` within the `local/gene/example` component folder. 30 | ``` 31 | /** 32 | * Example Plugin for BlueFoot 33 | * 34 | * @author Dave Macaulay 35 | */ 36 | define(['hook'], function (Hook) { 37 | 38 | // Declare any events 39 | Hook.attach('gene-bluefoot-before-stage-init', function ($hook) { 40 | // Do various logic 41 | $hook.done(); 42 | }); 43 | 44 | return { 45 | /** 46 | * Initialize function called by the CMS 47 | * 48 | * @param stage 49 | */ 50 | init: function (stage) { 51 | // Do any init logic 52 | } 53 | }; 54 | }); 55 | ``` 56 | 57 | Here you can see we're attaching a hook that will be triggered when any stage is initialized. We are passed the stage within the init function if it's declare. If you only want to attach a hook to the specific stages instead of globally you would need to move your hook into the init function and pass the stage as the context appropriately ([see hooks](Hooks.md)). 58 | 59 | ### jQuery plugins 60 | As you may of seen whilst inspecting the code there is also a `jquery` tag defined with a number of child entities. You can find out more about how to use this functionality within the resources section. 61 | 62 | [Read more about jQuery plugins](Resources.md#including-your-own-jquery-plugin) 63 | 64 | ### Async 65 | The final section of the plugins area is the async area. This is used for async dependency load like JSONP and Google Maps. Within the core module this is used to ensure the correct loading of the Google Maps API. 66 | 67 | ``` 68 | 69 | ... 70 | 71 | ... 72 | 73 | //maps.google.com/maps/api/js 74 | 75 | ... 76 | 77 | ... 78 | 79 | ``` 80 | 81 | All async plugins are loaded at the start of a stage being initialized and will be available throughout the application. 82 | -------------------------------------------------------------------------------- /PageBuilderBlocks/CustomBlock.md: -------------------------------------------------------------------------------- 1 | # Blue Foot: Page Builder Blocks 2 | ## Creating a custom block 3 | Creating a custom block wth BlueFoot is easy. The first thing you will need to do is create and register your custom blocks and templates. 4 | 5 | #### Adding an custom page builder xml file 6 | 7 | To register custom templates and blocks you must first create a pagebuilder.xml within your module. 8 | app/code/community/[Namespace]/[Module]/etc/bluefoot/pagebuilder.xml 9 | 10 | ``` 11 | 12 | 13 | 14 | ``` 15 | 16 | #### Registering a template 17 | 18 | To register a template add the following code to your custom pagebuilder.xml file. 19 | ``` 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | js_css 28 | gene/bluefoot/resource/your.css 29 | 30 | 31 | js 32 | gene/bluefoot/resource/your.js 33 | 34 | 35 | 36 | 37 | 38 | ``` 39 | 40 | TEMPLATE_IDENTIFIER should be a unique identifier for your template. e.g. awesome_custom_block 41 | To load assets with your template please identify them inside 'assets'. 42 | CSS_IDENTIFIER & JS_IDENTIFIER are simple unique identifiers for the assets. 43 | If you want a custom admin template BlueFoot will use the same template within your admin theme. 44 | 45 | 46 | #### Registering a block 47 | 48 | If your custom block needs it's own set of functions it's recommended to create a custom block for it. Simple blocks should be fine using the blocks that already exist within BlueFoot. 49 | Registering a block works in exactly the same way as registering a template. First open your pagebuilder.xml file and add the following code. 50 | 51 | ``` 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | ``` 60 | 61 | #### Creating a block 62 | 63 | Now you have registered a template and block it's time to get started creating your block. 64 | This can all be done within the admin. You can see visuals of these pages on the [Overview](Overview.md) page. 65 | 66 | **Step 1** - Create your attributes 67 | If you want your block to have attributes that don't already exist you will need to create them. Doing this is simple, first visit System->BlueFoot->Content Attributes. 68 | From here you can create attributes in the same way you would product attributes. 69 | 70 | **Step 2** - Create your block 71 | Go to System->BlueFoot->Page Builder Blocks. From here you can creates blocks easily. Remember to hit 'Use in Page Builder' and to assign your template and box. 72 | 73 | #### Creating your template 74 | 75 | The last step is to create your templates. Once your have created the file specified in your pagebuilder.xml you can add what ever markup you like :-) 76 | An example below shows how to load the title attribute in a template. 77 | 78 | ``` 79 | getEntity(); ?> 80 | 81 |

getTitle(); ?>

82 | ``` 83 | 84 | #### Creating child blocks 85 | 86 | Coming Soon 87 | -------------------------------------------------------------------------------- /PageBuilder/Walkthrough.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Walkthrough 3 | The entirity of the Page Builders JavaScript code is located in `js/gene/bluefoot/` within this folder you will see a number of folders for the various different aspects of the page builder. 4 | 5 | - `component` - houses the various components required by the system to initialize, interact with the server side and interact with the user. 6 | - `content-type` - each content block can have a custom content block class assigned to it, the core only ships with an abstract content block class. This class handles the functionality associated with the particular content block and it's data. 7 | - `resource` - contains any 3rd party resources that are required for the system to work, this is where you'll find the numerous jQuery libraries along with other libraries used throughout the page builder. 8 | - `widget` - fields can have widgets assigned to them which can dramatically customize the functionality of the particular field, you can find out more about widgets [here](PageBuilder/Edit/Widgets.md). 9 | 10 | ### Core vs Local 11 | You'll see within a number of directories there are both core, and local folders. Core folders are reserved for the core Blue Foot development team, any customizations or additions to the system should be created in the local folder, followed by a namespace. 12 | For instance creating a new local storage component you'd create the file `component/local/namespace/localstorage.js`. 13 | 14 | If you're wanting to override a core file you're able to do this via our [plugin system](PageBuilder/Plugins.md). 15 | 16 | > You shouldn't ever modify a core file, doing so will cause your changes to be removed when the module is updated. If you believe there is a bug, or a change needs to be made to the core files which cannot be achieved through the plugin system please contact us. 17 | 18 | ### Components 19 | These are the core backbone to the page builder, they provide different crucial parts of the application. 20 | 21 | - `ajax.js` - provides an easy to use Ajax wrapper to the jQuery ajax functionality. Can easily be swapped out in preference for another library, or a core JavaScript implementation. 22 | - [`config.js`](PageBuilder/Component/Config.md) - handles the on page configuration, alongside making a request to the server to retrieve the full configuration, along with any entity data. 23 | - [`dragdrop.js`](PageBuilder/Component/DragDrop.md) - provides an interface to jQuery UI's drag, drop and sort libraries. 24 | - [`edit.js`](PageBuilder/Edit.md) - initializes and handles a user editing a content block. 25 | - [`hook.js`](PageBuilder/Hooks.md) - our pub/sub system for attaching and triggering events. 26 | - [`modal.js`](PageBuilder/Modal.md) - an alternative to browser alerts and confirms. Provides the user with helpful feedback without blocking their browsers functionality. 27 | - [`plugins.js`](PageBuilder/Plugins.md) - the initialization and running of any defined plugins. 28 | - `renderer.js` - an interface between the page builder and MustacheJS. 29 | - [`stage.js`](PageBuilder/Stage.md) - every instance of the page builder is refered to as the stage, this file handles the communication between all the other components. A new version of the inner class is initialized when a user enables blue foot. 30 | - `build.js` - handles rebuilding the stages content blocks from a stored string. 31 | - `panel.js` - builds the left handle panel, handling the rendering of content blocks and initializing the drag drop class to provide drag and drop functionality. 32 | - `save.js` - utilises the hook system to automatically build the data into a JSON object that the server side can parse, and save. 33 | - `structural.js` - handles any static structural elements that can be added on the page, this currently includes rows and columns. 34 | - [`template.js`](PageBuilder/Template.md) - provides functionality to allow users to save templates of their current page builder content, alongside reloading this. 35 | -------------------------------------------------------------------------------- /PageBuilder/Resources.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Resources 3 | Blue Foot is bundled with a number of resources that are required for various operations and user interactions within the page builder. You're welcome to call any of these as dependencies in your own widgets & plugins. 4 | 5 | These resources are located within the `resource` JS directory. They are organised into sub-folders if there are multiple resources under a similar name or type. There maybe both minified and unminfied versions of various resources bundled in the module, below we will list the unminified versions for reference. 6 | 7 | #### RequireJS - [requirejs.org](http://requirejs.org) 8 | `require.js` 9 | > This is automatically loaded globally to handle dependencies within the page builder. 10 | 11 | [Read more on Overview](PageBuilder/Overview.md#requirejs) 12 | 13 | #### jQuery - [jquery.com](http://jquery.com) 14 | `jquery-1.11.3.min.js` 15 | 16 | #### BlueFoot jQuery Extensions 17 | `jquery.bluefoot.normaliseHeights.min.js` 18 | `jquery/bluefoot-accordion/jquery.bluefoot.accordion.js` 19 | `jquery/bluefoot-normalise-heights/jquery.bluefoot.normaliseHeights.js` 20 | `jquery/bluefoot-tabs/jquery.bluefoot.tabs.js` 21 | 22 | We have built numerous jQuery extensions to provide various functionality for dynamic widgets and data. 23 | 24 | #### jQuery UI - [jqueryui.com](http://jqueryui.com) 25 | `jquery-ui/jquery-ui.min.js` 26 | 27 | We implement numerous interactions from the jQuery UI library to ensure compatibility with all browsers. This includes drag & drop and sortable. 28 | 29 | #### FancyBox 2 - [fancyapps.com/fancybox](http://fancyapps.com/fancybox/) 30 | `jquery/fancybox/jquery.fancybox.js` 31 | 32 | We use FancyBox 2 to power our lightboxes. 33 | 34 | #### Slick - [kenwheeler.github.io/slick](http://kenwheeler.github.io/slick/) 35 | `jquery/slick/slick.js` 36 | 37 | We use Slick for any carousels that are rendered within the preview view in the admin, or on the front-end. 38 | 39 | #### TagIt - [aehlke.github.io/tag-it](http://aehlke.github.io/tag-it/) 40 | `jquery/tag-it/tag-it.js` 41 | 42 | Tag it is used within the `tags.js` widget to provide better usability when entering a list of options. 43 | 44 | #### Dropzone.js - [dropzonejs.com](http://www.dropzonejs.com) 45 | `dropzone.js` 46 | 47 | Dropzone is use for any image and asset uploading within the BlueFoot system. 48 | 49 | #### HTML2Canvas - [html2canvas.hertzen.com](https://html2canvas.hertzen.com) 50 | `html2canvas.js` 51 | 52 | We render the stage into a PNG file to be stored alongside templates using HTML2Canvas. 53 | 54 | #### MustacheJS - [github.com/janl/mustache.js](https://github.com/janl/mustache.js/) 55 | `mustache.min.js` 56 | 57 | Mustache is a powerful logicless template rendering system. It allows us to declare our templates and render them using objects. 58 | 59 | ### Including your own jQuery plugin 60 | There maybe a need to include your own jQuery plugin for use within a widget or plugin. To do so you'll need to ensure that the plugin is loaded within our `bluefoot/jquery` no conflict version. This is to ensure we don't pollute any global jQuery instances with the additions the page builder system makes. 61 | 62 | Within the `plugins` section of the pagebuilder.xml you will see a number of declare jQuery plugins. 63 | ``` 64 | 65 | ... 66 | 67 | ... 68 | 69 | jquery/tag-it 70 | resource/jquery/tag-it/tag-it.min 71 | 72 | bluefoot/jquery/ui 73 | 74 | 75 | ... 76 | 77 | ... 78 | 79 | ``` 80 | As you can see above for the jQuery tag it plugin which is used within the tags widget. It declares the alias of the plugin, the path to that plugin and any depdencies that plugin has. 81 | 82 | This will be loaded into the page builder system, and then become available via the alias. 83 | 84 | So in the case above you'd put `jquery/tag-it` as a depdency within the widget or plugin you need to call it within. You'd also in this instance need to have `bluefoot/jquery/ui` and `bluefoot/jquery`. 85 | 86 | 87 | -------------------------------------------------------------------------------- /PageBuilder/Hooks.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Hooks 3 | 4 | The hook system is a pub/sub, observer/event system built directly into the core of the page builder. This enables easy extension to numerous actions a user can make whilst interacting with the page builder. 5 | 6 | You can find the hook JavaScript at `js/gene/cms/component/core/hook.js` this is the first thing that is initialized in the page builder application. It's also heavily used by the core for updating various UI elements. 7 | 8 | ### Triggering an event 9 | If you have created a widget, or custom plugin you may need the system to know you've updated something to re-trigger previews or rendering. You can do this with the following code: 10 | 11 | ``` 12 | Hook.trigger('gene-bluefoot-stage-ui-updated', false, false, this.stage); 13 | ``` 14 | When calling `Hook.trigger` there are 4 possible paramters, the first is already required. 15 | 16 | - **name**: The event you wish to trigger. 17 | - **params**: Any parameters you wish to be available to anything attached onto this event. 18 | - **completeFn**: A function to be ran once the event has been fully ran. 19 | - **origin**: The origin of the hook being trigger, it's good practice to pass the current stage into this parameter as the hook system is global. 20 | 21 | ### Attaching/observing an event 22 | If you're wanting to conduct a certain action when the system triggers a certain event you can declare an attachment onto that events name. For instance the system uses these to tweak various parts of the UI when entities are updated. 23 | 24 | ``` 25 | Hook.attach('gene-bluefoot-stage-ui-updated', function ($hook) { 26 | // Logic here 27 | $hook.done(); 28 | }.bind(this)); 29 | ``` 30 | Attaching onto an event only has two parameters, the first being the name of the event you're wanting to attach onto and the second being the function to call when the event is triggered. 31 | 32 | The complete function will be passed an instance of `$hook` for the system to behave correctly you must **always** call `$hook.done();` once your processing is finished, failure to do so could cause some very strange behaviour. 33 | 34 | > Failure to call $hook.done() could result in the page builder system failing to initialize or complete important operations. If you're building a system utilising hooks and experience an issue please ensure all your hooks are calling this once their processing has finished. 35 | 36 | #### Asynchronous callback 37 | If you need to conduct an asynchronous action (such as an Ajax request) you're able to call `$hook.done()` once that operation has completed or failed. The hook system will wait until the operation is completed, and the callback is called to run the next hook, or complete the hooks callback function. 38 | 39 | ``` 40 | Hook.attach('gene-bluefoot-stage-ui-updated', function ($hook) { 41 | var Ajax = new AjaxClass(); 42 | Ajax.post('url', {}, function (data) { 43 | // Logic here from response 44 | $hook.done(); 45 | }); 46 | }.bind(this)); 47 | ``` 48 | 49 | > Not all triggered hooks wait for the attached hooks to finish, you can determine this by seeing if the Hook.trigger implements a callback function. 50 | 51 | ### Parameters 52 | When parameters are passed during the trigger event they're available within the `$hook` object, under the `params` key. 53 | 54 | ``` 55 | Hook.trigger('example-hook', {message: 'hello'}, false, this.stage); 56 | ``` 57 | 58 | You could then access the message variable via 59 | ``` 60 | $hook.params.message; 61 | ``` 62 | 63 | ### Core hooks 64 | The core implements a number of different hooks to allow your plugin / widget to interact with many different parts of Blue Foot. 65 | 66 | - `gene-bluefoot-stage-ui-updated` 67 | - `gene-bluefoot-stage-restore-empty-text` 68 | - `gene-bluefoot-stage-updated` 69 | - `gene-bluefoot-stage-visible` 70 | - `gene-bluefoot-entity-update-previews` 71 | - `gene-bluefoot-after-edit-view` 72 | - `gene-bluefoot-after-edit-init` 73 | - `gene-bluefoot-save-configure-entity` 74 | - `gene-bluefoot-validate-form` 75 | - `gene-bluefoot-before-render-field` 76 | - `gene-bluefoot-after-render-field-*FIELD_TYPE*` 77 | - `gene-bluefoot-plugins-prepare-before` 78 | - `gene-bluefoot-plugins-prepare-paths` 79 | - `gene-bluefoot-plugins-prepare-after` 80 | - `gene-bluefoot-before-stage-init` 81 | - `gene-bluefoot-after-stage-init` 82 | - `gene-bluefoot-build-complete` 83 | - `gene-bluefoot-panel-get-config` 84 | - `gene-bluefoot-stage-save-extra` 85 | - `gene-bluefoot-get-options-*CODE*` 86 | 87 | > If you believe we should implement further hooks throughout the system please contact us and we will include these in future releases. 88 | 89 | ### Triggering your own hook 90 | We strongly suggest implementing your own hooks, so others can inject functionality into your code. 91 | 92 | #### Waiting hook 93 | You can implement a hook so that it won't run the callback functionality until all attached hooks have finished running. You can see a number of these being called in the early initializing of the page builder. 94 | 95 | Here you can see an example from `stage.js` 96 | ``` 97 | // Fire a trigger 98 | Hook.trigger('gene-bluefoot-before-stage-init', { 99 | button: jQuery(button), 100 | id: this.id, 101 | container: container 102 | }, function () { 103 | // Logic to run after hook 104 | }.bind(this), this); 105 | ``` 106 | 107 | #### Nonwaiting hook 108 | A nonwaiting hook will call the attached events, but won't wait until they're completed to continue on with the rest of the functionality. You can implement a non waiting hook by passing false in place of the callback function. 109 | 110 | Here you can see how we inform the system that the stages UI has been updated. This runs functionality to ensure the stage is being presented correctly. 111 | ``` 112 | Hook.trigger('gene-bluefoot-stage-ui-updated', false, false, this); 113 | ``` 114 | -------------------------------------------------------------------------------- /PageBuilder/Edit/Widgets.md: -------------------------------------------------------------------------------- 1 | # BlueFoot: Page Builder 2 | ## Widgets 3 | 4 | Widgets in Blue Foot allow a developer to create a new type of field within the Blue Foot page builder. This can provide extended functionality upon a field, a number of core widgets are provided by default: 5 | 6 | - Color 7 | - Date 8 | - WYSIWYG 9 | - Child Blocks 10 | - Align 11 | - Metrics 12 | - Tags 13 | - Upload 14 | 15 | Some of these are used to mimic similar fields available in core Magento, for instance the WYSIWYG field creates an instance of TinyMCE within the page builder. 16 | 17 | ### XML Configuration 18 | The system allows you to easily, and dynamically create new widgets without having to modify any core components. 19 | 20 | A widget has to be created as part of a complete Magento module. This module will contain a *genecms.xml* file. Within this file we are able to declare our widgets. The declaration in this file creates an alias within *RequireJS* to allow the system to automatically load your widget when it's assigned to a field. 21 | 22 | Here we can see the structure of the product search widget: 23 | ``` 24 | 25 | ... 26 | 27 | 28 | 29 | search/product 30 | text 31 | Blue Foot 32 | gene_cms/attribute_data_widget_product 33 | 34 | 35 | ... 36 | 37 | ``` 38 | 39 | There are 4 XML tags that have to be declared for a widget to be successfully loaded by the system. A widget doesn't need a data model, a data model should only be used if extra data is required. 40 | 41 | - **label**: The widgets name as displayed to an administrator 42 | - **alias**: The widget's alias that will be used to load this widget within the page builder 43 | - **input_type**: The default input type this widget will save as, this is important to ensure you're storing your data in the correct EAV table. 44 | - **group**: The group which this widget belongs to, this should be the company name or content app that the widget is included within. Core widgets are displayed in the Blue Foot group. 45 | - **data_model**: If the widget needs to complete any further processing to display data contained within the field it can implement a data model. This is used in a number of core widgets to load product, category and static block models. 46 | 47 | As our widget will be driven by a JavaScript file we will also need to declare a JavaScript plugin for the page builder to automatically alias. 48 | 49 | Here we have the example from the product search widget: 50 | ``` 51 | 52 | ... 53 | 54 | 55 | ... 56 | 57 | 58 | bluefoot/widget/search/product 59 | widget/core/search/product 60 | 61 | 62 | ... 63 | 64 | 65 | ... 66 | 67 | ``` 68 | 69 | Within a JavaScript plugin you need to declare two attributes: 70 | 71 | - **alias**: The alias which this file can be loaded from, in the case of all widgets this should start with `bluefoot/widget`. It should then be prepended by the alias of the widget declared earlier in the widgets section. 72 | - **path**: The actual path to the JavaScript file, in the case of a core widget the file will be located in the core folder. However you should locate your file within the local directory. You don't include the .js extension with the path. 73 | 74 | ### Other Resources 75 | If your widget requires a 3rd party library or another JavaScript file as well as your widget file you'll need to implement another entry in `plugins/js`. 76 | 77 | For instance the core upload widget has a depdency for DropzoneJs: 78 | ``` 79 | 80 | 81 | bluefoot/dropzone 82 | resource/dropzone 83 | 84 | 85 | bluefoot/widget/upload 86 | widget/core/upload 87 | 88 | 89 | ``` 90 | 91 | Our JavaScript widget file then contains a depedency for `bluefoot/dropzone` which will automatically load Dropzone into our widget. 92 | 93 | > These plugins don't currently support non-AMD compatible (RequireJS) JavaScript files. 94 | 95 | ### JavaScript 96 | Every widget has a JavaScript file that handles the functionality of the widget. This widget is responsbile to building the HTML elements, updating their values and can provide further functionality when serializing the edit form. 97 | 98 | From our XML earlier we know that the product search widget is located at `widget/core/search/product`, this file is a standard RequireJS file with a class being created within. In this instance the product widget is in a sub folder of search, however this isn't a requirement but suggested to aid in the organisation of widgets. 99 | 100 | Our actual widget file will start with RequireJS's standard define call, this will declare any dependencies that the widget has on other libraries, for instance we are requiring the configuration, jQuery and the Hook system. 101 | ``` 102 | /** 103 | * - Product.js 104 | * 105 | * @author Aidan Threadgold 106 | */ 107 | define(['bluefoot/config', 'bluefoot/jquery', 'bluefoot/hook'], function (Config, jQuery, Hook) { 108 | 109 | /** 110 | * Our Field class 111 | * 112 | * @constructor 113 | */ 114 | function InputField(field, value, edit) { 115 | this.field = field; 116 | this.value = value; 117 | this.element = false; 118 | this.entity = edit.entity; 119 | 120 | this.attachHooks(); 121 | } 122 | ``` 123 | 124 | The constructor of the class will be passed 3 different parameters. 125 | 126 | - **field** [object]: The fields information that is being rendered, this will include any information from the configuration call earlier. 127 | - **value**: The previous value for this field, if the field has different make up from a standard field the widget will need to implement logic to correctly update it's components. 128 | - **edit**: The instance of the edit class that was used to build this widget. This can be used when the widget needs to interact with other parts of Blue Foot. 129 | 130 | > ***Abstract Class***: In a future version we will implement an abstract class that can be extended and provides basic functionality for functions that are commonly implemented. 131 | 132 | The widget will then need to implement a `buildHtml` function which will return the fields HTML to be rendered into the edit form. 133 | 134 | Again using our product search as an example, we can see the widget creating various HTML elements using jQuery, assigning classes and variables: 135 | ``` 136 | /** 137 | * Build the dom element to represent this widget within the edit panel 138 | * 139 | * @returns object 140 | */ 141 | InputField.prototype.buildHtml = function () { 142 | var id = this.getId(), 143 | fakeId = this.getId() + "_autocomplete", 144 | placeholder = ''; 145 | 146 | // Get the product name for the placeholder text 147 | if (this.entity.data[this.field.code + "_product_name"]) { 148 | placeholder = this.entity.data[this.field.code + "_product_name"]; 149 | } 150 | 151 | // Build elements 152 | this.element = jQuery('
').addClass('gene-cms-search-field gene-cms-input-field'); 153 | this.element.attr("id", this.getId() + "_wrapper"); 154 | this.element.append( 155 | // Append label 156 | jQuery('