Cs_recall() Doesn't Work with Child Theme

Following the Elements API Primer, I was creating a custom element and used the first suggestion here: https://theme.co/docs/element-api-primer#common-abstractions.

Unfortunately, it seems the cs_recall() function is not working for me. I’m unsure if I’m using it incorrectly (I doubt this because I copied the code from the document), or if this is a bug.

Additionally there is a mistake in the second code block linked above:

// Anywhere inside your builder function.
$my_options = cs_remember( 'my_options' );

Should Be

// Anywhere inside your builder function.
$my_options = cs_recall( 'my_options' );

Hey @amst_ws,

Thanks for posting in! To better assist you with your issue, kindly provide us access to your site so that we can check your settings. Please create a secure note with the following info:
– Link to your site
– WP login URL
– WP username
– WP password
– WP Administrator Role

To know how to create a secure note, please check this out: How The Forum Works

Best Regards.

Sure, I’ve added the account details to a secure note here. Also, here’s the code for the element:

<?php

// Register "Recent Posts Caousel"
cs_register_element( 'recent-posts-carousel', array(

  'title' => __( 'Recent Posts Carousel', '__x__' ),

  // Define some values that we want to let users customize for this element
  'values' => cs_compose_values(
    array(
      'post_count'          => cs_value( 10, 'markup', true ),
      'category'            => cs_value( '', 'markup', true ),
      'show_post_meta'      => cs_value( false, 'markup', false),
      'flickity_draggable'  => cs_value( '>1', 'markup', false ),
      'flickity_freeScroll' => cs_value( false, 'markup', false ),
      'flickity_wrapAround' => cs_value( false, 'markup', false ),
      'flickity_groupCells' => cs_value( false, 'markup', false ),
      'flickity_autoPlay'   => cs_value( true, 'markup', false )
    ),
    'omega'
  ),

  'builder' => 'recent_posts_carousel_builder_setup',

  'style' => 'recent_posts_carousel_style',

  'render' => 'recent_posts_carousel_render',

) );

// Builder Setup

function recent_posts_carousel_builder_setup() {
  return cs_compose_controls(
    array(

      // Define the control groups that will appear in the inspector navigation bar
      'control_nav' => array(
        'recent-posts-carousel'                  => __( 'Recent Posts Carousel', '__x__' ),
        'recent-posts-carousel:setup'            => __( 'Setup', '__x__' ),
        'recent-posts-carousel:carousel-options' => __( 'Carousel Options', '__x__' )
      ),

      // Define the controls that connect to our values.
      'controls' => array(

        // Setup
        array(
          'type'  => 'group',
          'label' => __( 'Setup', '__x__' ),
          'group' => 'recent-posts-carousel:setup',
          'controls' => array(

            // Setup: Post Count
            array(
              'key'   => 'post_count',
              'type'  => 'number',
              'label' => __( 'Post Count', '__x__' )
            ),

            // Setup: Category
            array(
              'key'   => 'category',
              'type'  => 'text',
              'label' => __( 'Category', '__x__' )
            ),

            // Setup: Show Post Meta
            array(
              'key'     => 'show_post_meta',
              'type'    => 'choose',
	      'label'   => __( 'Show Post Meta', '__x__' ),
	      'options' => array(
                'choices' => cs_recall( 'options_choices_off_on_bool' )
              )
            )
          )
	),

	// Carousel Options
	array(
          'type'  => 'group',
          'label' => __( 'Carousel Options', '__x__' ),
          'group' => 'recent-posts-carousel:carousel-options',
          'controls' => array(

            // Carousel Options: Draggable
            array(
              'key'     => 'flickity_draggable',
              'type'    => 'choose',
	      'label'   => __( 'Draggable', '__x__' ),
	      'options' => array(
                'choices' => array(
	  	  array( 'value' => false, 'label' => __( 'Off', '__x__' ) ),
		  array( 'value' => true,  'label' => __( 'On', '__x__' ) ),
		  array( 'value' => '>1',  'label' => __( '>1', '__x__' ) )
		)
	      )
            ),

            // Carousel Options: Free Scroll
            array(
              'key'   => 'flickity_freeScroll',
              'type'  => 'choose',
	      'label' => __( 'Free Scroll', '__x__' ),
	      'options' => array(
                'choices' => cs_recall( 'options_choices_off_on_bool' )
              )
            ),

            // Carousel Options: Wrap Around
            array(
              'key'     => 'flickity_wrapAround',
              'type'    => 'choose',
              'label'   => __( 'Wrap Around', '__x__' ),
              'options' => array(
                'choices' => cs_recall( 'options_choices_off_on_bool' )
              )
	    ),
	    // Carousel Options: Group Cells
            array(
              'key'     => 'flickity_groupCells',
              'type'    => 'choose',
              'label'   => __( 'Group Cells', '__x__' ),
              'options' => array(
                'choices' => cs_recall( 'options_choices_off_on_bool' )
              )
	    ),
	    // Carousel Options: Auto Play
            array(
              'key'     => 'flickity_autoPlay',
              'type'    => 'choose',
              'label'   => __( 'Auto Play', '__x__' ),
              'options' => array(
                'choices' => cs_recall( 'options_choices_off_on_bool' )
              )
            )
	  )
        )
      )
    ),
    cs_partial_controls( 'omega' )
  );
}


