lida101 http://tech.oeru.org/taxonomy/term/47 en The OERu Blog Feed Finder http://tech.oeru.org/oeru-blog-feed-finder <span class="field field--name-title field--type-string field--label-hidden">The OERu Blog Feed Finder</span> <div class="field field-node--field-blog-tags field-name-field-blog-tags field-type-entity-reference field-label-above"> <h3 class="field__label">Blog tags</h3> <div class="field__items"> <div class="field__item field__item--lida101"> <span class="field__item-wrapper"><a href="/taxonomy/term/47" hreflang="en">lida101</a></span> </div> <div class="field__item field__item--wenotes"> <span class="field__item-wrapper"><a href="/taxonomy/term/41" hreflang="en">wenotes</a></span> </div> <div class="field__item field__item--blog-feed-finder"> <span class="field__item-wrapper"><a href="/taxonomy/term/53" hreflang="en">blog feed finder</a></span> </div> <div class="field__item field__item--free--open-source"> <span class="field__item-wrapper"><a href="/taxonomy/term/6" hreflang="en">free &amp; open source</a></span> </div> <div class="field__item field__item--rss"> <span class="field__item-wrapper"><a href="/taxonomy/term/54" hreflang="en">rss</a></span> </div> <div class="field__item field__item--atom"> <span class="field__item-wrapper"><a href="/taxonomy/term/55" hreflang="en">atom</a></span> </div> <div class="field__item field__item--json"> <span class="field__item-wrapper"><a href="/taxonomy/term/56" hreflang="en">json</a></span> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">dave</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mon 15/10/2018 - 11:40</span> <div class="clearfix text-formatted field field-node--body field-name-body field-type-text-with-summary field-label-hidden"> <div class="field__items"> <div class="field__item"><p>One of the <a href="/many-simple-tools-loosely-coupled">distributed tools</a> that the <a href="https://oeru.org">OERu</a> makes available as part of its open source distributed digital learning environment is WEnotes. I've <a href="/wikieducator-notes-oerus-course-feed-aggregation-and-messaging-system">described what it is and how it works previously</a>. One of the most powerful distributed tools has also been the most complicated to achieve: the ability for learners to complete assignments and reflect on their learning journeys on their own blogs, tagging posts with relevant OERu course ids (e.g. <em>lida101</em> - see the <a href="https://course.oeru.org/lida101/interactions/course-feed/">Learning in a Digital Age 101 course feed</a> for example) and then having our blog feed scanner:</p> <ol><li>know to look at the learner's blog in a timely manner,</li> <li>identify the newly published appropriate blog post (i.e. with the relevant tag), and</li> <li>create a WEnotes message with a reference to the blog post</li> </ol><p>for the other learners participating in the course to see.</p> <p>There are a lot of moving parts in achieving this ambition, but the most unexpectedly difficult (from my perspective as a technologist) was solving the first problem: knowing how to find the learner blog feeds to monitor!</p> <h2>The mysterious blog feed</h2> <p>It turns out few people who use the web, even those who blog, are familiar with "feeds". A "<a href="https://en.wikipedia.org/wiki/Web_feed">feed</a>" is a web accessible file, adhering to a well-known and publicly defined "open standard" <em>machine readable </em>format, which summarises <em>and references</em> (links to), the content on a website, in this case a blog. Most blog platforms enable them right out-of-the-box, by default. This fact isn't widely appreciated, even among active bloggers!</p> <p>If you haven't seen a feed, here're some examples and an explanation of the two most common types: <a href="https://www.w3schools.com/XML/xml_rss.asp">RSS</a> (which stands for "Really Simple Syndication") and <a href="https://en.wikipedia.org/wiki/Atom_(Web_standard)">Atom</a>, both of which support "tagging" content.</p> <p>When we (here at the OER Foundation) first looked into offering the monitoring of learner (or educator) blogs for suitably tagged posts to include in course interaction feeds, I thought it would be a simple process of allowing learners to nominate a "Blog Feed URL" when they registered an account on our <a href="https://course.oeru.org" title="The OERu Course Site">Course Site</a>. I was quite mistaken.</p> <p>Over the course of six or so months after we made a "Blog Feed URL" field available in learner profiles, entered during the registration process, we had perhaps a hundred or so learners nominate a URL. (N.B. our model allows a learner to nominate a different blog feed URL for each course in which they're participating, allowing for the possibility that they might create a new blog site for each course. Naturally, they can nominate the <em>same</em> blog URL for multiple courses) Of those, perhaps one in 50 was an actual valid blog <em>feed</em> URL. Most were not even valid blog addresses. The most common entries were either facebook.com, google.com, a wikieducator.org user profile, or the course's own url - none of which are blogs, much less blog feeds. So this was useful market research: the market does not, in general, know what a blog is or what its feed might be, if it has one.</p> <p>Among other problems this creates is the fact that our automated feed monitoring code could not effectively sift the wheat from the chaff to find <em>valid</em> blog feeds to monitor. Clearly, a different approach was required.</p> <h2>Back to the drawing board</h2> <p>Turns out that if a learner<em> has a blog</em>, they generally know its web address. If provided clear instructions, they can fairly reliably go to it, and copy and paste the URL into a text field. So I decided to use this as a starting point for creating our "Blog Feed Finder" - a simple tool that helps us side step the issue of requiring a learner to find their blog feed URL - by finding it for them. Our approach was to provide a clear, well documented interface that embraces "<a href="http://www.instructionaldesign.org/theories/elaboration-theory/" title="A summary of elaboration theory">elaboration theory</a>", providing enough information at a glance to guide a learner, but offers further information to those who want to understand more.</p> <p>Here's what it looks like:</p> <figure role="group" class="caption caption-img"><img alt="The BFF with no blog URL entered yet. " data-entity-type="file" data-entity-uuid="b6e1d29c-ed8b-44bb-8842-e37d432f81e1" src="/sites/default/files/inline-images/bff_default_0.png" /><figcaption>Here's the default view of the BFF - you can enter your blog URL as per the instructions, or seek further instruction if you're not sure how to do that.</figcaption></figure><p>I'll copy in the URL of this very blog (and I won't even bother with the "https://" that appears at the start of it):</p> <figure role="group" class="caption caption-img"><img alt="BFF with block URL entered... " data-entity-type="file" data-entity-uuid="52be95bc-c609-4e8f-b966-04bbd4d8a2a1" src="/sites/default/files/inline-images/bff_with_blog_url_0.png" /><figcaption>The URL is pasted in. Now push the "Submit" button...</figcaption></figure><p>After a few seconds of behind-the-scenes whirring and grinding...</p> <figure role="group" class="caption caption-img"><img alt="BFF with an initial result." data-entity-type="file" data-entity-uuid="57caa975-4761-4369-bfba-71b2bde08802" src="/sites/default/files/inline-images/bff_with_result.png" /><figcaption>We have a result from the BFF. Note that the BFF also determines the type of feed, typically RSS or Atom. Some blog platforms offer both, in which case the BFF lets you choose which one to use.</figcaption></figure><p>If we want to know more about what the BFF had to do to find that blog feed, we can review its output, and even ask for more information by hovering over the info icons, fo example:</p> <figure role="group" class="caption caption-img"><img alt="Showing further elaboration of the blog feed finding process." data-entity-type="file" data-entity-uuid="da32b127-3e68-418a-8e1a-3ad8360fa218" src="/sites/default/files/inline-images/bff_with_result_and_elaboration_0.png" /><figcaption>Showing an elaborating pop-up, triggered by hovering over (or clicking on) an information icon.</figcaption></figure><p>And having found a feed, we can now update any of the courses for which we're registered to use that feed as the designated "feed to scan periodically" for blog posts tagged with the relevant course code (in brackets next to each course title, e.g. analyticsdev, lida101, mun).</p> <p>Here's what it looks like after I've replaced <em>all</em> of my blog feed associations with the new feed URL:</p> <figure role="group" class="caption caption-img"><img alt="After 'replacing' the feed URLs previously associated with my courses." data-entity-type="file" data-entity-uuid="a66ddf80-ec3b-46cf-b550-9dd4b4e1f83e" src="/sites/default/files/inline-images/bff_with_result_after_updating_all.png" /><figcaption>This is what the interface looks like after I've elected to "Replace" each of my blog feed URLs with the newly found URL.</figcaption></figure><p>And, what if, instead of tech.oeru.org, I'd mistakenly entered a URL like one of those I mentioned above? Here's how the BFF responds if someone enters, say, Facebook.com as their blog URL:</p> <figure role="group" class="caption caption-img"><img alt="BFF with the 'common accidental' blog URL message... " data-entity-type="file" data-entity-uuid="e699e2b2-9a83-4c58-bddf-a6c81ce0b1d3" src="/sites/default/files/inline-images/bff_with_common_accident_message_0.png" /><figcaption>This is what the BFF says to a learner if they mistakenly enter one of a handful of frequently entered non-blog URLs like facebook.com, google.com, or even course.oeru.org.</figcaption></figure><h2>Try it now, or adapt it! It's free (and open source)</h2> <p>Of course, you can <a href="https://course.oeru.org/blog-feed-finder" title="The OERu's Block Feed Finder. It's all open source.">try it yourself right now</a> without even needing to log in, although you get additional functionality if you're logged in an enrolled in one or more courses, like the ability to assign blog feed URLs to any courses in which you're enrolled.</p> <p>Even though we're only on our first iteration of it (any software developer will tell you: no software application is ever <em>finished</em>) our Blog Feed Finder (BFF for short) has also been <a href="http://cogdogblog.com/2018/06/better-magic-box/">assessed by others in the online learning realm</a>, who have given it a good going over and their seal of approval.</p> <p>If anyone is curious about how it works, the <a href="https://github.com/oeru/blog-feed-finder">entire source code is available</a> under the terms of the <a href="https://www.gnu.org/licenses/agpl-3.0.en.html">GNU Affero General Public License</a> (same as what's used by the Linux kernel, WordPress, Drupal, MediaWiki, and thousands of other well know free and open source projects) to make its review and reuse convenient and reliable!</p> <h2>OERu Blog Scanner is Go!</h2> <p>As of a few weeks ago, following the introduction of the BFF (and a bit of manual tidy-up of previously entered blog feed URL where OERu administrators used the BFF to find legitimate feed URLs where-ever possible) we now have a working scan which periodically checks all registered learner blog feeds and, if a suitably tagged post is found on any of them, incorporates a link to the post in the relevant course feed!</p> <p>The <a href="https://course.oeru.org/lida101/interactions/course-feed/">course interaction feed</a> (also linked above) includes some posts with a "blog" designator, which indicates they are references to blog posts which have been scanned by our WEnotes blog scanner (which is a different piece of software).</p> <h2>Loose Ends</h2> <p>As with any first iteration software release, there are quite a few known issues (a whole itemised, prioritised list, actually) we'd like to address for the next release. The first among them in the BFF's case is making the interface properly "responsive" (i.e. friendly for mobile device users)... At present, it doesn't do very well at that.</p> <p>If you have a go with the BFF and run into trouble related to the software itself, we encourage you to let us know in <a href="https://github.com/oeru/blog-feed-finder/issues">the project's Issue Queue</a>. </p> <p>Final note: we will be moving our source code repositories to a properly open source code repository (our own <a href="https://gitlab.com" title="Gitlab is an open source alternative to Github, which is not open source.">Gitlab</a> instance) in the coming weeks, so you may find you're being redirected from Github to a different site. Please don't be alarmed! It's by design.</p> </div> </div> </div> <section class="field field-node--field-blog-comments field-name-field-blog-comments field-type-comment field-label-above comment-wrapper"> <a name="comments"></a> <div class="comment-form-wrapper"> <h2 class="comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=22&amp;2=field_blog_comments&amp;3=comment" token="DjJy08iCX70uHh392eLxPjDOG3f9SoByCElo9m3CGxs"></drupal-render-placeholder> </div> </section> Sun, 14 Oct 2018 22:40:06 +0000 dave 22 at http://tech.oeru.org What is the OERu? - Pizza Thursday talk for Catalyst Christchurch http://tech.oeru.org/what-oeru-pizza-thursday-talk-catalyst-christchurch <span class="field field--name-title field--type-string field--label-hidden">What is the OERu? - Pizza Thursday talk for Catalyst Christchurch</span> <div class="field field-node--field-blog-tags field-name-field-blog-tags field-type-entity-reference field-label-above"> <h3 class="field__label">Blog tags</h3> <div class="field__items"> <div class="field__item field__item--lida101"> <span class="field__item-wrapper"><a href="/taxonomy/term/47" hreflang="en">lida101</a></span> </div> <div class="field__item field__item--oeru"> <span class="field__item-wrapper"><a href="/taxonomy/term/46" hreflang="en">oeru</a></span> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">dave</span></span> <span class="field field--name-created field--type-created field--label-hidden">Thu 23/08/2018 - 09:31</span> <div class="float-none field field-node--field-image field-name-field-image field-type-image field-label-hidden has-single"> <figure class="field-type-image__figure image-count-1 align-none"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2018-08/OERu_technology_wheel.png?itok=SujshCxP" title="The wheel of interactive technologies OERu learners can work with that will be recruited into their course feed." data-colorbox-gallery="gallery-field_image-yMLET1emlP0" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;The wheel of interactive technologies OERu learners can work with that will be recruited into their course feed.&quot;}"><img src="/sites/default/files/styles/medium/public/2018-08/OERu_technology_wheel.png?itok=c-VCQ8aT" width="220" height="152" alt="The wheel of interactive technologies OERu learners can work with that will be recruited into their course feed." typeof="foaf:Image" class="image-style-medium" /> </a> </div> </figure> </div> <div class="clearfix text-formatted field field-node--body field-name-body field-type-text-with-summary field-label-hidden"> <div class="field__items"> <div class="field__item"><p>I've been asked to speak about the OERu to my former colleagues at <a href="https://catalyst.net.nz" title="NZ's premier open source development and cloud hosting company">Catalyst IT</a>'s Christchurch office as part of their monthly "Pizza Thursday" talks. Amusingly, this talk will be on a Friday, and lunch will be curries rather than pizza :)</p> <h2>What is the OERu?</h2> <p>Last week, an <a href="https://opensource.com/article/18/8/oeru-courses">article and interview discussing exactly that</a> was published on <a href="https://opensource.com">OpenSource.com</a> which examined both the OERu and its relationship to free and open source software, which is core to the organisation's ethos. We're a "radically open" organisation... our terms of reference state that we</p> <ul><li>use exclusively openly licensed educational resources (OERs), i.e. written materials and digital artefacts that conform with the "<a href="https://freedomdefined.org/Definition">free cultural works</a>" criteria.</li> <li>we only use free and open source software for <em>everything</em> where-ever possible</li> <li>all our planning processes are conducted openly and with external participation encouraged (where-ever possible, they're streamed live and <a href="https://www.youtube.com/channel/UCCMLj7wLhiIYq_CH84D_TPg">recorded for posterity</a>, so others can see how we arrived at strategic decisions)</li> </ul><p>I work in the role of "<a href="/insight-what-does-open-source-technologist-oer-foundation-do">Open Source Technologist</a>" for the OER Foundation (a Dunedin-based charitable foundation, which in turn, is owned and formally hosted by the Otago Polytech, my official employer), who facilitate and enable the OER universitas (OERu), the global network of <a href="https://oeru.org/oeru-partners/">higher education institutions and related organsations</a> (like donors and sponsors), who are working together to meet the OERu's strategic goals. </p> <p>This is how we explain the OERu to prospective partners:</p> <p><iframe allow="autoplay; encrypted-media" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/Ia3g2qh-qjQ" width="560"></iframe></p> <p>Of course, as an educational provider, the OERu cannot make a lot of progress without "learners" (they're not "students" because that implies a contractual relationship with an institution - people choosing to learn with us can do so anonymously, without any formal relationship, so we've adopted the term "learners"). This is what the OERu looks like from a learner's perspective:<br /><iframe allow="autoplay; encrypted-media" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/F4q3CjOQARI" width="560"></iframe></p> <p>Earlier this year, we launched our "MVP", a "1st year of study" - a sequence of courses a learner can take (equivalent to a first year of undergraduate study) which, if they choose to be assessed (and meet the assessment criteria) can lead to a formal exit qualification.</p> <p>Our current "flagship" course is <a href="https://oeru.org/learning-in-a-digital-age/">Learning in a Digital Age</a>, a series of four "microcourses" which can be undertaking in a sequence or individually:</p> <ol><li><a href="https://oeru.org/oeru-partners/otago-polytechnic/digital-literacies-for-online-learning/">Digital literacies for online learning</a> (LiDA101)</li> <li><a href="https://oeru.org/oeru-partners/otago-polytechnic/digital-citizenship/">Digital citizenship</a> (LiDA102)</li> <li><a href="https://oeru.org/oeru-partners/otago-polytechnic/open-education-copyright-and-open-licensing-in-a-digital-world/">Open education, copyright and open licensing in a digital world</a> (LiDA103)</li> <li><a href="https://oeru.org/oeru-partners/otago-polytechnic/critical-media-literacies-and-associated-digital-skills/">Critical media literacies and associated digital skills</a> (LiDA104)</li> </ol><p>So, as a learner, what does a course look like? Let's have a look at <a href="https://course.oeru.org/lida101" title="Digital literacies for online learning">LiDA101</a>...</p> <p>What you see is it's a WordPress site holding all the course materials. These materials are not edited or altered by course designers within WordPress. Instead, they're created as a course outline on our collaborative OER assembly platform, <a href="https://wikieducator.org">WikiEducator</a>, an instance of the venerable MediaWiki platform (yes, it's high time for a facelift - never fear, in the works). Here's the <a href="https://wikieducator.org/Learning_in_a_digital_age/_Outline_LiDA101">course outline</a> used to build the LiDA101 course.</p> <p>You can see that the course outline is just a selection of content from elsewhere on the site, including reference materials, media objects (videos, images, audio), quizzes and assignments, and assessment rubrics. We use MediaWiki as the collaboration platform thanks to the (relatively) user-friendly and flexible version control of content it provides. (n.b. the WikiEducator site, one of the OER Foundation's main initiatives, the other being the OERu, is very heavily used by educators around the world, and <a href="https://www.alexa.com/siteinfo/wikieducator.org">hovers near the 100k sites on the web</a>).</p> <p>You'll notice the "Snapshot" button at the top of the outline - behind that button is a one line specification for a target WordPress site - clicking that button allows someone with "administrator" permissions on that site (or "sub site") to automatically push the course materials contained in that outline to the chosen WordPress site - it will be formatted as you see, with the selected branding (e.g. for our partner institutions), <em>particularly designed for use with mobile devices</em> (although that could use some refinement) which is our largest potential audience.</p> <p>Learners can access all course materials anonymously, however, if they want to <a href="https://wikieducator.org/File:OERu_technology_wheel.svg">interact with one another, and have their participation recorded</a>, they must create an account on the site.</p> <h2>OERu's FOSS Tech Stack</h2> <p>The technology stack on which the OERu is built has a few parts. We have created what we refer to as a "next generation digital learning environment" made up of a number of carefully selected free and open source tools all "<a href="/many-simple-tools-loosely-coupled">loosely coupled</a>" together (the "UNIX philosophy"), with some strategic custom glue...</p> <ul><li>educator collaboration tools (Discourse, Rocket.Chat, OnlineGroups, Jitsi Meet)</li> <li>educator collaborative course assembly tools (MediaWiki, NextCloud/CollaboraOffice, Kanboard)</li> <li>market-automation, learner instruction email tools, market research (Mautic, LimeSurvey)</li> <li>learner course sites (WordPress)</li> <li>learner assessment tools (Moodle)</li> <li>learner interaction (Mastodon, Discourse, Semantic Scuttle, Hypothes.is, other social media, learner blogs)</li> <li>learner <a href="https://course.oeru.org/lida101/interactions/course-feed/" title="An example of a course feed">interaction feed</a> (<a href="/wikieducator-notes-oerus-course-feed-aggregation-and-messaging-system">WEnotes</a>: Node.Js + Python + CouchDB + MediaWiki extensions + WordPress plugins)</li> <li>organisational info platforms (MediaWiki, Silverstripe, Drupal, Grav)</li> <li>reporting/promotional presentations (Reveal.JS)</li> <li>analytics (Matomo)</li> <li>infrastructure (Ubuntu/Debian Linux VMs/Instances, Git, Docker, Docker-Compose)</li> </ul><p>We use this website (tech.oeru.org) as a place to explain how we do what we do, and why. We include how-tos for many of the technologies we use in hopes that more organisations will start to use them inspired by our example - our underlying "enlightened self-interest" culture sees that we all fare better when we have an interest in making these tools the best they can be...</p> <h2>Why I do this</h2> <p>In my career as a technologist, I've been very aware of (and involved in activism for improving) the many problems faced by our society (and others around the world). There's one compelling, effective, and unequivocally <em>good</em> thing I've identified as a key component to all the solutions to our social ills:<strong> education</strong>. By that, I mean education (which depends on aptitude, motivation, and opportunity) from literacy to higher learning, across all of social strata, particularly for girls and women.</p> <p>As we in the OERu network build a platform for low cost higher education, we hope to create something that <em>anyone</em> can build upon, and scale up to meet the latent demand for education (globally, fewer than 10% of people ever have the opportunity to complete a tertiary qualification), providing people the <em>realistic</em> opportunity to reach their individual educational potentials. That opportunity depends only on people having access to suitable technology and Internet connectivity, both of which are spreading across the world faster than anyone could ever have imagined.</p> <p>The fact that I can do something I enjoy, have real passion for, and derive satisfaction from because it's the "right thing to do for our world" - also known as "enlightened self-interest" - with people I respect and admire (and get on with really well), means that I have found my calling and consider myself incredibly fortunate.</p> <h2>Demos</h2> <p>Time permitting, I'd be keen to show you a few of the tech things:</p> <ol><li>Demo of the WEnotes <a href="https://course.oeru.org/lida101/interactions/course-feed/">Course Feed </a>(git repos: <a href="https://bitbucket.org/wikieducator/wenotes-tools/src" title="The tools">tools</a>, <a href="https://github.com/oeru/wenotes" title="WordPress plugin and MediaWiki extension">plugins</a>, <a href="https://github.com/oeru/wenotes-docker">deployment</a>) <ol><li>The <a href="https://wikieducator.org/WENotesCompleteFeed">full noise</a></li> <li>A look at Hypothesis annotations</li> <li>A look at Mastodon</li> </ol></li> <li>A look at our <a href="https://wpms.oeru.org/blog-feed-finder">Blog Feed Finder</a> (git <a href="https://github.com/oeru/blog-feed-finder">repo</a>) which helps learners who want to submit their personal blog for scanning (to include suitably "tagged" posts in their course feed) actually find the feed and associate it with their course so our WEnotes scanner periodically checks it for new posts of interest.</li> <li>A tour of our <a href="https://mautic.oeru.org">Mautic</a> and our approach to keeping learners and partners in the loop!</li> </ol><p>I reckon many of these tools are the sort of thing Catalyst could offer as managed services commercially.</p> <p>N.B. we're not happy with Microsoft acquiring Github, and will be moving our repos from Github (and Bitbucket, too, while we're at it, because we're not overly excited to be using proprietary repos in general) to our own free and open source Git hosting as soon as possible. We will leave pointers to the new locations for these (and our many other) repos when they are created.</p> <p> </p> <p> </p> <p> </p> </div> </div> </div> <section class="field field-node--field-blog-comments field-name-field-blog-comments field-type-comment field-label-above comment-wrapper"> <a name="comments"></a> <div class="comment-form-wrapper"> <h2 class="comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=21&amp;2=field_blog_comments&amp;3=comment" token="99KWcafILHKzzimelPVVtuDa5XZ3jjZyJ2-reyAbBAI"></drupal-render-placeholder> </div> </section> Wed, 22 Aug 2018 21:31:44 +0000 dave 21 at http://tech.oeru.org WikiEducator Notes: OERu's course feed aggregation and messaging system http://tech.oeru.org/wikieducator-notes-oerus-course-feed-aggregation-and-messaging-system <span class="field field--name-title field--type-string field--label-hidden">WikiEducator Notes: OERu&#039;s course feed aggregation and messaging system</span> <div class="field field-node--field-blog-tags field-name-field-blog-tags field-type-entity-reference field-label-above"> <h3 class="field__label">Blog tags</h3> <div class="field__items"> <div class="field__item field__item--wenotes"> <span class="field__item-wrapper"><a href="/taxonomy/term/41" hreflang="en">wenotes</a></span> </div> <div class="field__item field__item--couchdb"> <span class="field__item-wrapper"><a href="/taxonomy/term/42" hreflang="en">couchdb</a></span> </div> <div class="field__item field__item--faye"> <span class="field__item-wrapper"><a href="/taxonomy/term/43" hreflang="en">faye</a></span> </div> <div class="field__item field__item--javascript"> <span class="field__item-wrapper"><a href="/taxonomy/term/44" hreflang="en">javascript</a></span> </div> <div class="field__item field__item--nodejs"> <span class="field__item-wrapper"><a href="/taxonomy/term/39" hreflang="en">node.js</a></span> </div> <div class="field__item field__item--docker"> <span class="field__item-wrapper"><a href="/taxonomy/term/16" hreflang="en">docker</a></span> </div> <div class="field__item field__item--docker-compose"> <span class="field__item-wrapper"><a href="/taxonomy/term/25" hreflang="en">docker compose</a></span> </div> <div class="field__item field__item--mastodon"> <span class="field__item-wrapper"><a href="/taxonomy/term/31" hreflang="en">mastodon</a></span> </div> <div class="field__item field__item--hypothesis"> <span class="field__item-wrapper"><a href="/taxonomy/term/45" hreflang="en">hypothesis</a></span> </div> <div class="field__item field__item--oeru"> <span class="field__item-wrapper"><a href="/taxonomy/term/46" hreflang="en">oeru</a></span> </div> <div class="field__item field__item--lida101"> <span class="field__item-wrapper"><a href="/taxonomy/term/47" hreflang="en">lida101</a></span> </div> <div class="field__item field__item--mediawiki"> <span class="field__item-wrapper"><a href="/taxonomy/term/38" hreflang="en">mediawiki</a></span> </div> <div class="field__item field__item--wikieducator"> <span class="field__item-wrapper"><a href="/taxonomy/term/34" hreflang="en">wikieducator</a></span> </div> <div class="field__item field__item--wordpress"> <span class="field__item-wrapper"><a href="/taxonomy/term/35" hreflang="en">wordpress</a></span> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">dave</span></span> <span class="field field--name-created field--type-created field--label-hidden">Thu 24/08/2017 - 09:21</span> <div class="float-none field field-node--field-image field-name-field-image field-type-image field-label-hidden has-multiple"> <figure class="field-type-image__figure image-count-1 align-none"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2017-08/WEnotes_diagram.png?itok=_aB7Lt-Y" title="A diagram describing the function of WikiEducator Notes (WEnotes)" data-colorbox-gallery="gallery-field_image-pkJCfnLgTi8" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;A diagram describing the function of WikiEducator Notes (WEnotes)&quot;}"><img src="/sites/default/files/styles/medium/public/2017-08/WEnotes_diagram.png?itok=EncLVnTc" width="174" height="220" alt="A diagram describing the function of WikiEducator Notes (WEnotes)" typeof="foaf:Image" class="image-style-medium" /> </a> </div> </figure> <figure class="field-type-image__figure image-count-2 align-none"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2017-09/WENotesPostMW.png?itok=sAdOfXNT" title="Example of a WEnotes feed and post widget on WikiEducator - MediaWiki" data-colorbox-gallery="gallery-field_image-pkJCfnLgTi8" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Example of a WEnotes feed and post widget on WikiEducator - MediaWiki&quot;}"><img src="/sites/default/files/styles/medium/public/2017-09/WENotesPostMW.png?itok=0QqAZWQf" width="220" height="182" alt="Example of a WEnotes feed and post widget on WikiEducator - MediaWiki" typeof="foaf:Image" class="image-style-medium" /> </a> </div> </figure> <figure class="field-type-image__figure image-count-3 align-none"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2017-09/WENotesPostWP.png?itok=_58SHpuz" title="Example of a WEnotes feed and post widget on Course - WordPress Multisite" data-colorbox-gallery="gallery-field_image-pkJCfnLgTi8" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Example of a WEnotes feed and post widget on Course - WordPress Multisite&quot;}"><img src="/sites/default/files/styles/medium/public/2017-09/WENotesPostWP.png?itok=QQl6B5hF" width="220" height="182" alt="Example of a WEnotes feed and post widget on Course - WordPress Multisite" typeof="foaf:Image" class="image-style-medium" /> </a> </div> </figure> </div> <div class="clearfix text-formatted field field-node--body field-name-body field-type-text-with-summary field-label-hidden"> <div class="field__items"> <div class="field__item"><p>Here at the OERu, we provide a service, attached to all of our online courses (and available to all of our partners - or anyone else for that matter) which allows anyone involved in those courses to communicate with one another from any one of a dazzling array of online "places" with WikiEducator Notes (aka WEnotes). The entire system is free and open source software (FOSS). </p> <p>The magic glue is "tags" - most social media and online systems support "tagging" in one way or another. Tools like Twitter, <a href="https://github.com/tootsuite/mastodon" title="A FOSS alternative to Twitter, but distributed rather than centralised. Ruby-on-Rails and React.js are the underlying technology.">Mastodon</a>, and G+ support "hashtags" like "#OERu" as shorthand. Other tools like blog engines (<a href="https://medium.com" title="A proprietary blogging cloud service and aggregator">Medium</a>, <a href="https://wordpress.org" title="The worlds most widely used web platform. FOSS blogging engine used by 25% of websites.">WordPress</a>, and others), forums (like <a href="https://discourse.org" title="A next generation forum engine, FOSS, built on Ruby on Rails and Ember.js for the front end.">Discourse</a>), content annotation services (like <a href="https://web.hypothes.is/" title="FOSS website annotation system - review any web page, sentence by sentence. ">Hypothesis</a>), social bookmarking services (like <a href="http://semanticscuttle.sourceforge.net/" title="The software underlying our https://bookmarks.oeru.org service">Semantic Scuttle</a>), and instant messaging services (like <a href="https://rocket.chat" title="A FOSS private messaging system built on Meteor and React.JS, with MongoDB">Rocket.Chat</a>, <a href="https://about.riot.im/" title="A FOSS React.js-based private messaging client system built on top of the Matrix (matrix.org) messaging standard and the &quot;Synapse&quot; server (Python + Twisted).">Riot</a> + <a href="https://matrix.org/docs/projects/server/synapse.html" title="The Matrix server used by the Riot messaging client. Written in Python + Twisted.">Synapse</a>, <a href="https://zulip.org" title="A FOSS private messaging service originally created by Dropbox for internal use. Written in Python with the Django framework and Electron clients.">Zulip</a>, and <a href="https://about.mattermost.com" title="A FOSS private messaging service built on Go (aka Golang)">Mattermost</a>, among others) support adding  "tags", "labels" or "categories" to any given post. WEnotes is sensitive to those tags, and thanks to the modern trend towards services providing feeds, it can happily "harvest" relevant content from all over the web, in real time (or nearly, depending on the technology).</p> <h2>How WEnotes components fit together</h2> <p>WEnotes is a collection of a significant number of separate FOSS components. See the graphical diagram of WEnotes alongside this article for an overview of the WEnotes component architecture. To provide further explanation, WEnotes is made up of several functional components:</p> <ol><li>A set of feed harvesting scripts that are part of the <a href="https://bitbucket.org/wikieducator/wenotes-tools">WEnotes-tools project</a> (written in Javascript and Python, for those interested in that sort of detail, the former ideal for those sites producing JSON feeds and real time updates, the latter our choice for periodic scans - every 10 minutes by default at the moment - of RSS and ATOM feeds)</li> <li>A central <a href="http://couchdb.apache.org/">CouchDB</a> instance, which stores all posts harvested, along with metadata like their source, a unique ID (to ensure we don't re-harvest it) and some useful info to ensure we can push the messages to subscribers effectively.</li> <li>The WEnotes client for MediaWiki or WordPress, part of the <a href="https://bitbucket.org/wikieducator/wenotes">WEnotes project</a>, which provides a real-time feed of posts, either a full feed (for example <a href="https://wikieducator.org/WENotesCompleteFeed">this one</a>) or specific to a tag (for example a specific <a href="https://course.oeru.org/lida101/interactions/course-feed/">OERu Course</a>). The client also offers a posting interface, allowing logged in users to post new posts (up to 300 characters) automatically tagged in the relevant context. See two screenshots attached.</li> <li>A "publish-subscribe" or "Pub-Sub" service, <a href="https://bitbucket.org/wikieducator/wenotes-server">WEnotes-server project</a>, a Node.JS based <a href="https://faye.jcoglan.com/">Faye</a> implementation of the <a href="https://docs.cometd.org/current/reference/index.html#_bayeux">Bayeux protocol</a>. It uses <a href="https://en.wikipedia.org/wiki/WebSocket">websockets</a> to push out real-time updates to subscribed WEnotes clients.</li> <li> <p>The "couchwatch.js" script, also part of the WEnotes-tools project, watches the CouchDB and alerts Faye whenever a new post is received, which in turn pushes it out to subscribed WENote clients.</p> </li> </ol><h2>Whence WEnotes posts come</h2> <p>Here are three scenarios which outline the process by which a WEnote post is created.</p> <h3>Handy WEnotes post form</h3> <p>The most obvious way to create a WEnotes post is to go to a WEnote feed page - for <a href="https://course.oeru.org/lida101/interactions/course-feed/">instance</a> - and log into the system (assuming you have authentication credentials or can create some). If you're logged in, you should see a simple form as illustrated in the two attached screen shots. The system then knows who you are so that your post can be properly attributed, and it knows the "context" for the feed you're looking at (namely the associated tag). You can enter a message of up to 300 characters, and hit the "Post a WEnote" button, and this will send - direct from your browser - a suitably formatted post (a simple JSON object - example below) into the WEnotes CouchDB where it is then available for inclusion in relevant feed displays.</p> <h3>Personal blog post, appropriately tagged</h3> <p>If you register for our <a href="https://course.oeru.org" title="The main OERu course delivery platform for OERu itself and many partner institutions.">Course site</a>, or any course on that site, you have the option of adding a "Blog URL" - that's the web address of your blog (the address of <em>this </em>blog is <code>https://tech.oeru.org</code>, for instance). Because most widely used blogging platforms, like the open source <a href="https://wordpress.org">WordPress</a> platform (which is the most widely use web platform in the world, the basis for <a href="https://w3techs.com/blog/entry/wordpress-powers-25-percent-of-all-websites">25% of <em>all</em> websites</a>!! For the record, this website uses <a href="https://drupal.org">Drupal</a>, which is the 3rd biggest web platform, and is also open source), and proprietary cloud blogging platforms like Blogger and Medium, provide both "tagging" of posts and a built-in <a href="http://www.whatisrss.com/">RSS feed</a>. When you know what to look for, you'll start to see them all over the place (this blog has <a href="/blog/feed">one</a> - the logo is the little grey icon on the bottom left corner of <a href="/blog" title="The Tech Blog index page.">this page</a>).</p> <p>When you create a blog post on your registered blog and tag it with a course-specific tag (each course we run has one, it's usually the short code immediately after the main course website URL: <code>https://course.oeru.org/[course code here]/...</code>) the WEnotes feed harvesters will periodically visit your blog's RSS feed and look for new posts tagged with a course tag. If it finds one, it will create a new post in CouchDB with all the necessary info to provide an informative post in the WEnotes feed, proper author attribution (and an "avatar" picture of you where available!), and a way for interested readers to get to your original post.</p> <h3>Tagged/Hashtagged social media reference</h3> <p>Because the attention of many people is heavily focused on social media - dominated by "network effect" companies like Twitter and Facebook, for better or worse, but also by an array of more open and egalitarian services (which we, on principle, prefer, but recognise that they're far less well marketed due mostly to not taking anyone's money) - we also provide a variety of social media specific "feed harvesters".  Some of these periodically scan specific social media technologies for new relevant posts, others perpetually monitor their sources providing instant updates.</p> <p>If you</p> <ul><li><a href="https://mastodon.oeru.org" title="OERu's Instance of the open source Mastodon social media platform.">Toot</a> including a relevant hashtag (e.g. #oeru or #lida101 for the "Learning in a Digital Age 101" course),</li> <li>use <a href="https://hypothes.is">Hypothesis</a> to annotate a web page, tagging it appropriately (e.g. oeru or lida101),</li> <li>add a <a href="http://semanticscuttle.sourceforge.net/">Semantic Scuttle</a> "<a href="https://bookmarks.oeru.org" title="Our Semantic Scuttle instance.">Bookmark</a>" to a web reference of interest, tagging it appropriately,</li> <li>add a topic or reply on our <a href="https://community.oeru.org" title="Our Discourse forum for educators and OER developers">Community</a> or <a href="https://forums.oeru.org" title="The OERu's Discourse forum for learners">Forums</a> Discourse instances also suitably tagged, or</li> <li>create a <a href="https://moodle.org/" title="Market leading learning management system (it's also open source).">Moodle</a> post on a Moodle site running a suitable "student bot",</li> </ul><p>the WEnotes feed harvesters will find it and create a suitable post in the CouchDB.</p> <h2>How WEnotes feeds are made</h2> <p>Once you have a bunch of WEnotes posts stored in CouchDB, how do we create a feed? At present, we have "WEnotes client" scripts that run either on MediaWiki instances, like Wikieducator, or on WordPress sites, like our Course multisite, for which content is usually provisioned per-course using our "<a href="/oeru-mediawiki-wordpress-snapshot-toolchain">Snapshot</a>" toolchain. In both cases, the client is invoked via the inclusion of a "Widget" in the MediaWiki content that will either be viewed on the <a href="https://wikieducator.org/WENotesCompleteFeed" title="An example of the WENotes Widget, in this case a full feed, not restricted to one or more tags.">MediaWiki instance itself</a>, or on a target <a href="https://course.oeru.org/lida101/interactions/course-feed/" title="This is an example of the widget being transferred to a WordPress course subsite. Note the 'Content' link at the bottom of the page, which points to the Wikieducator page which contains the actual Widget.">WordPress course subsite</a>.</p> <p>After you log into the Wikieducator site, and create or find a page on which you want a feed, you "Edit source" and you can add both a <a href="https://wikieducator.org/Widget:WEnotesPost" title="The WENotes Post Widget how-to documentation.">WEnotes Post template</a> and <a href="https://wikieducator.org/Widget:WEnotes" title="The WENotes Feed Widget documentation">WEnotes Feed template</a> two simple one line recipes like this:</p> <p><code>{{#widget:WEnotesPost|tag=lida101}}<br /> {{#widget:WEnotes|tag=lida101|count=20}} </code></p> <p>This invocation will create a page showing a WEnotes Post Widget, where any submitted post will automatically be tagged by "lida101", and directly below that, a feed showing up to 20 posts from the CouchDB tagged with "lida101". Note, any <em>new</em> suitably tagged posts will pop into the feed in realtime as they're added to CouchDB thanks to couchwatch.js and Faye - invoking a WEnotes Feed Widget automatically subscribes you to realtime updates for that tag.</p> <p>You can also create a cross-tag feed using the magic <code>"_"</code> designator. WEnotes Posts require a tag (the default, if none is specified, is "wikieducator"):</p> <p><code>{{#widget:WEnotes|tag=_|count=20}} </code></p> <h2>WEnotes technical details</h2> <p>This is a tech-blog, so I'm not going to shy away from the technical details. Here're some useful bits and pieces for folks wanting to get a better understanding of this system. If you're scared of technical details, you can stop reading here.</p> <h3>WEnotes technology infrastructure</h3> <p>We implement the services making up the WEnotes stack using a set of three Docker containers as well as our main MediaWiki implementation, WikiEducator, and our main WordPress multisite implementation, the OERu Course multisite (we also maintain development instance of each of these). The Docker containers are managed with <a href="/docker-compose-better-way-deploy-rocketchat-wekan-and-mongodb">Docker Compose</a> and the roles are divided  We've created a separate <a href="https://github.com/oeru/wenotes-docker">code repository on GitHub </a>for our evolving WEnotes stack to facilitate others making use of some or all of it! The three containers currently being deployed do the following:</p> <ol><li>run CouchDB version 2.0 or later, as well as its "Fauxton" interactive web front-end.</li> <li>run the Faye Pub-Sub websocket destination for realtime feed updates, implemented as a Node.JS service running under <a href="http://pm2.keymetrics.io/">pm2</a>.</li> <li>run the Javascript (using pm2) and Python-based (using cron to run periodically) feed harvesters and the Javascript "couchwatch.js" script which alerts Faye to the addition of new posts.</li> </ol><p>Once configured (we're working on making that a straight forward "out-of-the-box" experience, although it's not quite there yet), the three containers can be deployed together with a single invocation of Docker Compose - at the moment, though, this system is quite dependent on a properly configured "options.json" file, the format of which is still in a state of flux.</p> <h3>WENotes JSON object</h3> <p>A WEnotes post is stored in our CouchDB as a JSON object (JSON = <a href="json.org" title="JSON is rapidly superseding XML as a way of storing and propogating machine-readable structured data. ">JavaScript Object Notation</a>). This is an example of a Post as it's stored in our CouchDB:</p> <p>{<br />   "_id": "3e1c16eb1c99ae59899761a680006f4a",<br />   "_rev": "1-7462f14a0515d98b5985b9f4b8c39dd5",<br />   "media_attachments": [<br />     {<br />       "url": "<a href="https://mastodon.oeru.org/system/media_attachments/files/000/000/017/original/c3e85e56142c5c4d.png?1505016473">https://mastodon.oeru.org/system/media_attachments/files/000/000/017/or…</a>",<br />       "text_url": "<a href="https://mastodon.oeru.org/media/jvUoIpj6OAt-e5t-H8k">https://mastodon.oeru.org/media/jvUoIpj6OAt-e5t-H8k</a>",<br />       "preview_url": "<a href="https://mastodon.oeru.org/system/media_attachments/files/000/000/017/small/c3e85e56142c5c4d.png?1505016473">https://mastodon.oeru.org/system/media_attachments/files/000/000/017/sm…</a>",<br />       "meta": {<br />         "small": {<br />           "width": 400,<br />           "size": "400x321",<br />           "aspect": 1.2461059190031152,<br />           "height": 321<br />         },<br />         "original": {<br />           "width": 1148,<br />           "size": "1148x921",<br />           "aspect": 1.246471226927253,<br />           "height": 921<br />         }<br />       },<br />       "type": "image",<br />       "id": 17,<br />       "remote_url": ""<br />     }<br />   ],<br />   "truncated": true,<br />   "reblog": null,<br />   "id": 21,<br />   "in_reply_to_id": null,<br />   "content": "&lt;p&gt;Productive weekend fixing hashtags and instructions for &lt;a href=\"<a href="https://mastodon.oeru.org/tags/lida101">https://mastodon.oeru.org/tags/lida101</a>\" class=\"mention hashtag\" rel=\"tag\"&gt;#&lt;span&gt;LiDA101&lt;/span&gt;&lt;/a&gt; photo challenges . Super cool to see mastodon.oeru,org toots in the course feed. &lt;a href=\"<a href="https://mastodon.oeru.org/tags/lida101photo">https://mastodon.oeru.org/tags/lida101photo</a>\" class=\"mention hashtag\" rel=\"tag\"&gt;#&lt;span&gt;lida101photo&lt;/span&gt;&lt;/a&gt; &lt;a href=\"<a href="https://mastodon.oeru.org/media/jvUoIpj6OAt-e5t-H8k">https://mastodon.oeru.org/media/jvUoIpj6OAt-e5t-H8k</a>\" rel=\"nofollow noopener\" target=\"_blank\"&gt;&lt;span class=\"invisible\"&gt;https://&lt;/span&gt;&lt;span class=\"ellipsis\"&gt;mastodon.oeru.org/media/jvUoIp&lt;/span&gt;&lt;span class=\"invisible\"&gt;j6OAt-e5t-H8k&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;",<br />   "application": null,<br />   "text": "Productive weekend fixing hashtags and instructions for #LiDA101 photo challenges . Super cool to see mastodon.oeru,org toots in the course feed. #lida101photo...",<br />   "profile_url": "<a href="https://mastodon.oeru.org/@mackiwg">https://mastodon.oeru.org/@mackiwg</a>",<br />   "tags": [<br />     {<br />       "url": "<a href="https://mastodon.oeru.org/tags/lida101">https://mastodon.oeru.org/tags/lida101</a>",<br />       "name": "lida101"<br />     },<br />     {<br />       "url": "<a href="https://mastodon.oeru.org/tags/lida101photo">https://mastodon.oeru.org/tags/lida101photo</a>",<br />       "name": "lida101photo"<br />     }<br />   ],<br />   "visibility": "public",<br />   "we_tags": [<br />     "lida101"<br />   ],<br />   "user": {<br />     "screen_name": "mackiwg",<br />     "profile_image_url": "<a href="https://mastodon.oeru.org/system/accounts/avatars/000/000/002/original/1575afda498ac49c.jpg?1494995233">https://mastodon.oeru.org/system/accounts/avatars/000/000/002/original/…</a>",<br />     "name": "Wayne Mackintosh"<br />   },<br />   "spoiler_text": "",<br />   "we_timestamp": "2017-09-10T04:09:05.000Z",<br />   "account": {<br />     "username": "mackiwg",<br />     "display_name": "Wayne Mackintosh",<br />     "statuses_count": 10,<br />     "following_count": 1,<br />     "url": "<a href="https://mastodon.oeru.org/@mackiwg">https://mastodon.oeru.org/@mackiwg</a>",<br />     "locked": false,<br />     "created_at": "2017-04-30T01:51:59.778Z",<br />     "avatar_static": "<a href="https://mastodon.oeru.org/system/accounts/avatars/000/000/002/original/1575afda498ac49c.jpg?1494995233">https://mastodon.oeru.org/system/accounts/avatars/000/000/002/original/…</a>",<br />     "note": "&lt;p&gt;Open sourcing education at OERu&lt;/p&gt;",<br />     "header": "<a href="https://mastodon.oeru.org/headers/original/missing.png">https://mastodon.oeru.org/headers/original/missing.png</a>",<br />     "followers_count": 1,<br />     "avatar": "<a href="https://mastodon.oeru.org/system/accounts/avatars/000/000/002/original/1575afda498ac49c.jpg?1494995233">https://mastodon.oeru.org/system/accounts/avatars/000/000/002/original/…</a>",<br />     "header_static": "<a href="https://mastodon.oeru.org/headers/original/missing.png">https://mastodon.oeru.org/headers/original/missing.png</a>",<br />     "acct": "mackiwg",<br />     "id": 2<br />   },<br />   "favourites_count": 0,<br />   "language": "en",<br />   "url": "<a href="https://mastodon.oeru.org/@mackiwg/21">https://mastodon.oeru.org/@mackiwg/21</a>",<br />   "we_source": "mastodon",<br />   "in_reply_to_account_id": null,<br />   "uri": "tag:mastodon.oeru.org,2017-09-10:objectId=21:objectType=Status",<br />   "reblogs_count": 0,<br />   "sensitive": false,<br />   "mentions": [],<br />   "created_at": "2017-09-10T04:09:58.197Z"<br /> }</p> <p>The most crucial things for WEnotes are the values that start with '<code>we_</code>'. They are used by the system which filters and displays WEnotes posts. </p> <h3>The OERu Tag List</h3> <p>The list of tags which OERu's WEnotes looks for changes from time-to-time, usually growing as we add new course tags or other tags of business. Currently, the list is being updated manually, but it is <a href="http://wenotes.oeru.org/resources/feed-sources.json" title="WENotes Tag List">available as a web feed</a> in JSON format. We intend to provide both a simple editing interface for this list and to provide an API to automate adding new tags. Eventually, when we create a new course on our Course multisite, we expect to be able to automatically registered the new course "tag" with the tag list.</p> <h2>Credits</h2> <p>The entire underlying mechanics and most of the cleverness of WikiEducator Notes are thanks to the ingenuity and hard work of <a href="https://wikieducator.org/User:JimTittsler">Jim Tittsler</a>, my predecessor as OER Foundation Technical Lead.</p> </div> </div> </div> <section class="field field-node--field-blog-comments field-name-field-blog-comments field-type-comment field-label-above comment-wrapper"> <a name="comments"></a> <div class="comment-form-wrapper"> <h2 class="comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=16&amp;2=field_blog_comments&amp;3=comment" token="PxBEEjMNnN6bxJwA5uTvkIiXXSU76SK-WRBHv4dgcXc"></drupal-render-placeholder> </div> </section> Wed, 23 Aug 2017 21:21:04 +0000 dave 16 at http://tech.oeru.org