Support

Account

Home Forums Backend Issues (wp-admin) ACF Field using WYSIWYG Editor

Solving

ACF Field using WYSIWYG Editor

  • I found a cool filter that removes buttons from the TinyMCE editor in WYSIWYG fields. I wonder if there’s a way to create a ul or ol field by removing all buttons except the ul or ol button. I tried this but the user still needs to click the ul button to change the markup. They can also uncheck the button and write paragraph text which defeats the purpose of this field. Is there a way to force the ul button to be activated by default and not deactivated? I could then hide the toolbar completely from view.

    I typically use the repeater field for things lists like recipes ingredients but it’s tedious as you have to paste/type each ingredient individually. A ul field would mean you could paste all ingredients at once. Hope this makes sense but ask me any questions to make it more clear.

    
    // ACF - Customize WYSIWYG Editor Tiny MCE Toolbar
    // https://www.advancedcustomfields.com/resources/customize-the-wysiwyg-toolbars/
    add_filter( 'acf/fields/wysiwyg/toolbars' , 'my_toolbars'  );
    function my_toolbars( $toolbars ) {
    	// Add a new toolbar called "Very Simple"
    	// - this toolbar has only 1 row of buttons
    	$toolbars['List' ] = array();
    	$toolbars['List' ][1] = array('bullist');
    
    	// Edit the "Full" toolbar and remove 'code'
    	// - delete from array code from http://stackoverflow.com/questions/7225070/php-array-delete-by-value-not-key
    	if( ($key = array_search('code' , $toolbars['Full' ][2])) !== false ) {
    	    unset( $toolbars['Full' ][2][$key] );
    	}
    
    	// remove the 'Basic' toolbar completely
    	unset( $toolbars['Basic' ] );
    
    	// return $toolbars - IMPORTANT!
    	return $toolbars;
    }
    

    Screenshot of my current test field:
    https://www.dropbox.com/s/l2aqbedpwx7wdbv/Screenshot%202018-09-24%2009.23.47.png?dl=0

  • Just a thought, could you not just use repeater fields as you have done previously but create a simple jQuery function to trigger the add row button, and then focus into the new input, upon pressing the enter key?

    *just noticed the part about not having to paste things individually, which means my advice isn’t really that helpful in this situation – sorry!

  • That would certainly improve the UI a bit over my current solution; however, it would still require the user to copy each ingredient of a recipe individually from the source document. Often a client or myself is inputting copy from a Word doc and I have to copy each ingredient and instruction step separately instead of being able to copy the entire set at once. It’s so tedious and I need to find a way to improve it. I could see this coming in handy for many other projects and could even be developed into a new field type where the user could select between UL and OL.

    I appreciate the response! Hope my reply doesn’t read too much like a rant!

  • If you really want to allow pasting all of the items at once, or this was a requirement by the client, using what is available I would choose a textarea field and I would include instructions about putting each ingredient on a new line. Very similar to how the choice settings for radio, checkbox and select fields work in ACF. I would set the formatting of the text field to “No Formatting”. I would then parse the value of the field either by getting the value and parsing it or I’d build an acf/format value filter that would do the formatting so I don’t have to re-code the parsing or call a function.

    
    add_filter ('acf/format_value/name=my_field_name', 'format_my_field_name', 20, 3);
    function format_my_field_name($value, $post_id, $field) {
      if (!$value) {
        return $value;
      }
      $array = acf_decode_choices($value);
      if (!is_array($array) || empty($array)) {
        return $value;
      }
      ob_start();
      ?>
        <ul>
          <?php 
            foreach ($array as $line) {
              ?><li><?php echo $line; ?></li><?php 
            }
          ?>
        </ul>
      <?php 
      $value = ob_get_clean();
      return $value;
    }
    
  • @hube2 Thanks so much for the advice! I just implemented that in my test environment and it works great for an individual custom field. Is there a way to make this work for nested fields in repeaters and within flexible content fields? I see in the documentation that I could filter for all textarea field types but this would be too broad.

  • For sub fields of any type, (Group, Repeater, Flex) you should use the field key instead of the field name I think.

    Also, the 3rd parameter contains the current field array for the field being formatted. You could apply the filter to all textarea fields and then you can look at the field details and on filter specific one.

    If you want to go a step further you can create your own field setting for textareas https://www.advancedcustomfields.com/resources/adding-custom-settings-fields/. Then you can filter all text area fields and check for this custom setting in the field array and do the formatting or not based on that setting.

    It may also be possible to use an acf/prepare_field filter to actually modify the formatting choices given by ACF for text area fields. I’m sure this is possible because ACF uses the same filters to display its own settings fields that we can use to alter the fields we create. However, that would take a bit of digging and testing. This one is heading off into a bit of the unknown.

  • I tried using the field key but I must have something incorrect. I tried name= type= and key= without success. I also tried all combos using the field key for the actual textarea field and the flex field key. The textarea field name is definitely ‘ingredients’.

    
    add_filter ('acf/format_value/name=field_5bc60b64aa3bd', 'format_ingredients', 20, 3);
    function format_ingredients($value, $post_id, $field) {
      if (!$value) {
        return $value;
      }
      $array = acf_decode_choices($value);
      if (!is_array($array) || empty($array)) {
        return $value;
      }
      ob_start();
      ?>
        <ul>
          <?php 
            foreach ($array as $line) {
              ?><li><?php echo $line; ?></li><?php 
            }
          ?>
        </ul>
      <?php 
      $value = ob_get_clean();
      return $value;
    }
    
  • I overlooked the problem several time myself. Had to actually test it out to find the problem. Yu have the wrong hook for using the field key. It should be

    
    add_filter ('acf/format_value/key=field_5bc60b64aa3bd', 'format_ingredients', 20, 3);
    
  • I had already tried ‘acf/format_value/key=field_5bc60b64aa3bd’ without success. I tried using the flex field key as well as the textarea subfield key. No combo works. I even refreshed the page edit screen and front end.

    Here’s an export of my flex field: https://www.dropbox.com/s/w7mbzhftxdwg22n/acf-export-2018-10-22.json?dl=0

    The textarea I’m testing with is called “Ingredients”.

  • I just tested the code with your field group and it seems to be working for me. This is my simple test:

    
    if (have_rows('content_blocks')) {
      while (have_rows('content_blocks')) {
        the_row();
        if (get_sub_field('ingredients')) {
          the_sub_field('ingredients');
        }
      }
    }
    
Viewing 10 posts - 1 through 10 (of 10 total)

You must be logged in to reply to this topic.