Module HasMachineTags::TagMethods

  1. lib/has_machine_tags/tag_methods.rb

Machine Tags

Machine tags, also known as triple tags, are in the format:

[namespace]:[predicate]=[value]

As explained here, a namespace and predicate must start with a letter a-z while its remaining characters can be any lowercase alphanumeric character and underscore. A value can contain any characters that normal tags use.

Wildcard Machine Tags

Wildcard machine tag syntax is used with Tag.machine_tags() and tagged_with() or find_tagged_with() of tagged objects. This syntax allows one to fetch items that fall under a group of tags, as specified by namespace, predicate, value or a combination of these ways. While this plugin supports Flickr's wildcard format, it also supports its own slightly shorter format.

Examples

For a tag ‘user:name=john’, the following wildcards would match it:

  • Wild namespace (any tag with namespace user)
    Tag.machine_tags 'user:'   # Our way
    Tag.machine_tags 'user:*=' # Flickr way
  • Wild predicate (any tag with predicate name)
    Tag.machine_tags 'name='   # Our way
    Tag.machine_tags '*:name=' # Flickr way
  • Wild predicate (any tag with value john)
    Tag.machine_tags '=john'    # Our way
    Tag.machine_tags '*:*=john' # Flickr way
  • Wild namespace and predicate (any tag with namespace user and predicate name)
    Tag.machine_tags 'user:name'  # Our way
    Tag.machine_tags 'user:name=' # Flickr way
  • Wild predicate and value (any tag with predicate name and value john)
    Tag.machine_tags 'name=john'   # Our way
    Tag.machine_tags '*:name=john' # Flickr way
  • Wild namespace and value (any tag with namespace user and value john)
    Tag.machine_tags 'user.john'   # Our way
    Tag.machine_tags 'user:*=john' # Flickr way

Food For Thought

So what’s so great about being able to give a tag a namespace and a predicate?

  • It allows for more fine-grained tag queries by giving multiple contexts:

    Say instead of having tagged with ‘user:name=john’ we had tagged with the traditional separate tags: user, name and john. How would we know that we had meant an item to be tagged as a user ie with namespace user? We wouldn’t know. Any query for ‘user’ would return all user-tagged items without context. With machine tags, we can have ‘user’ refer to a particular combination of namespace, predicate and value.

  • It keeps tag-spaces cleaner because there are more contexts:

    With traditional separate tags, tags just have a global context. So if different users decide to give different meaning to the same tag, the tag starts to become polluted and loses its usefulness. With the limitless contexts provided by machine tags, a machine tag is less likely to pollute other tags.

  • It allows tagging to serve as a medium for defining relationships between objects:

    Since a machine tag tracks three attributes (namespace, predicate and value), it’s possible to develop relationships between the attributes. This means namespaces can have many predicates and predicates can have many values. Since this closely resembles object modeling, we can start to use tagging to form relationships between tagged items and other objects.

Constants

NAMESPACE_REGEX = "[a-z](?:[a-z0-9_]+)"
PREDICATE_REGEX = "[a-z](?:[a-z0-9_-]+)"
VALUE_REGEX = '.+'
PREDICATE_DELIMITER = ':'   TODO: use delimiters in this file
VALUE_DELIMITER = '='