You can develop a Page Builder CK plugin to extend the functionnality of the interface and add your own element type. For example if you want to add an element to show a Google Map.

You will have to create the main plugin file with the needed functions :


onPagebuilderckAddItemToMenu()

This will render the item in the menu to drag and drop in the page.

	public function onPagebuilderckAddItemToMenu() {
// load the google map API (must be unique in the page)
$doc = JFactory::getDocument();
$doc->addScript("https://maps.googleapis.com/maps/api/js");
// load the language files of the plugin
$this->loadLanguage();
// create the menu item
$menuitem = new stdClass();
$menuitem->type = $this->type;
$menuitem->title = JText::_($this->context . '_MENUITEM_TITLE');
$menuitem->description = JText::_($this->context . '_MENUITEM_DESC');
$menuitem->image = JUri::root(true) . '/plugins/pagebuilderck/googlemap/assets/images/map.png';

return $menuitem;
}

Here we create an object $menuitem that will be used to create automatically the menu item in the interface.

There is also a call to the google map api script. This could also be launched in the constructor function.

 

onPagebuilderckLoadItemContent[plugin name]()

This function will return the html code to put in the interface when the user drag and drop the item. This is what will be shown in the page in edition mode.

	public function onPagebuilderckLoadItemContentGooglemap() {
// ckstyle and inner classes are needed to get the styles from the interface
$input = JFactory::getApplication()->input;
$id = $input->get('ckid', '', 'string');
?>
<div id="<?php echo $id; ?>" class="cktype" data-type="<?php echo $this->type ?>">
<div class="ckstyle">
</div>
<div class="googlemapck inner">
<img style="display:block;margin: 0 auto;" src="/<?php echo JUri::root(true); ?>/plugins/pagebuilderck/googlemap/assets/images/google_map_exemple.jpg" width="100%" height="auto" />
<div class="googlemapmarkertitleck"></div>
<div class="googlemapmarkercontentck"></div>
</div>
</div>
<?php
}

The variable "ckid" is automtically sent by the interface to be sure that there is no duplicate ID in the page. Then you can create the html structure that you want.

To use the automatic styling of the interface for the block, you must have add the "inner" css class to the html tag that is directly under the <div id="<?php echo $id; ?>" /> element and and add also the <div class="ckstyle" /> under it.

The data-type attribute is used to identify which type of element is in the page. This is needed on your main tag.

 

onPagebuilderckLoadItemOptions[plugin name]()

This will load the interface with all options to manage the item features. Mainly it will load the file "edit_[plugin name].php" located in the folder "layouts" of the plugin. But you can write the html directly into the function or call another file.

It will render what the user see when clicking on the edit button of the item.

    public function onPagebuilderckLoadItemOptionsGooglemap() {
        // load the language files of the plugin
        $this->loadLanguage();
        // load the interface for the options
        $tpl = JPATH_SITE . '/plugins/pagebuilderck/googlemap/layouts/edit_googlemap.php';
        return $tpl;
    }

Here we are just calling the "edit_googlemap" file where all options are displayed and managed. The structure of this file can be found here.

 

onPagebuilderckRenderItem[plugin name]()

This will manage the frontend rendering. You can choose to show exactly what has been created in the interface page, or to show something totally different based on the options.

If you want to render exactly the same as what is shown in the interface (for example usefull for text, image, anything what does not need to be reworked) you can use the following function :

    public function onPagebuilderckRenderItem[plugin name]($item) {
        $html = $item->innertext;

        return $html;
    }

Else you can render what you want based on the item element that is in the interface. Example with the google map, which gets the infos and then render a real map instead of the interface where there is only an image.

    public function onPagebuilderckRenderItemGooglemap($item) {
        // load the helper to help us to use the parameters
        include_once JPATH_ADMINISTRATOR . '/components/com_pagebuilderck/helpers/pagebuilderckfront.php';

        // load the google map API (must be unique in the page)
        $doc = JFactory::getDocument();
        $doc->addScript("https://maps.googleapis.com/maps/api/js");

        // ckstyle and inner classes are needed to get the styles from the interface
        $ckstyle = $item->find('.ckstyle');
        $styles = count($ckstyle) ? $ckstyle[0]->innertext : '';

        // get the content of the marker
        $content = $item->find('.googlemapmarkercontentck');
        $content = count($content) ? $content[0]->innertext : '';

        $mapattrs = $item->find('.tab_map'); // this is the tab id in the interface which contains the map options
        $params = PagebuilderckFrontHelper::createParamsFromElement($mapattrs);

        $html = '<style>
          #googlemap'.$item->attr['id'].' {
            width: ' . $params->get('mapwidth', '500px') .';
            padding-bottom: ' . $params->get('mapheight', '400px') .';
            height: 0;
            overflow: hidden;
          }
        </style>
        <div class="ckstyle">
            '. $styles . '
        </div>
        <div class="googlemapck inner">
            <div id="googlemap'.$item->attr['id'].'"></div>
        </div>
        <script>
        function ck_map'.$item->attr['id'].'_initialize() {
            var mapCanvas = document.getElementById("googlemap'.$item->attr['id'].'");
            var mapOptions = {
                center: new google.maps.LatLng(' . $params->get('latitude') . ', ' . $params->get('longitude') . '),
                zoom: ' . (int) $params->get('mapzoom', 8) . ',
                mapTypeId: google.maps.MapTypeId.ROADMAP
            }
            var map = new google.maps.Map(mapCanvas, mapOptions);
            var marker = new google.maps.Marker({
                map: map,
                position: new google.maps.LatLng(' . $params->get('latitude', '44.5403') . ', ' . $params->get('longitude', '-78.5463') . '),
                title: \'' . $params->get('markertitle', '') . '\'
            });
            if (\'' . $content . '\') {
                var infowindow = new google.maps.InfoWindow({
                    content: \'' . $content . '\'
                });
                marker.addListener(\'' . $params->get('markershowon', '') . '\', function() {
                    infowindow.open(map, marker);
                });
            }
        }
        google.maps.event.addDomListener(window, "load", ck_map'.$item->attr['id'].'_initialize());
        </script>';
        return $html;
    }

The $item variable sent to this function is a simple_html_dom element. You can find more infos on how to use here on the project page

http://simplehtmldom.sourceforge.net/

For example you can search for an element like this

$ckstyle = $item->find('.ckstyle');

and then return its content

$ckstyle[0]->innertext

 

To get the params (options set by the user in the interface) you can use this

$mapattrs = $item->find('.tab_map'); // this is the tab id in the interface which contains the map options
$params = PagebuilderckFrontHelper::createParamsFromElement($mapattrs);
$params->get('mapwidth', '500px')

First you have to know in which edition tab you have put the options (see the file "edit_googlemap.php"). Here we are looking for the "tab_map" tab which is in fact the html ID of the container element where the options are shown.

Just call the function "createParamsFromElement" to create automatically the Object from the options. Then you can get the value with the "get" function like any other Joomla! JRegistry element.

 

Here you can see the typical plugin strcuture with the files and folders. It would be good to follow this structure to have a global way to do for all plugins.