// Style Template

function recent_posts_carousel_style() {

  ob_start();

  ?>

  /*! Flickity v2.2.1
  https://flickity.metafizzy.co
  ---------------------------------------------- */

  .$_el {
    opacity: 0;
    transition: opacity 0.4s;
  }

  .$_el.is-hidden {
    display: none;
  }

  .$_el.flickity-enabled {
    opacity: 1;
    position: relative;
  }

  .$_el.flickity-enabled:focus { outline: none; }

  .$_el .flickity-viewport {
    overflow: hidden;
    position: relative;
    height: 100%;
  }

  .$_el .flickity-slider {
    position: absolute;
    width: 100%;
    height: 100%;
  }

  /* draggable */

  .$_el.flickity-enabled.is-draggable {
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
  }

  .$_el.flickity-enabled.is-draggable .flickity-viewport {
    cursor: move;
    cursor: -webkit-grab;
    cursor: grab;
  }

  .$_el.flickity-enabled.is-draggable .flickity-viewport.is-pointer-down {
    cursor: -webkit-grabbing;
    cursor: grabbing;
  }

  /* ---- flickity-button ---- */

  .$_el .flickity-button {
    position: absolute;
    background: hsla(0, 0%, 100%, 0.75);
    border: none;
    color: #333;
  }

  .$_el .flickity-button:hover {
    background: white;
    cursor: pointer;
  }

  .$_el .flickity-button:focus {
    outline: none;
    box-shadow: 0 0 0 5px #19F;
  }

  .$_el .flickity-button:active {
    opacity: 0.6;
  }

  .$_el .flickity-button:disabled {
    opacity: 0.3;
    cursor: auto;
    /* prevent disabled button from capturing pointer up event. #716 */
    pointer-events: none;
  }

  .$_el .flickity-button-icon {
    fill: currentColor;
  }

  /* ---- previous/next buttons ---- */

  .$_el .flickity-prev-next-button {
    top: 50%;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    /* vertically center */
    transform: translateY(-50%);
  }

  .$_el .flickity-prev-next-button.previous { left: 10px; }
  .$_el .flickity-prev-next-button.next { right: 10px; }
  /* right to left */
  .$_el.flickity-rtl .flickity-prev-next-button.previous {
    left: auto;
    right: 10px;
  }
  .$_el.flickity-rtl .flickity-prev-next-button.next {
    right: auto;
    left: 10px;
  }

  .$_el .flickity-prev-next-button .flickity-button-icon {
    position: absolute;
    left: 20%;
    top: 20%;
    width: 60%;
    height: 60%;
  }

  /* ---- page dots ---- */

  .$_el .flickity-page-dots {
    position: absolute;
    width: 100%;
    bottom: -25px;
    padding: 0;
    margin: 0;
    list-style: none;
    text-align: center;
    line-height: 1;
  }

  .$_el.flickity-rtl .flickity-page-dots { direction: rtl; }

  .$_el .flickity-page-dots .dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    margin: 0 8px;
    background: #333;
    border-radius: 50%;
    opacity: 0.25;
    cursor: pointer;
  }

  .$_el .flickity-page-dots .dot.is-selected {
    opacity: 1;
  }

  /* Item CSS */
  .$_el .carousel-post {
    width: 25%;
    padding: 1em;
    text-align: center;
    margin: 1.5em 0.5em;
    border-radius: 1em;
    box-shadow: 0 0 1em 0 rgba(0, 0, 0, 0.15);
  }

  .$_el .carousel-post-image {
    max-width: 150px;
    display: inline-grid;
  }

  .$_el .carousel-post-image > * {
    width: 100%;
    border-radius: 0.5em;
  }

  @media (min-width: 1200px) {
    .$_el .carousel-post {
      width: 20%;
    }
  }

  @media (max-width: 979px) {
    .$_el .carousel-post {                    
      width: 33%;     
    }
  }

  @media (max-width: 767px) {
    .$_el .carousel-post {            
      width: 50%;     
    }
  }

  @media (max-width: 480px) {
    .$_el .carousel-post {
      width: 80%;
    }
  }

  .$_el .carousel-post p {
    font-size: 87.5%;
    text-align: initial;
  }

  .$_el .carousel-post > h3 {
    line-height: 1.2;
  }

  <?php

  return ob_get_clean();

}


