jcard: Difference between revisions

From Microformats Wiki
Jump to navigation Jump to search
mNo edit summary
m (jCard schema)
 
(21 intermediate revisions by 2 users not shown)
Line 16: Line 16:
=== Authoring rules ===
=== Authoring rules ===


* The structure of a jCard follows the structure of an hCard in regard to nesting elements.
* The structure of a jCard follows the ''logical'' structure of an hCard in regard to nesting elements.
 
<pre><nowiki>
  <p class="note">You can e-mail me at <a class="email"
  href="mailto:me@example.com">me@example.com</a>.</p>
</nowiki></pre>
 
  // Correct
  {
    "note" : ["You can e-mail me at me@example.com."],
    "email" : [{ value: "me@example.com" }]
  }
 
  // Wrong
  {
    "note" : [{
      "value" : "You can e-mail me at me@example.com.",
      "email" : [{ value: "me@example.com" }]
    }]
  }
 
* All property names must be consistent with their equivalents in hCard.
* All property names must be consistent with their equivalents in hCard.
* All property names must be enclosed with quotes to allow hyphenated properties.
* All property names must be enclosed with double quotes to allow hyphenated properties.
** This is a [http://json.org JSON] syntax rule anyway. Do we really need to restate it?
* Singular instance properties use only their corresponding datatype for value:
* Singular instance properties use only their corresponding datatype for value:


   // Correct
   // Correct
   n = { givenName: 'John', familyName: 'Doe'}
   "fn" : "John Doe",
   fn = 'John Doe'
   "uid" : "http://jdoe.example.com"
    
    
   // Wrong
   // Wrong
   n = [ {givenName: 'John'}, {familyName: 'Doe'} ]
   "fn" : { "value" : "John Doe" }
   fn = {value: 'John Doe'}
   "uid" : ["http://jdoe.example.com"]


* All properties that may have multiple instances use an Array of their corresponding datatype.
* All properties that may have multiple instances use an Array of their corresponding datatype.


   // Correct
   // Correct
   nickname = ['Rio Demonhog', 'Gus Aspara']
   "nickname" : ["Rio Demonhog", "Gus Aspara"]


* Properties that are not set must be omitted.
* Properties that are not set must be omitted.


   // Correct
   // Correct
   email = [
   "email" : [
     {type: ['pref'], value: 'foo at example.com'},
     {"type" : ["pref"], "value" : "foo at example.com"},
     {value: 'bar at example.com'}
     {"value" : "bar at example.com"}
   ]
   ]


Line 45: Line 66:


   // Wrong
   // Wrong
   email = [{type: 'pref'}]
   "email" : [{"type" : "pref"}]
 
=== Open for Discussion ===


'''The following is still undecided and needs further discussion'''
'''The following is still undecided and needs further discussion'''


* a) Enclosing Arrays or Objects must NOT be reduced.
* Option a) Enclosing Arrays or Objects must NOT be reduced (favored option by the community atm).


   // Wrong
   // Wrong
   email = 'bar at example.com'
   "email" : "bar at example.com"
 
   // Correct
   // Correct
   email = [{value: 'bar at example.com'}]
   "email" : [{"value" : "bar at example.com"}]


or
* Option b) Enclosing Arrays or Objects MUST be reduced


* b) Enclosing Arrays or Objects MUST be reduced
  // Wrong
  "email" : [{"value" : "bar at example.com"}]
  "nickname" : ["Gogo Fiasco"]


   // Wrong
   // Correct
   email = [{value: 'bar at example.com'}]
   "email" : "bar at example.com"
   nickname = ['Gogo Fiasco']
  "email" : [
    {"type" : ["pref"], "value" : "foo at example.com"},
    "foobar at example.com"
  ]
   "nickname" : "Gogo Fiasco"
 
