Re: [model] Proposal: Allow motivatedBy on SpecificResource

Hi everyone,

I work with Chris at The OpenGov Foundation, and I was chatting with him and Doug last week about the multiple bodies proposal from this thread.  Doug suggested I bring the discussion up with the group.


For context, we're allowing the public to annotate and comment on lengthy legal documents.  There can potentially be hundreds or thousands of comments and annotations on a given document, especially the longer ones.  Pragmatically, we're only going to be using two bodies ever - one to show what was annotated, and one for a comment.  I'd assume this is pretty similar to most people's use cases, where they really only care about a specific body or two.  

I hope this isn't bikeshedding, but the problem arises in the fact that the bodies are contained in a list, and not keyed in any way.  The result is that you have to filter that list down to the specific body you want to display in the given context.  This means an extra iterative loop to find the one you want, every time you show that piece of content - since you have no other way to address that data.  For us, that means an extra 20K loops or so on some documents just to show a single field.  That's less than ideal.

As a solution, I'd propose grouping bodies of a similar type/role under a single key, so end users can more directly get at this data which they need - I assume this will hold up for everyone's use cases, but I may have missed something?



In detail, here's our actual implementation:  On our site, this document: https://mymadison.io/docs/us-public-participation-playbook has annotations listed on the right side of the page. 

In practice, that means our actual Angular code looks something like this, note that we just get highlight.textContent and annotation.text directly:

<section class="annotation-list">
  <article ng-repeat="annotation in currentGroup.annotations" class="annotation">

    <blockquote>
      {{ highlight.textContent }}
    </blockquote>

    <header class="annotation-header">
      <span class="author">{{ annotation.user.display_name }}</span>
      <time pubdate class="date" datetime="{{ annotation.created_at }}">{{ annotation.created_at | timeAgo }}</time>
    </header>

    <section class="content">
      {{ annotation.text }}
    </section>
  </article>
</section>


Under the current proposal however, that becomes much more complicated:

<section class="annotation-list">
  <article ng-repeat="annotation in currentGroup.annotations" class="annotation">

    <!-- Iterating over every body. -->
    <blockquote ng-repeat="body in annotation.body">
      <!-- Filter to just the body we want -->
      <div ng-if=" body.role == 'edit' ">
        {{ body. content }}
      </div>
    </blockquote>

    <header class="annotation-header">
      <span class="author">{{ annotation.user.display_name }}</span>
      <time pubdate class="date" datetime="{{ annotation.created_at }}">{{ annotation.created_at | timeAgo }}</time>
    </header>

    <!-- Iterating over every body for the second time. -->
    <section ng-repeat="body in annotation.body" class="content">
      <!-- Filter to just the body we want -->
      <div ng-if=" body.role == 'commenting' ">
        {{ body.content }}
      </div>
    </section>
  </article>
</section>

(That's admittedly a bit pedantic, as there are filter functions in Angular - though they're just running loops like this behind the scenes.)

This would be greatly simplified, and in every way more efficient and faster for rendering, if the bodies were keyed by type in some way. This is also more directly declarative of the data itself.   I'd also recommend that keyed bodies could be singular or multiple depending on the end user's use case. 

Assuming that role is the most common filter for most users (but obviously other keys might make more sense to the group - this is just a for-example), this results in a model something like:

 {"body" : {
     "edit": { // Single object
       "@type": "oa:EmbeddedContent",
        "content":"literalcontent"
    },
    "commenting": [{ // List of objects
       "@type": "oa:SpecificResource",
       "content": "I love this thing"
    }, {
       "@type": "oa:SpecificResource",
       "content": "And here's why."
    }]
 }

Which greatly simplifies implementation, closer to what most users would expect:

<section class="annotation-list">
  <article ng-repeat="annotation in currentGroup.annotations" class="annotation">

    <!-- We know we have only one edit, so we don't iterate. -->
    <blockquote>
        {{ annotation.body.edit.content }}
    </blockquote>

    <header class="annotation-header">
      <span class="author">{{ annotation.user.display_name }}</span>
      <time pubdate class="date" datetime="{{ annotation.created_at }}">{{ annotation.created_at | timeAgo }}</time>
    </header>

    <!-- Only iterating over comments, which is all we care about here. -->
    <section ng-repeat="body in annotation.body.commenting" class="content">
        {{ body.content }}
    </section>
  </article>
</section>


Again, I may not be up to speed on all aspects of this, so please let me know if I'm off the map here.

Thanks,
-Bill


Bill Hunt
Senior Developer
OpenGov Foundation
http://opengovfoundation.org/

Received on Sunday, 5 July 2015 16:13:28 UTC