I'm very interested in the emerging trend of comments-per-paragraph systems (also called "annotations systems"), such as the ones implemented by medium.com and qz.com and i'm looking at the idea of developing one for my own.
Question: it seems they are mainly implemented via javascript, that runs through the text's html paragraphs uniquely identified by an id attribute (or, in the case of Medium, a name attribute). Does it mean their CMS actually store each paragraph as a separate entry in the database? Seems overly complex to me, but otherwise, how do they manage the fact that a paragraph can be deleted, edited or moved around in the overall text? How would the unique id be preserved if the author changes the paragraph?
How is that unique id logically structured? (post_id + position_in_post)?
Thank you for your insights...
I can't speak to the medium side, but as one of the developers for Quartz, I can give insight into how qz.com annotations work.
The annotations code is custom php code and is independent of the CMS for publishing articles (wordpress VIP). We do indeed store a reference to each paragraph as a row in the database, in order to track any updates to the article content. We call this an annotation thread and when a user saves an annotation the threadId gets stored along with the annotation.
We do not have a unique id stored on the wordpress side for each paragraph, instead we store the paragraphs relative position in that article (nodeIndex “3" and nodeSelector “p” == the third p-tag in the content body for a given article) and the javascript determines where exactly to place the annotation block. We went this route to avoid heavier customizations on the wordpress side, though depending on your CMS it may be easier to address this directly in the CMS code and add unique ids in the html before sending to the client.
Every time an update to an article is published, each paragraph in the updated article is compared against what was previously stored with the annotation threads for that article. If the position and paragraph text do not match up, it attempts to find the paragraph that is the closest match and update the row for that thread and new threads are created and deleted where appropriate. All of this is handled server side whenever changes are published to an article.
A couple of alternate implications that are also worth looking at are Gawker's Kinja text annotations (currently in use on Jalopnik) and the word-for-word annotations of rapgenius.com.
(disclaimer: I'm a factlink dev.)
I work for a company trying to allow per-paragraph (or per-phrase) commenting on arbitrary sites. Essentially, you've got two choices to identify the anchor of a comment.
Remember the structure of the page (e.g. some path from a root to a paragraph), and place comments at the same position next time.
Identify the content of the paragraph and place comments near identical or similar content next time.
Both systems have their downsides, but you pretty much need to go with option 2 if you want a robust system. Structural identification is fragile in the face of changing structure. Especially irrelevant changes such theming or the precise html tags used can significantly impact the "path". When that happens, you really can't fix it - unless you inspect the content, i.e. option (2).
Sam describes what comes down to a server-side content-based in his answer. Purely client-side content-based matching is what factlink and (IIRC) hypothesis use. Most browsers support non-standard but fast substring search in page content using either window.find or TextRange.findText. Alternatively, you could walk the DOM, which is slower but gives you the flexibility to implement (e.g.) fuzzy matching.
It may seem like client-side matching is overkill or complex, but really, it's simpler: it's a very robust way to decouple your content-management from your commenting. Neither is really simple, so decoupling those concerns can be a win.
I had created a fiddle on the same lines to demonstrate power of JQuery during a training session.
http://fiddle.jshell.net/fotuzlab/Lwhu5/
Might help as a starting point along with Sam's detailed and useful insights. You get the value of textfield in Jquery function where you can send it across to your CMS using ajax/APIs.
PS: The function is not production ready. Its only meant as a starting point. A little tweaking will make it usable.
I've recently published a post on how to do this with WordPress building on an existing plugin.
Like qz.com, I assign paragraph ids on the client and then provide that info to WordPress to store as comment meta when a new comment is created. I used hashing of the paragraph text to create the id which means that the order of paragraphs is unimportant but does mean that if a paragraph is edited then any associated comments become orphaned.
At first I thought this was an issue but thinking about it, if a reader comments on a paragraph then editing that text subsequently seems a little sneaky.
The code is freely available on GitHub if you feel like forking it and enhancing it.
There is one other wordpress plugin called "commentpress" which exist since a long time.
I use an old version of this plugin for my blog and it's work very well.
You can choose to comment per lines or per paragraphs, and ergonomics is really thinking!
A demo here:
http://futureofthebook.org/
and all the code is on github:
https://github.com/IFBook/commentpress-core
After a quick look on the code, it seems they use the second approch like #Eamon Nerbonne explains on his answer.
They parse each paragraphs to make a signature based on the first char of each words. Here is the function to do that.
In case someone comes looking in here, I've implemented a medium like functionality as a Django app.
It is open source and can be found as package on Pypi, and on github.
I used one of my other apps, blogging to allocate unique Paragraph IDs to each content object (currently we're only looking at <p> tags) and puts uses some extra internal meta data in the backend while storing it in DB (MySQL currently, but what we've done is JSONed the Blob, this method is more natively suited for a document oriented DBs). The frontend is mainly jQuery driven with REST API plugging the backend with the frontend.
I took cues from this post, but then rejected the creation of some kind of digest value from paragraph because content can change. What I wanted was to preserve the annotations as long as the paragraph was not completely over-written. In the complete over-write case, I provided for collection of the annotations in an orphaned bucket.
More in these tutorials
A legacy version of the same is running on those tutorials pages, that was the first revision. (But you won't be able to post without logging in, but you could always login using social accounts to check it out :-) )
Related
Situation:
I work for a multinational/global organization in the HR dept as Engineering Manager.
HR needs a lot of content related to Immigration, Benefits, Leaves, Disability, Transfers, New Hire Onboarding, Covid Policies, Expense Policies.
These are rendered thru documents/Knowledge bases. As you can imagine for a global corporation that is present in multiple countries this problem can get very complex soon.
Almost all of the content is in terms of text/documents that are not really structured.
Today we are using AEM as the Content Management Platform. AEM was being used in a headful manner but AEM imposed a lot of restrictions when we had to develop Applications on top of AEM
So we are going to use AEM in a headless manner and bring in all the content in content fragments so that those content fragments can be rendered on different portals (some use cases need more than 15 portals)
Questions:
Does it make sense imposing structure on these documents?
Does continuing to use AEM make sense here?
We want to enable reuse of pages : One page is rendered on multiple platforms.
We want to enable reuse of text blocks: One block of text could be used on multiple platforms.
How do we derive information such as breadcrumbs?
How do we build an information tree: e.g. article A , B , C should be shown under US-> Leaves-> Maternal leaves while D,E,F should show under Global -> Leaves -> Bearevent Leaves. That information is not going to be present in content fragments.
How do we build a site map?
How do authors discover information? If I write a content fragment - how do I manage its taxonomy?
Just in case - AEM also delivers any content as json or xml. Or, if your sling models are set up for model.json, you even get a json representation with all the context you need.
So I am not really convinced that this statement is true:
AEM imposed a lot of restrictions when we had to develop Applications
on top of AEM
I have seen projects using experience fragments combined with content fragments in "real" AEM pages. That way you can reuse and combine content parts on several levels and even make use of the multi site manager feature.
Using tags or custom metadata fields (based on a central taxonomy) will help you add information you might need to display content parts without enclosing elements. All you need is a servlet that returns all the content or experience fragments with the right tags attached.
It's hard to tell you more here without doing the complete rwquirements engineering ;-)
in AEM,
do via writing different scripts that use different selectors
do via using reference components
perhaps render breadcrumbs using page path
use a tree structure of tags and tag the items accordingly
you may want to create a custom left side authoring pane picker
The other things are more complex (site maps!) but all can be done with AEM.
You can also use AEM to do some of those things and do other ones outside of it.
I tried my best to answer it :
Does it make sense imposing structure on these documents?
Structuring document will give you more control over content, even better to strategies it. It will help in several things such as planning, searching, filtering.
Does continuing to use AEM make sense here?
I don’t know your exact business entirely however if content have more static content unlike real time websites live update in data then it will help surly.
in addition, CMS market AEM mold good in compare with other CMS such as Sitecore. others CMS using databases whereas AEM content repository. it is debatable which is good
We want to enable reuse of pages : One page is rendered on multiple platforms.
if you are saying pages means it an HTML experience division of page. AEM has good feature of experience Fragment. Yes, there is challenges but still this will fit efficiently
We want to enable reuse of text blocks: One block of text could be used on multiple platforms.
Here also experience fragment can be a good fit, make as many variants as possible you want and reuse it
How do we derive information such as breadcrumbs?
I do not know exact wanting here but I would say implement multiple breadcrumbs for small segments or can implement custom breadcrumbs to target content small segments accordingly. Here if you content is well designed then breadcrumbs will not be real challenge
How do we build an information tree: e.g. article A , B , C should be shown under US-> Leaves-> Maternal leaves while D,E,F should show under Global -> Leaves -> Bearevent Leaves. That information is not going to be present in content fragments.
You can also manage it through Template and restrict the template in a way that page will be created under certain tree. In other way, make taxonomy in such a way it creates structure you have given for example parent page (HR work, Engineering) for each and every business unit its ok to have redundant content, use MSM feature also tag them meaningful way.
How do we build a site map?
As in breadcrumbs, you can also build sitemaps for small segments such as one for HR/US and Engineering/US render them individual or together it does not matter. It will be still well design sitemap
How do authors discover information? If I write a content fragment - how do I manage its taxonomy?
Either to make folder structure in certain way or make variants and use tagging framework
To conclude - No product will be 100% fit for any requirement, it’s just you have to use the product in such a way it will be more and more suitable for your requirement.
Good luck!
The more I am going into the depths of structured data makeup, the more complex and detailed it seems to become. One could even markup areas of the page like footer, header, sidebar, single menu elements etc., I guess a page could easily consist of 80% schema markup and 20% content when taken too seriously. :)
Is it really doing any good to add more than a rough markup skeleton (WebPage or Article) to the potentially hundreds of actual content pages of a website, and shouldn't one only include full author information along with business opening times, contact details etc. on a dedicated contact/business information page? I'm concerned about the bloat. Which kind of markup is recommended for certain types of pages and which of it can be left out because a search engine would compile the information from other parts of the website anyway?
If you only care about user-visible search result features in big seach engine services (e.g., Bing, Google Search, Yahoo! Search and Yandex, which all happen to sponsor Schema.org), the answer is easy: Provide what search engines document to recognize.
Are these user-visible search result features the only things search engines "do" with Schema.org structured data? Probably not. They’ll likely use structured data to better understand page content, and most likely to analyze what other features they could offer in the future. See for example Dan Brickley’s (he is Google’s Schema.org representative) posting about this. But all this is typically not documented by the search engines, of course. So if you care about this, too, the answer would be: Provide what is conceivable to be useful for search engines.
Are search engines the only consumers interested in Schema.org structured data? No, there are countless other consumers (services as well as tools). Enter the world of the Semantic Web and Linked Data. If you know and care about a consumer, the answer is easy again: Provide what this consumer documents to support. But you can’t know them all, of course. So if you care about all these (known and unknown, currently existing and still to appear) consumers, the answer would be: Provide what is conceivable to be useful for all consumers. Or, because the interest of these consumers varies widely, even: Provide what you can.
That said, there are certainly Schema.org types which are rarely useful to provide. A good example are the WebPageElement types, which, as you mentioned, can get used for page areas (header, footer, navigation, sidebar etc.). In my opinion, a typical web page shouldn’t provide these types.
If you care about file sizes, you’ll want to use Microdata/RDFa (because these syntaxes allow you to annotate existing content) instead of JSON-LD (because this syntax requires you to duplicate the content). With RDFa you’ll probably even save slightly more compared to Microdata.
However, structured data typically only represents a fraction of the markup/content anyway, even if you provide as much data as possible.
Instead of repeating "background information" on every page (for example, the full data about the business), you can make use of references: you define a URI for your business (or every other thing) on the page where you fully describe it, and use this URI as property value where applicable on other pages. This is possible with #id (JSON-LD, see an example), itemid (Microdata), and resource (RDFa). The only reason not do this is possibly lacking consumer support for such references (depending on the consumer / the use case, they might not get followed). A middle way might be to provide the item (about the business or any other thing) on every page, once with the full data, and in all other cases with a limited set of data (ideally what is visible on the page, or what is needed for a specific consumer). The URI gets used as identifier for each item, conveying that all these items are about the same thing.
This is pretty wide question, but I'm hoping to get a push in the right direction (technologies and methodology).
Ok, I have an iphone app (which I am developing) that works with a web service (c#) through http requests. The web service connects to the underlying database, extracts the necessary data depending on the request and feeds it back to the application.
Now, I need to implement a search system in the app. The user searches for some words, and I need to provide the most relevant results. The search must be performed on different tables in the database. Each table can be searched in a number of columns. For example, when searching through the people table I need to search in the first name, lastname, company, and other fields. Other tables have other important columns.
I have so many questions that I don't even know where to start.
How do I make my sql queries to make the search, but still be fast enough. Do I need to make some extra tables with indexed content somehow?
How should I add relevance factor to the results so I can ultimately filter only the most relevant results? For example, if an user searches for Smith, maybe there is a person named Smith or even a Company. They should be displayed before any other content that can have smith in the description.
I know the question is a little vague/wide but I can explain more if somebody desires.
Thank you
This kind of depends on which language/rdbms you are using on your server. You might checkout various DB search solutions like Sphinx which will do all of that indexing for you and provide a simple Search API. Sphinx for example allows you to prioritize columns, define character mappings (ß->s, ä->a) etc.
In the end I have decided to use Lucene. It's a wonderful piece of technology and even if I had some doubts in the beginning, after reading 3/4 of the book called "Lucene in Action" it was clear to me that it had everything I needed (and much more).
I know it's not a fully-functional searching system (with all the elements needed), but merely a library handling the core of a search system. It will need some work to integrate it with my application/webservice/database. I will let you know how it goes :)
Thanks for your input!
I am bouncing around the idea of creating a custom document versioning system to use on business rule manuals. These manuals are broken up into outlined sections which contain one rule per section which are outlined in various ways (1.1, 1.2, etc). There are many manuals which contain the same rule for different locations in the country (down to the state/county level), however many locations will have different versions of the rules depending on business needs or whatnot.
My thought is to create a system which will manage versions of each section/rule separately. This would make the management of this mess much easier to maintain (think hundreds of manuals times hundreds of rules), and it would make fielding query requests from management much quicker.
Ok, it's a fairly easy and straightforward design to this point. Now for the monkey wrench. These rules are regulated by government agencies, so they must be submitted to and approved by state agencies. In doing this, many states require only the exact pages which are updated for each request to be submitted for approval. Once they are approved, these pages will get a new effective date and the rest of the manual will remain the same. There are business reasons for this process.
So my choice of document format has to allow for flowing layout much like Word, however I need to be able to programatically determine the page range of these sections and if changes or additions will cause a repagination.
The most complex layout will contain only tables, headers/footers, and a table of contents. I have thought about using OOXML, but I don't see a way to determine pagination without loading Word which is something I would prefer to avoid. I could create my own pagination algorithm, but that sounds a lot like reinventing the wheel.
Can anyone offer pointers to a solution whether it is an open document format, a book, or something else? Thank you for taking the time to read this.
If you want a truly modular document, then DocBook might be worth a look. You have all the rich formatting you need but it does need a bit of work. It really depends on who's doing the authoring and what tools they're comfortable using. DocBook is a rich mark-up language and you can do anything from work in the base plain text file or look at a number of WYSIWYG editors, e.g. ArborText.
It's not Word though - which might be enough to put your authors off!
If you did go with DocBook, you would maintain each document section in a separate text file so your versioning solution would work well. DocBook can produce output in a number of formats simultaneously so you could have an HTML version, an OOXML version, and a PDF version produced from the same source. A PDF version of each changed section might be appropriate to send to government agencies for approval.
On pagination, you could make life a lot easier for yourself by not having continuous page numbers. Use section or chapter based page numbering, e.g. page I-1, I-2, ..., II-1, II-2.
I am interested in choosing a good structure for an online message board-type application. I will use SO as an example, as I think it's an example that we are all familiar with, but my question is more general; it is about how to achieve the right balance between organization and flexibility in online message boards.
The questions page is a load of random stuff. It moves quickly (some might say, too quickly) and contains a huge number of questions that I'm not interested in.
The idea, I imagine, is that we can use tags to find questions that we're interested in. However, I'm not sure that this works: you can't use tags negatively. I'm not interested in PHP or perl or web development. I want to exclude such posts. But with the tags, I can't.
Although discrete subforums are in a sense less flexible, as they generally force you to pick a category even if a question might fit into two (if SO had, say, areas for "Web Development", "Games development", "Computer Science", "Systems Programming", "Databases", etc. then sure, some people might want to post about developing of web-based games, for example) is it worth sacrificing some of that flexibility in order to make it easier to find the content that you are interested in, and hide the content that you are not interested in?
Is there any way with a pure tagging system to achieve the greater ease of use that subforums provide?
The real problem with subforums comes when you guess wrong about which topics have enough interest to get their own subforums. While some topics end up with their own vibrant subcommunities others end up as empty ghettos, with little activity or feeling of community. Topics that might flourish as occasional subjects in a larger forum end up fragmented among many subforums, none of which has the critical mass of people necessary to have an active, vibrant community.
Though I think that tagging is supperior to grouping, people tend to think hierarchically.
In general it depends on the target group for the forum.
Maybe you can go with a mixture: use tagging and later use tag groups to order to posts. Delicious uses this, for example, and I find it rather helpful.
If you're worried about the divide between specific forums and open tag-based systems, like Stack Overflow, consider making a query system that allows you to do a bit more complex queries than just the AND operator, like here on Stack Overflow.
I cannot make a query here that will give me all questions in .NET, SQL or C#, combined, and that is the biggest irritation I have with the tags. With such a query system, you can create virtual forums at least.
Other than that, I don't really have a good opinion. I like both, and I haven't yet decided which one is best.
The idea, I imagine, is that we can use tags to find questions that we're interested in. However, I'm not sure that this works: you can't use tags negatively. I'm not interested in PHP or perl or web development. I want to exclude such posts. But with the tags, I can't.
While it's currently the case that you can't use tags to hide content, it shouldn't be impossible. Using SO as an example again, there's no reason that a system similar to the ignore function on a forum couldn't be made for the tag system. By adding a right-click context menu or a small "X" link somewhere in the tag display, tags could be marked as ignored. This would also allow the current tag feature to function; Seeing everything (minus your ignore list), or clicking a tag to see only questions with that tag.
Ignored tags could be managed in your profile if you should later develop an interest in PHP or INTERCAL that you lacked before.
The real question is that of performance. In my head it's as simple as replacing a SELECT [stuff] WHERE Tag = 'buffer-overflow' with SELECT [stuff] WHERE Tag NOT IN ('php','offtopic','funny-hat-friday') but I've not put together any DB backed sites that get absolutely pounded on by thousands people.