Interaction with Element API and Cornerstone CSS

Hello,

I am making a smart element that is hooking up to a DB, logic to DB is correct but I am getting weird rendering problems, second column gets squished and stretches along with the first column as opposed to staying “default” size, also at the bottom of the screen I am experiencing {%%{children(‘cs12’)}%%}{%%{children(‘cs13’)}%%} of the screen.
I have attached screenshots of what is happening as well.
This is the children issue mentioned
children

This is the column issue:


This is the code we are using for reference.

public function display_item($item) {

            ob_start();

            $thumbnail = $item->getPicture();

            if (!empty($thumbnail)) {

                $picture = "<img class='img-thumbnail' src='https://items-manager.beta.getabsolute.com/$thumbnail' />";

            }

            $prices = json_decode($item->getPrices(), true);

            ?>

            <div class = "element-display">

                <div class = "element-content">

                    <h3><?php echo $item->title; ?></h3>

                    <div><em><?php echo $item->store_description; ?></em></div>

                    <div class="prices-container">

                        <?php if (is_array($prices) && count($prices)):?>

                            <?php foreach ($prices as $price) : ?>

                                <div class = "price-list">

                                    <div class = "price-name">

                                        <?= ucwords($price['title']); ?>

                                    </div>

                                    <div class = "price-cost">

                                        $<?= number_format($price['price'], 2); ?>

                                    </div>

                                </div>

                            <?php endforeach ?>

                        <?php   endif; ?>

                    </div>

                </div>

                <div class ="smart-picture">

                    <?= $picture ?>

                </div>

            </div>

    <?php

            return ob_get_clean();

        }

    }

Here is what I am using for the smart element

<?php

use Model\Location;

use Model\Item;

use Model\Category;

class ATSMenuItemElement {

    public function __construct() {

        //add_action('cs_register_elements', [$this, 'init']);

    }

    public function init() {

        $this->register_element();

    }

    public function register_element() {

        cs_register_element('absm-shortcode-element', [

            // Define a localized title of your element and how it is labeled in the Element Library

            'title' => __('Menu Item', 'shortcode-view'),

            //Defin some values that we want to let users customize for this element

            'values' => cs_compose_values(

                [

                    'Item'         => cs_value('', 'attr', false),

                    'Location'     => cs_value('', 'attr', false),

                    'ItemSettings' => cs_value('', 'attr', false),

                    'checkbox_a'   => cs_value('', 'attr', false),

                ],

                'bg',

                'omega'

            ),

            //'builder' => 'absm_items_manager_element_builder_setup',

            'builder' => [$this, 'absm_items_manager_element_builder_setup'],

            // Connect the style template callback

            //'style' => 'absm_items_manager_element_style',

            'style' => [$this, 'absm_items_manager_element_style'],

            // Connect a function used to render this element

            //'render' => 'absm_items_manager_element_render',

            'render' => [$this, 'absm_items_manager_element_render'],

        ]);

    }

    public function absm_items_manager_element_builder_setup() {

        return cs_compose_controls(

            [

                // Define the control groups that will appear in the inspector navigation bar

                'control_nav' => [

                    'absm-manager-element'          => __('ABSM Element', 'shortcode-view'),

                    'absm-manager-element:setup'    => __('Setup', 'shortcode-view'),

                    'absm-manager-element:design'   => __('Design', 'shortcode-view')

                ],

                //Define Contorls that connect to the values

                'controls' => [

                    [

                        'type'  => 'group',

                        'label' => __('Setup', 'shortcode-view'),

                        'group' => 'absm-manager-element:setup',

                        'controls' => [

                            // Setup: Item Dropdown

                            [

                                'key'   => 'Item',

                                'type'  => 'select',

                                'label' => __('Item', 'your-text-domain'),

                                'options' => [

                                    'choices' => $this->items()

                                ]

                            ],

                            //Setup: Location Dropdown

                            [

                                'key'   => 'Location',

                                'type'  => 'select',

                                'label' => __('locations', 'your-text-domain'),

                                'options' => [

                                    'choices' => $this->locations(),

                                ]

                            ],

                            //Placeholder for now. Show price for all items?

                            [

                                'key'   => 'ItemSettings',

                                'type'  => 'select',

                                'label' => __('Item Settings', 'your-text-domain'),

                                'options'   =>  [

                                    'choices'  =>  [

                                        ['label' => 'Everything', 'value' => 'everything'],

                                        ['label' => 'Title', 'value' => 'title'],

                                        ['label' => 'Picture', 'value' => 'picture'],

                                        ['label' => 'Description', 'value' => 'description'],

                                        ['label' => 'Prices', 'value' => 'prices'],

                                    ],

                                ]

                            ],

                            //Setup: Location pricing Checkbox

                            [

                                'keys'   => [

                                    'checkbox_a'    =>  'test_value',

                                ],

                                'type'    =>  'checkbox-list',

                                'options'  =>   [

                                    'list'  =>  [

                                        [

                                            'key' => 'checkbox_a',

                                            'label' => __('Location Aware Pricing', '__x__'),

                                            'full' => true,

                                            'value' => $this->locationAwarePricing()

                                        ],

                                    ],

                                ],

                            ]

                        ],

                        // Content Margin

                        [

                            'key'   => 'content_margin',

                            'type'  => 'margin',

                            'label' => __('Content Margin', 'shortcode-view'),

                            'group' => 'absm-manager-element:design',

                        ]

                    ]

                ],

                cs_partial_controls('bg', [

                    'group'     => 'absm-manager-element:design',

                    // 'condition' => ~~~~~

                ]),

                cs_partial_controls('omega')

            ]

        );

        // return $controls;

    }