* Option c) Enclosing Arrays or Objects MAY be reduced


   // Correct
   // Correct
   email = 'bar at example.com'
   "email" : [{"value" : "bar at example.com"}]
   email = [
  "email" : "bar at example.com"
     {type: ['pref'], value: 'foo at example.com'},
   "email" : [
     'foobar at example.com'
     {"type" : ["pref'], "value" : "foo at example.com"},
     "foobar at example.com"
   ]
   ]
   nickname = 'Gogo Fiasco'
   "nickname" : ["Gogo Fiasco"]
  "nickname" : "Gogo Fiasco"


=== Field and Element Details ===
=== Field and Element Details ===


[ This section is a placeholder and should be replaced with field descriptions ]
[ This section is a placeholder and should be replaced with field descriptions ]
== Implementations ==
The author of Optimus has announced his support of jCards.
A proof-of-concept jCard web service is available (powered by Cognition) at http://srv.buzzword.org.uk/jcard/. To use it, simply append the URL of an hCard page (minus the <nowiki>"http://"</nowiki>). e.g.
http://srv.buzzword.org.uk/jcard/www.example.com/contact.html
== Javascript ==
For consistency with hCard, jCard retains hyphenated key names, such as "given-name". However, it has been remarked that for Javascript consumers, camel case terms such as givenName would be more useful, as they can be addressed as object properties rather than the keys of an associative array. The following Javascript function allows easy conversion from jCard's hyphenated key names to camel case, and back again. It is released into the public domain by its author, [[User:TobyInk|Toby Inkster]].
<pre><nowiki>
/* camelObject ($object, $reverse)
* Replaces hyphenated-keys in $object with camelCaseKeys.
* Optional second argument specifies that the reverse should happen.
* Not always round-trip safe, but good enough for jCard.
*/
function camelObject ($obj, $reverse)
{
/* Would be nice to just use regular expressions, but callbacks fail in
* all released versions of Safari so far (fixed in WebKit nightlies
* apparently).
*/
function cc ($str, $reverse)
{
if ($reverse)
{
var $rv = '';
for (var $i=0; $str[$i]; $i++)
{
if ($str[$i] == $str[$i].toUpperCase()) $rv += '-';
$rv += $str[$i];
}
return $rv.toLowerCase();
}
var $chunks = $str.split('-');
var $rv = $chunks[0];
for (var $i=1; $chunks[$i]; $i++)
$rv += $chunks[$i].charAt(0).toUpperCase() + $chunks[$i].substring(1);
return $rv;
}
if (typeof $obj == 'object' && $obj instanceof Array)
{
var $rv = new Array;
for (var $i in $obj)
$rv[$i] = camelObject($obj[$i], $reverse);
return $rv;
}
else if (typeof $obj == 'object')
{
var $rv = new Object;
for (var $key in $obj)
$rv[cc($key, $reverse)] = camelObject($obj[$key], $reverse);
return $rv;
}
return $obj;
}
/*
USAGE:
var jCard = {
  "fn" : "Toby Inkster",
  "n" : {
    "given-name" : ["Toby"],
    "family-name" : ["Inkster"]
  }
}
var camelCard = camelObject(jCard);
camelCard.n.additionalName[0] = "Andrew";
var jCardNew = camelObject(camelCard, true);
*/
</nowiki></pre>
== Criticism ==
Critics argued, that there is no need for a jCard standard. In order to preserve the semantics of microformats, the entire marked up HTML or the URI should be passed between applications. Applications should then decide by themselves on how to represent a Microformat internally.
* Say I'm writing an online address book app. I don't want to have to include hCard parsing code in the app itself. [[hcard-parsing|hCard parsing is a lot of work]] and [[principles#lowering-barriers|intentionally so]]. I don't want to re-invent the wheel. I want to simply plug in an existing parser, and take the output from that. The output from this parser should conform to an interoperable standard so that I don't need to worry about having to change my code every time I upgrade the parser, and so that I can choose to switch to a different parser altogether if need be - interoperability, avoiding vendor lock-in. vCard is not a good candidate for such an output format, as it would require a lot of parsing effort in itself. jCard can be parsed with [http://json.org widely available libraries for JSON]. [[User:TobyInk|TobyInk]]
* Further, jCard does not attempt to define how applications should represent microformats internally. It defines a JSON-based data format for representing contacts. (Much like how vCard defines a directory-based format for representing contacts, FOAF defines an RDF-based format for representing contacts, and hCard defines an HTML-based format for representing contacts.) jCard can be seen as a contact data format in itself, albeit one with a very simple mapping between it, hCard and vCard. Although a frequent use-case of jCard will be to output parsed hCards, there is nothing to stop it being used for other purposes: a vCard to jCard converter would be a simple example; or a format for sharing contact data between two arbitrary differently-structured SQL databases. [[User:TobyInk|TobyInk]] 04:03, 4 Apr 2008 (PDT)


== References ==
== References ==
* http://microjson.org/wiki/JCard - The original jCard specification at the MicroJSON Project
* [http://microjson.org/wiki/JCard MicroJSON.org] - The original jCard specification at the MicroJSON Project (as of December 2008, server seems to be down)
* http://lib.omnia-computing.de/images/JCard.png - UML Diagram of a jCard (Note the properties are not yet correct)
* [http://buzzword.org.uk/2008/jCard.schema jCard JSON Schema]
* [http://buzzword.org.uk/2008/jsonGRDDL/spec jsonGRDDL spec]

Latest revision as of 18:28, 17 December 2008

jCard 0.1

A jCard is a standardized representation of an hCard encoded in JSON.

Introduction

A jCard is a standardized representation of an hCard encoded in JSON. The primary aim of a jCard is to provide a standardized JSON output in Microformat parsers to allow for easier interchange and integration with other applications.

The term jCard was first coined by Jon Sykes und Jim Barraud of the MicroJSON project. The MicroJSON wiki was also the first to come up with a standard for this format. This standard however is incomplete and inconsistent in regards to property names and structure. The specification presented here is a completely new attempt at defining a standard representation and only borrows the name from the original jCard specification at MicroJSON.org.

The specification is considered a draft. Contents are subject to change. It is provided here for reference and a basis for discussion on the mailing list.

Format

Authoring rules

  • The structure of a jCard follows the logical structure of an hCard in regard to nesting elements.
  <p class="note">You can e-mail me at <a class="email"
  href="mailto:me@example.com">me@example.com</a>.</p>
 // Correct
 {
   "note" : ["You can e-mail me at me@example.com."],
   "email" : [{ value: "me@example.com" }]
 }
 
 // Wrong
 {
   "note" : [{
     "value" : "You can e-mail me at me@example.com.",
     "email" : [{ value: "me@example.com" }]
   }]
 }
  • All property names must be consistent with their equivalents in hCard.
  • All property names must be enclosed with double quotes to allow hyphenated properties.
    • This is a JSON syntax rule anyway. Do we really need to restate it?
  • Singular instance properties use only their corresponding datatype for value:
 // Correct
 "fn" : "John Doe",
 "uid" : "http://jdoe.example.com"
 
 // Wrong
 "fn" : { "value" : "John Doe" }
 "uid" : ["http://jdoe.example.com"]
  • All properties that may have multiple instances use an Array of their corresponding datatype.
 // Correct
 "nickname" : ["Rio Demonhog", "Gus Aspara"]
  • Properties that are not set must be omitted.
 // Correct
 "email" : [
   {"type" : ["pref"], "value" : "foo at example.com"},
   {"value" : "bar at example.com"}
 ]
  • A type property must not be the only property of an Object.
 // Wrong
 "email" : [{"type" : "pref"}]

Open for Discussion

The following is still undecided and needs further discussion

  • Option a) Enclosing Arrays or Objects must NOT be reduced (favored option by the community atm).
 // Wrong
 "email" : "bar at example.com"
 
 // Correct
 "email" : [{"value" : "bar at example.com"}]
  • Option b) Enclosing Arrays or Objects MUST be reduced
 // Wrong
 "email" : [{"value" : "bar at example.com"}]
 "nickname" : ["Gogo Fiasco"]
 // Correct
 "email" : "bar at example.com"
 "email" : [
   {"type" : ["pref"], "value" : "foo at example.com"},
   "foobar at example.com"
 ]
 "nickname" : "Gogo Fiasco"
  • Option c) Enclosing Arrays or Objects MAY be reduced
 // Correct
 "email" : [{"value" : "bar at example.com"}]
 "email" : "bar at example.com"
 "email" : [
   {"type" : ["pref'], "value" : "foo at example.com"},
   "foobar at example.com"
 ]
 "nickname" : ["Gogo Fiasco"]
 "nickname" : "Gogo Fiasco"

Field and Element Details

[ This section is a placeholder and should be replaced with field descriptions ]

Implementations

The author of Optimus has announced his support of jCards.

A proof-of-concept jCard web service is available (powered by Cognition) at http://srv.buzzword.org.uk/jcard/. To use it, simply append the URL of an hCard page (minus the "http://"). e.g.

http://srv.buzzword.org.uk/jcard/www.example.com/contact.html

Javascript

For consistency with hCard, jCard retains hyphenated key names, such as "given-name". However, it has been remarked that for Javascript consumers, camel case terms such as givenName would be more useful, as they can be addressed as object properties rather than the keys of an associative array. The following Javascript function allows easy conversion from jCard's hyphenated key names to camel case, and back again. It is released into the public domain by its author, Toby Inkster.

/* camelObject ($object, $reverse)
 * Replaces hyphenated-keys in $object with camelCaseKeys.
 * Optional second argument specifies that the reverse should happen.
 * Not always round-trip safe, but good enough for jCard.
 */
function camelObject ($obj, $reverse)
{
	/* Would be nice to just use regular expressions, but callbacks fail in
	 * all released versions of Safari so far (fixed in WebKit nightlies
	 * apparently).
	 */
	function cc ($str, $reverse)
	{
		if ($reverse)
		{
			var $rv = '';
			for (var $i=0; $str[$i]; $i++)
			{
				if ($str[$i] == $str[$i].toUpperCase()) $rv += '-';
				$rv += $str[$i];
			}
			return $rv.toLowerCase();
		}
		
		var $chunks = $str.split('-');
		var $rv = $chunks[0];
		for (var $i=1; $chunks[$i]; $i++)
			$rv += $chunks[$i].charAt(0).toUpperCase() + $chunks[$i].substring(1);
		return $rv;
	}

	if (typeof $obj == 'object' && $obj instanceof Array)
	{
		var $rv = new Array;
		for (var $i in $obj)
			$rv[$i] = camelObject($obj[$i], $reverse);
		return $rv;
	}
	
	else if (typeof $obj == 'object')
	{
		var $rv = new Object;
		for (var $key in $obj)
			$rv[cc($key, $reverse)] = camelObject($obj[$key], $reverse);
		return $rv;
	}
	
	return $obj;
}

/*
USAGE:

var jCard = {
  "fn" : "Toby Inkster",
  "n" : {
    "given-name" : ["Toby"],
    "family-name" : ["Inkster"]
  }
}
var camelCard = camelObject(jCard);
camelCard.n.additionalName[0] = "Andrew";
var jCardNew = camelObject(camelCard, true);

*/

Criticism

Critics argued, that there is no need for a jCard standard. In order to preserve the semantics of microformats, the entire marked up HTML or the URI should be passed between applications. Applications should then decide by themselves on how to represent a Microformat internally.

  • Say I'm writing an online address book app. I don't want to have to include hCard parsing code in the app itself. hCard parsing is a lot of work and intentionally so. I don't want to re-invent the wheel. I want to simply plug in an existing parser, and take the output from that. The output from this parser should conform to an interoperable standard so that I don't need to worry about having to change my code every time I upgrade the parser, and so that I can choose to switch to a different parser altogether if need be - interoperability, avoiding vendor lock-in. vCard is not a good candidate for such an output format, as it would require a lot of parsing effort in itself. jCard can be parsed with widely available libraries for JSON. TobyInk
  • Further, jCard does not attempt to define how applications should represent microformats internally. It defines a JSON-based data format for representing contacts. (Much like how vCard defines a directory-based format for representing contacts, FOAF defines an RDF-based format for representing contacts, and hCard defines an HTML-based format for representing contacts.) jCard can be seen as a contact data format in itself, albeit one with a very simple mapping between it, hCard and vCard. Although a frequent use-case of jCard will be to output parsed hCards, there is nothing to stop it being used for other purposes: a vCard to jCard converter would be a simple example; or a format for sharing contact data between two arbitrary differently-structured SQL databases. TobyInk 04:03, 4 Apr 2008 (PDT)

References