// Render

function recent_posts_carousel_render( $data ) {

  extract( $data );

  $atts = cs_atts( array(
    'id'    => $id,
    'class' => cs_attr_class( $mod_id, $class, 'recent-posts-carousel', 'is-hidden' )
  ));

  $the_query = new WP_Query(array(
    'no_found_rows'  => true,
    'category_name'  => "{$category}",
    'posts_per_page' => "{$post_count}"
  ));

  if ( $the_query->have_posts() ) {
    wp_enqueue_script('Flickity.min', 'https://cdn.jsdelivr.net/npm/flickity@2.2.1/dist/flickity.pkgd.min.js', array(), '2.2.1', true);
    wp_add_inline_script('Flickity.min', 'let c = document.querySelectorAll(".recent-posts-carousel"); c.forEach(function(e) { e.classList.remove("is-hidden"); e.offsetHeight; });');
    ob_start();
    ?>

    <div <?php echo($atts) ?> data-flickity='<?php echo(sprintf(
      '{"draggable": %s, "freeScroll": %s, "wrapAround": %s, "groupCells": %s, "autoPlay": %s}',
      json_encode($flickity_draggable),
      json_encode($flickity_freeScroll),
      json_encode($flickity_wrapAround),
      json_encode($flickity_groupCells),
      json_encode($flickity_autoPlay)
    )); ?>'>

    <?php
    while ( $the_query->have_posts() ) {
      $the_query->the_post();
      ?>

      <div class="carousel-post">
        <a class="carousel-post-image" href="<?php echo(get_permalink()); ?>">

        <?php if (has_post_thumbnail()):
          echo(the_post_thumbnail( 'thumbnail' ));
        else:

        ?>

          <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 64 64">
            <style type="text/css">
	      .st0{fill:#C75C5C}
	      .st1{opacity:0.2}
	      .st2{fill:#231F20}
	      .st3{fill:#E0E0D1}
	      .st4{fill:#4F5D73}
            </style>
            <g>
              <g>
                <rect class="st0" width="64" height="64"/>
	      </g>
	      <g class="st1">
	        <path class="st2" d="M52,50c0,2.2-1.8,4-4,4H16c-2.2,0-4-1.8-4-4V22c0-2.2,1.8-4,4-4h32c2.2,0,4,1.8,4,4V50z"/>
	      </g>
	      <g>
	        <path class="st3" d="M52,48c0,2.2-1.8,4-4,4H16c-2.2,0-4-1.8-4-4V20c0-2.2,1.8-4,4-4h32c2.2,0,4,1.8,4,4V48z"/>
	      </g>
	      <g class="st1">
	        <path class="st2" d="M52,46c0,2.2-1.8,4-4,4H16c-2.2,0-4-1.8-4-4V18c0-2.2,1.8-4,4-4h32c2.2,0,4,1.8,4,4V46z"/>
	      </g>
	      <g>
	        <path class="st3" d="M52,44c0,2.2-1.8,4-4,4H16c-2.2,0-4-1.8-4-4V16c0-2.2,1.8-4,4-4h32c2.2,0,4,1.8,4,4V44z"/>
	      </g>
	      <g>
	        <rect x="16" y="24" class="st4" width="12" height="12"/>
	      </g>
	      <g>
	        <rect x="36" y="27" class="st4" width="12" height="1"/>
	      </g>
	      <g>
	        <rect x="36" y="25" class="st4" width="12" height="1"/>
	      </g>
	      <g>
	        <rect x="32" y="24" class="st4" width="3" height="4"/>
	      </g>
	      <g>
	        <rect x="32" y="30" class="st4" width="16" height="1"/>
	      </g>
	      <g>
	        <rect x="32" y="32" class="st4" width="16" height="1"/>
	      </g>
	      <g>
	        <rect x="32" y="34" class="st4" width="16" height="1"/>
	      </g>
	      <g>
	        <rect x="32" y="36" class="st4" width="16" height="1"/>
	      </g>
	      <g>
	        <rect x="35.9" y="39" class="st4" width="12.1" height="1"/>
	      </g>
	      <g>
	        <rect x="16" y="39" class="st4" width="12" height="1"/>
	      </g>
	      <g>
	        <rect x="16" y="41" class="st4" width="12" height="1"/>
	      </g>
	      <g>
	        <rect x="16" y="43" class="st4" width="12" height="1"/>
	      </g>
	      <g>
	        <rect x="16" y="45" class="st4" width="12" height="1"/>
	      </g>
	      <g>
	        <rect x="32" y="41" class="st4" width="16" height="1"/>
	      </g>
	      <g>
	        <rect x="32" y="43" class="st4" width="16" height="1"/>
	      </g>
	      <g>
	        <rect x="32" y="45" class="st4" width="16" height="1"/>
	      </g>
	      <g>
	        <circle class="st3" cx="24" cy="28" r="2"/>
	      </g>
	      <g>
	        <rect x="16" y="16" class="st4" width="32" height="4"/>
	      </g>
	      <g>
	        <g>
	          <path class="st3" d="M27,35v-2.4l-0.8-0.8c-0.5-0.5-1.3-0.5-1.8,0l-0.8,0.8l-1.9-1.9c-1-1-2.6-1-3.5,0L17,31.9V35H27z"/>
	        </g>
	      </g>
            </g>
          </svg>

        <?php endif; ?>
        </a>

	<h3 class="h5 mts"><a href="<?php echo(get_permalink()); ?>"><?php echo(get_the_title()); ?></a></h3>
        <?php echo(the_excerpt()); ?>
      </div>

    <?php

    }

    echo('</div>');
  }

  wp_reset_postdata();
  return ob_get_clean();
}

Hello @amst_ws,

Thanks for updating in! Please be advised that the Element API cannot be added in the child theme’s functions.php. You must create it in a separate folder and install it to the site as a plugin. You should be seeing your custom plugin element in the Plugins section. Once it is active, it should word with the editor as a new custom element. Kindly use the Sample Element plugin to get your started with:

Best Regards.

Unfortunately, it also doesn’t work as a plugin. Using as a mu-plugin, a normal, plugin, or including it with the child theme yields the same results.

When using

'options' => array(
   'choices' => cs_recall( 'options_choices_off_on_bool' )
)

it shows image

But, when using

'options' => array(
  'choices' => array(
    array( 'value' => false, 'label' => __( 'Off', '__x__' ) ),
    array( 'value' => true,  'label' => __( 'On', '__x__' ) )
  )
)

it shows image

Hello @amst_ws,

Can you please allow file editing so that we can view your code via Appearance > Theme Editor or in Plugins > Plugin Editor? To do that, kindly check this out:

Thank you in advance.

I’ve enabled it.

Hey @amst_ws,

Please tell us what options you would like to remember so maybe we can give you an example.

Checking your code, you currently haven’t set any options to be remembered. The Element API Primer doc and looking at the usage in the core, you must “call” the options “in memory (remembered)”.

Also mentioned in the doc, take a look at how cs_remember is being used in the registry-setup.php file located in \themes\pro\cornerstone\includes\elements and how cs_recall is used in a lot of element options like in anchor.php in \pro\cornerstone\includes\elements\control-partials.

Remember is storing the options in memory so it’s ready to be recalled.
Recall is taking/using the options in memory.

Hope that helps.

Hi there,

I wanted to chime in with a thought that may help here. It’s important that the element is registered in this hook: cs_register_elements

By that point, all the native elements and their dependencies (registry data, partials, etc.) will have already loaded. That way if you want to use cs_recall on things already stored for native elements it will be available. If your code runs in that hook it shouldn’t matter if you’re including it from a child theme, plugin, or MU plugin.

This is, unfortunately, the issue I’m trying to report.

My element is being registered using the correct hook, however, I cannot use cs_recall to recall any of the native options.

Hi @amst_ws,

As @christian said, we don’t see the cs_remember in your code that’s the reason why your cs_recall is not working properly. Please review everything in our docs on how to properly use the element API primer.

Hope that helps.

Thank you.

Okay, I was under the impression that I would be able to use cs_recall on things the native options. Thanks.

Hi @amst_ws,

Glad that we are able to clarify it.

Thanks

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