    /**

     * This GETS all the data from the items Model and establishes the Title & item Id to be

     * passed into the label/value of the Dropdown for Items list.

     */

    public function items() {

        $item_obj = new Item();

        $items = $item_obj->getAll();

        $item_display = [];

        foreach ($items as $item) {

            $item_display[] = [

                'label' => $item->getTitle(),

                'value' => $item->getItemId()

            ];

        }

        return $item_display;

    }

    /**

     * Locations function/section. Goal is to get it to filter similar to itemsValue shortcode &

     * show items by location. Look @ logic. value = items WHERE it matches in locations.

     */

    public function locations() {

        $location_obj = new Location();

        $locations = $location_obj->getAll();

        $locations_display = [];

        $locations_display[] = ['label' => 'none', 'value' => 'none'];

        foreach ($locations as $location) {

            $locations_display[] = ['label' => $location->address, 'value' => $location->id];

        }

        return $locations_display;

    }

    /**

     * Not too sure what to do w/ category yet other than Value = items WHERE it exists in categories.

     * ALL ITEMS IN CATEGORY..

     */

    public function category() {

        $category_obj = new Category();

        $categories = $category_obj->getAll();

        foreach ($categories as $category) {

            $categories_display[] = ['value' => $category->id, 'label' => $category->name];

        }

        return $categories_display;

    }

    public function absm_items_manager_element_render($data) {

        extract($data);

        $atts = cs_atts([

            'Item'         => $Item,

            'Location'     => $Location,

            'ItemSettings' => $ItemSettings,

        ]);

        $menu_shortcodes = new ABSMMenuShortcodes($with_short_codes = true);

        $item_atts = [];

        $location_atts = [];

        ob_start(); ?>

        <?php

        echo cs_get_partial_view('bg', cs_extract($data, ['bg' => '']));

        //default case

        if (isset($item_atts) && $Location === 'none') {

            switch ($ItemSettings) {

                case "everything":

                    $item_atts = shortcode_atts(

                        [

                            'id'            => $Item,

                        ],

                        $item_atts,

                    );

                    echo $menu_shortcodes->absm_item_shortcode($item_atts);

                    break;

                    // If $ItemSettings = Title

                case "title":

                    $item_atts = shortcode_atts(

                        [

                            'id'            => $Item,

                            'title'         => ''

                        ],

                        $item_atts,

                    );

                    echo $menu_shortcodes->absm_item_shortcode($item_atts);

                    break;

                    // If $ItemSettings = Picture

                case "picture":

                    $item_atts = shortcode_atts(

                        [

                            'id'            => $Item,

                            'picture'       => ''

                        ],

                        $item_atts,

                    );

                    echo $menu_shortcodes->absm_item_shortcode($item_atts);

                    break;

                    // If $ItemSettings = Description

                case "description":

                    $item_atts = shortcode_atts(

                        [

                            'id'            => $Item,

                            'description'       => ''

                        ],

                        $item_atts,

                    );

                    echo $menu_shortcodes->absm_item_shortcode($item_atts);

                    break;

                    // If $ItemSettings = Prices

                case "prices":

                    $item_atts = shortcode_atts(

                        [

                            'id'            => $Item,

                            'prices'       => ''

                        ],

                        $item_atts,

                    );

                    echo $menu_shortcodes->absm_item_shortcode($item_atts);

                    break;

            }

        } //else if:: If item exists & location is not 'none'

        elseif (isset($item_atts)) {

            pre($menu_shortcodes->absm_compare_shortcode());

            //establishes location attributes for shortcode? Not sure if necessary now

            $location_atts = shortcode_atts(

                [

                    'id'        => $Location,

                    'only_address'      => ''

                ],

                $location_atts

            );

            //if location is set & Item exists at it

            if (isset($Location) && !empty($Item)) {

                echo 'beep';

            }

            //if location is set && item does not exist

            elseif (($Location) && empty($Item)) {

                echo 'blorp';

            }

        }

        ?>

    <?php

        return ob_get_clean();

    }

