Jump to content


Photo

Tags Fieldtype development problem


  • Please log in to reply
4 replies to this topic

#1 Rob

Rob

    Sr. Member

  • Members
  • PipPipPipPip
  • 122 posts
  • 34

  • LocationLondon, UK

Posted 22 March 2012 - 06:25 PM

I'm trying to write a FIeldtype that stores tags.

The basic idea is that it uses a standard Text Inputfield and takes the string entered, separates the values by comma and then saves each one as a tag. WHen it loads the values I preferably want the values to remain as an array of item in the page data, but be displayed as a simple comma-seperated lsit inthe InputField.

I'm extending a FieldTypeMulti but I see mto be running into some sort of problem when there is no value associated with the filed in the DB, as it displays "WireArray(0)" in the InputField.

I was originally taking the WireArray being returned from the DB and concatenating (using PHP implode() method) back into a string so the InputFIeld can display it.

I've gone round in circles and I can't work out exactly what I have t odo to successfully either:

A. Keep the data as an array from the DB, but successfully display it as a string in the InputFIeld.

OR

B. Convert the array from the DB into a simple string, and I can then re-explode it into individual tags if I want to iterate them in my template.

An extract of my FieldTypeTags code looks like this at present, although I've tried about 5 different things before this!!

public function ___sleepValue(Page $page, Field $field, $value) {
  $data = array();
  foreach(explode(',', $value) as $tag) {
   $data[] = array('data' => trim($tag));
  }
  $clean = array_filter($data, function($item) {
   return !empty($item['data']);
  });
  return $clean;
}

public function ___wakeupValue(Page $page, Field $field, $value) {
  return implode(', ', $value);
}

public function sanitizeValue(Page $page, Field $field, $value) {
  return $value;
}

I'm going absolutely mad with this. I can successfully store the tags in the DB as separate values, whcih is great for searching and doing tag cloud counts etc, but I can't get the InputField to behave properly when there is nothing stored for the field.

#2 Nico Knoll

Nico Knoll

    The Boss.

  • Members
  • PipPipPipPipPip
  • 641 posts
  • 233

  • LocationBerlin, Germany

Posted 23 March 2012 - 01:48 AM

Hey,
I don't know a solution either. But if you want it to look good you could combine it with my module: http://processwire.c...le-textboxlist/

/Nico

#3 ryan

ryan

    Hero Member

  • Administrators
  • 5,771 posts
  • 3114

  • LocationAtlanta, GA

Posted 23 March 2012 - 05:58 AM

Rob, feel free to email to me and I can try out this weekend and hopefully come up with an answer. This is one I probably need to step through the code as it runs. But If you are getting WireArray(0) somewhere, you may want to nail that back to a regular array since that is the value you want to work with. You can get a regular array by calling the getArray() method from any WireArray.

#4 Rob

Rob

    Sr. Member

  • Members
  • PipPipPipPip
  • 122 posts
  • 34

  • LocationLondon, UK

Posted 24 March 2012 - 08:10 AM

Something I really can't get my head around is that it seems liks wakeupValue() isn't being called if there is no value for a field in the DB.

The echo statement in the following code produces "Array" if there is any value in the DB and nothing at all happens (so it must be being skipped) if there is no value. This implies to me that a regular array, not a WireArray, is what is being returned. This is also supported by the fact that when I call $value->getArray() as suggested, I get an error about calling a method on a non-object.

public function ___wakeupValue(Page $page, Field $field, $value) {
		echo $value; exit;
  return implode(', ', $value->getArray());
}

Ryan - I'll email you the whole module code and perhaps you can shed some light on the issue. In the past I posted on the subject of the relationship between wakeupValue(), sleepValue() and sanitizeValue() and I'm still not clear!!

#5 ryan

ryan

    Hero Member

  • Administrators
  • 5,771 posts
  • 3114

  • LocationAtlanta, GA

Posted 25 March 2012 - 09:33 AM

Thanks Rob, got your message and will take a closer look today. Regarding the functions you mentioned:

• wakeupValue() converts a file from a basic storage type (typically an array) into it's representation in ProcessWire. Most often this is used to translate the raw value from the DB into the live value for runtime.

• sleepValue() does the opposite of wakeupValue() and translates a runtime value back to it's basic type for storage.

If you are just dealing with a simple type like an integer or a string that are represented in the database exactly how they are at runtime, then wakeupValue() and sleepValue() don't need to do anything at all (other than return the value they were given). So these functions really only come into play when the field's value has to be stored differently than it would be presented at runtime. This would be the case for anything that is presented as an object at runtime. Since an object can't just be "stored" and still have its components be searchable and sortable in a database, it needs to be translated to/from fields in a DB table. Likewise, if you are sending object field values to/from JSON/XML web services, you probably want that object represented as an array, so that it can be encoded by XML or JSON.

• sanitizeValue() is entirely unrelated to the other two functions (though you may see it called in series with them). But it does nothing other than sanitize a value that is assigned to a $page. So lets say that you have a field called 'myfield' and this API call gets executed:

$page->myfield = 'my value';

That value gets passed through the sanitizeValue() method for whatever fieldtype is used by 'myfield'. After passing through sanitizeValue() it gets set to the $page. The sanitizeValue() method is just a way to ensure that invalid data doesn't get assigned to the page. So if the fieldtype used by 'myfield' expects it to be a string, then its sanitizeValue() method should ensure that whatever it returns is a string, regardless of what it's given. Or if you want, you can have it throw an exception when it receives invalid data. But here's what a sanitizeValue() method might look like for 'myfield':

public function sanitizeValue(Page $page, Field $field, $value) {
    if(!is_string($value)) $value = (string) $value; 
    return $value; 
}





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users