    public function locationAwarePricing() {

        echo 'bing bong';

    }

    //Styling Template

    public function absm_items_manager_element_style() {

        ob_start();

    ?>

        .$_el {

        background-color: $background_color;

        margin: $content_margin;

        }

        .$_el:hover {

        background-color: $background_color_hover;

        }

<?php

        return ob_get_clean();

    }

}

add_action('cs_register_elements', function () {

    $abmsclass = new ATSMenuItemElement();

    $abmsclass->init();

});

Any assistance at all would be appreciated!

I have a feeling you need to use render_children => true, or child => true in your configuration of absm-shortcode-element. Your top level element might need that as well. Is this in Pro5? I would also try wrapping the output in a div tag if that doesn’t work. I’m missing some classes like ABSMMenuShortcodes to actually run this. $atts isn’t used on line 331 if that helps too.

Thanks so much for your help!

The child => true fixed the children showing at the bottom of the screen, one of the rendering issues that is currently happening is if I put the “menu” smart element twice in one column the entire column disappears, it comes back if I add a third. This is not in Pro5 we are using Version 6. Here is the ABSMMenuShortcodes for what you are working with

<?php

use Model\Item;

use Model\Category;

use Model\Location;

/**

 * this class provides all the short codes for building thte menes

 * Authors Tati, Ryan, Peyton, Aaron

 *

 *

 * Shortcodes

 * [item id='' store_id=''] -  Returns a single menu item

 * [category id='' store_id='' onlycategory=''] - returns an entire category list of items with title and decription

 * [location id='' onlyaddress=''] - returns an entire prebuilt menu on a single screen

 *

 * Need to deal with Store ID on things

 */

class ABSMMenuShortcodes {

    public $locations_model;

    public $category_model;

    public $item_model;

    public $items;

    public function __construct($with_short_codes = true) {

        $this->item_model = new Item();

        $this->category_model =  new Category();

        $this->locations_model = new Location();

        if ($with_short_codes) {

            add_shortcode('item', array($this, 'absm_item_shortcode'));

            add_shortcode('category', array($this, 'absm_category_shortcode'));

            add_shortcode('location', array($this, 'absm_location_shortcode'));

        }

    }

    /**

     * This function handles the rendering of menu items.

     * It can take the following parameters

     * id

     * store_id

     *

     * This is used in the other two shortcodes.

     */

    public function absm_item_shortcode($atts) {

        $atts = shortcode_atts(

            array(

                'id' => false,

                'store_id' => false,

                'title' => false,

                'picture' => false,

                'description' => false,

                'prices' => false,

            ),

            $atts

        );

        ob_start();

        if (!$atts['id'] || $atts['id'] == '') {

            return 'You must provide an Item ID Example : [item id="1"]';

        }

        $id = $atts['id'];

        $item = $this->item_model->singleQuery('item_id', $id);

        /** Just the Title */

        if ($atts['title'] !== false) {

            echo $item->getTitle();;

            return ob_get_clean();

        }

        /** Just the description */

        if ($atts['description'] !== false) {

            echo $item->getStoreDescription();;

            return ob_get_clean();

        }

        /**

         * Just picture

         */

        if ($atts['picture'] !== false) {

            $imagelink = $item->getPicture();

            if (!empty($imagelink)) {

                echo "<img class='table-image' src='https://items-manager.beta.getabsolute.com/$imagelink' />";

            }

            return ob_get_clean();

        }

        /**

         * Just Price List

         */

        if ($atts['prices'] !== false) {

            $prices = json_decode($item->getPrices(), true);

            if (is_array($prices) && count($prices)) { ?>

                <ul>

                    <?php

                    foreach ($prices as $price) {

                    ?>

                        <li><?= $price['title']; ?> : <?= '$' . number_format($price['price'], 2); ?></li>

                <?php

                    }

                } else {

                    "No Prices Found.";

                }

                ?>

                </ul>

            <?php

            return ob_get_clean();

        }

        if ($item->id === null) {

            echo '<p>No items match the shortcode provided</p>';

            return;

        }

        return $this->display_item($item);

    }

    /**

     * Renderes an entire category and its items or just the title and description

     */

    public function absm_category_shortcode($atts) {

        $atts = shortcode_atts(

            [

                'id' => false,

            ],

            $atts

        );

        if (!$atts['id']) {

            return 'You must provide an id';

        }

        $category = $this->category_model->singleQuery('cat_id', $atts['id']);

        if ($category->id === null) {

            return 'No categorys match the id provided';

        }

        $display = '';

        ob_start() ?>

            <div class="heading">

                <h2><?= $category->name ?></h2>

            </div>

            <?php

            $display .= ob_get_clean();

            foreach ($category->getItems() as $item_id) {

                $item = $this->item_model->singleQuery('item_id', $item_id);

                $display .= $this->display_item($item);

            }

            return $display;

        }

        /** Render the entire menu based on location */

        public function absm_location_shortcode($atts) {

            $atts = shortcode_atts(

                [

                    'id' => false,

                    'onlyaddress' => false

                ],

                $atts

            );

            if (!$atts['id']) {

                return 'You must provide a store_id';

            }

            $location = $this->locations_model->singleQuery('store_id', $atts['id']);

            if ($location->id === null) {

                return 'No Locations match the id provided';

            }

            $display = '';

            ob_start() ?>

            <div class="heading">

                <h2><?= $location->address ?></h2>

            </div>

            <?php

            $display .= ob_get_clean();

            foreach ($location->getItems() as $item_id) {

                $item = $this->item_model->singleQuery('item_id', $item_id);

                $display .= $this->display_item($item);

            }

            return $display;

        }

        public function absm_compare_shortcode() {

            $atts = shortcode_atts(

                [

                    'id' => false,

                    'store_id' => false,

                    'title' => false,

                    'picture' => false,

                    'description' => false,

                    'prices' => false,

                ],

                $atts

            );

            $item_shortcode = $this->absm_item_shortcode($atts);

            ats_log($item_shortcode);

            // if ($item_shortcode->locations !== null){

        }

        public function display_item($item) {

            ob_start();

            $thumbnail = $item->getPicture();

            if (!empty($thumbnail)) {

                $picture = "<img class='img-thumbnail' src='https://items-manager.beta.getabsolute.com/$thumbnail' />";

            }

            $prices = json_decode($item->getPrices(), true);

            ?>

            <div class = "element-display">

                <div class = "element-content">

                    <h3><?php echo $item->title; ?></h3>

                    <div><em><?php echo $item->store_description; ?></em></div>

                    <div class="prices-container">

                        <?php if (is_array($prices) && count($prices)):?>

                            <?php foreach ($prices as $price) : ?>

                                <div class = "price-list">

                                    <div class = "price-name">

                                        <?= ucwords($price['title']); ?>

                                    </div>

                                    <div class = "price-cost">

                                        $<?= number_format($price['price'], 2); ?>

                                    </div>

                                </div>

                            <?php endforeach ?>

                        <?php   endif; ?>

                    </div>

                </div>

                <div class ="smart-picture">

                    <?= $picture ?>

                </div>

            </div>

    <?php

            return ob_get_clean();

        }

    }

    add_action(

        'init',

        function () {

            $shortcode = new ABSMMenuShortcodes();

        }

    );

To summarize, the column squish/stretch still happens when adding the smart element I made, and when I add two of the smart elements we made in the same column the entire column disappears but comes back if a third is added. I have added the example from https://theme.co/docs/element-api-primer to test along side my element.

1 Like

Is this inside one of our columns or a custom column your creating? I’d check the HTML is actually on the page when there’s two elements in a column or if it’s a styling issuing. Does defining a raw pixel width of the column helps this?

The smart element we are working with is inside one of cornerstones columns, something new that I just found is that even though when editing in cornerstone the column disappears after adding a second custom smart element, both columns continue to show on the front end. Defining raw pixel width of the column doesnt seem to help

I think I might need to see a live example. Anything happening when WP_DEBUG is on? Is there some JS associated with this element? render_children => true on the parent element might help too.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.