帮酷LOGO
  • 显示原文与译文双语对照的内容
Introductory tutorial to Solid

  • 源代码名称:solid-tutorial-intro
  • 源代码网址:http://www.github.com/solid/solid-tutorial-intro
  • solid-tutorial-intro源代码文档
  • solid-tutorial-intro源代码下载
  • Git URL:
    git://www.github.com/solid/solid-tutorial-intro.git
  • Git Clone代码到本地:
    git clone http://www.github.com/solid/solid-tutorial-intro
  • Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/solid/solid-tutorial-intro
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
  • 为社交网站构建分散的应用程序

    教程,周二 12月四月

    简介

    今天早上我们将介绍 behind 个人数据存储,以及如何构建使用实体协议的个人数据存储中的个人数据存储的应用程序。 在 Coffee 中断之后,我们将做一个示例应用程序的演练,今天下午你可以自由构建自己的应用程序。

    的分散性:动机与原则

    为用户和应用程序开发人员提供真正的基于角色的集中应用技术栈,可以大大改善用户和应用程序开发人员的生活:

    • 避免供应商锁定( 以及与之有关的倾斜。墙壁。监视和它的他特权的倾向) 。

    • 在应用开发--中提升健康竞争和集成,因为用户数据与特定服务提供者或者应用程序分开。

    • 用户,而不是服务提供者,拥有他们自己的所有数据

    • 帮助防止数据丢失( 在获取提供程序或者决定中止特定服务时)

    • 鼓励使用标准的可以操作数据格式,从而提供更丰富的用户体验

    逻辑与数据分离

    Consider innovative mashup提供的各种创新和有趣的特性,服务提供者提供了访问用户数据的一般"网页 2.0"趋势,即简单 REST api 。 并且使用非标准 api 。专有和经常不兼容的数据格式,只使用服务提供者允许的严格控制和计量功能。

    如果用户可以完全控制自己的数据( 当前属于竖井服务提供程序的所有数据),那么可以选择哪些应用程序可以访问它,而不是使用它。 这是实体项目的核心目标之一。

    基于的互操作性

    当然,只有当数据以标准的。相互理解的格式书写时,才可能将应用程序与数据。

    通过重点使用标准协议。格式和词汇表,并提供一个通用的数据访问 API ( 以及访问控制列表格式) 。

    协议和 api

    我们提到,读取。创建和操作数据的应用程序与数据存储的位置完全分离。 这意味着应用程序和数据存储( 服务器) 需要一个通用的协议来互相通信。

    数据存储使用一个 RESTful API,并将数据存储为 RDF 。 无论是文档。图像。个人。抽象概念,还是两个资源之间的关系,数据中的每一个资源都有一个 URL,这是。 应用程序可以使用HTTP来创建。读取。更新和删除数据存储中的资源。 资源可以按照层次化的容器结构组织,这可以被看作是文件夹/目录。

    简单来说,要获取任何资源( 属性及其值) 中的数据,应用程序对资源的URL执行一个获取请求。 对于容器中的所有资源,容器上的get请求返回一个列表。 使应用程序在容器中创建新资源,使用该资源的属性对容器本身进行 HTTP POST 请求。 更新资源( 或者容器) 用户放置或者修补并删除使用删除。

    动作路径描述
    GET/path/to/resource检索资源
    GET/path/to/container/容器中的资源列表
    POST/path/to/parent/在容器中创建新资源
    PUT/path/to/resource替换资源
    PATCH/path/to/resource更新资源
    DELETE/path/to/resource删除资源

    发送和检索的数据是 RDF ;默认情况下我们使用的RDF序列化是 Turtle 。 如果你不熟悉这里格式,请不要担心,我们将向你展示使用它的方便库。 如果你想了解有关链接数据原则的更多信息,可以查看链接数据 quick quick quick 。

    这个API是一个W3C标准调用链接数据平台( LDP )

    模式和词汇表

    用于描述数据库中的数据,用一组描述数据项属性的术语来描述数据。 对于网络上的全球互操作性,我们都需要在选择模式来表示数据时找到一种协作。

    幸运的是,许多人发布了包含不同域的RDF词汇表,并且想要尽可以能重用现有的。 词汇( 就像其他数据项一样) 中的所有术语都有自己的URL 。 这确保当两个人使用相同的术语时,他们可以使用全局唯一标识符来表示他们的意思是相同的。

    • 词汇是指为了描述特定主题而决定放在一起的一组词汇和短语。 它们通常由和类组成。

    • 表示 <some-thing><other-thing> 类型。 例如: <http://rhiaro.co.uk/about#me> type <Person> ( Person是类) 。

    • 属性属性。 在前面的示例中,type 是属性。

    • 任何人都可以发布 vocabulary,并且你可以使用任何其他人发布的词汇表。 网上有很多东西,有些比其他的好。

    有很好的,稳定的词汇表。 示例包括:RDF和 RDFS ( 它提供了描述任何内容的基础) 。FOAF ( 用来描述人们和他们的朋友) 。都柏林核心( 用于描述出版物,主要用于) 。schema.org ( 涵盖了各种各样的东西) 。

    开始寻找领域特定术语的一个好地方是 LOV 。

    特别适用于你可能感兴趣的社交应用程序的词汇表:

    用户,身份验证和访问控制

    Solid使用 WebID url作为唯一的用户 id 。 这意味着不管web上的用户在哪里交互,它们都有一个标识符可以以用来登录他们的个人数据存储。

    • 不仅人类允许:应用和服务可以拥有自己的WebIDs,或者在需要时借用用户的WebID ( 通过委托)

    • 获取 WebID URL时,必须返回有效的WebID用户配置文件( 以RDF格式使用的文档)

    • 浏览器侧证书当前用于身份验证,而不是密码

    • 你需要一个WebID配置文件和相关的兼容存储提供商的相关证书,以使用任何基于实体的应用程序。

    如何决定谁可以访问特定资源? 由于我们有身份,我们可以使用它们来定义谁对资源有读或者写权限。 这些列表称为 ACL ( 访问控制列表),它们遵循网络访问控制规范。

    Pastebin示例

    本示例将指导你完成构建典型的固态应用程序所需的步骤。 你将学习如何:

    • 创建新资源( pastebins )
    • 查看已经创建的垃圾箱
    • 更新现有的垃圾箱

    正在准备应用程序

    在开始编写创建和查看容器的函数之前,我们需要决定应用程序的工作方式。 例如,我们知道我们将使用应用程序创建新的垃圾桶,以查看现有的软件包并更新它们。

    分离这些不同应用功能的最简单方法是使用查询参数 -- 换句话说,?view=...?edit=... 和来分隔状态。

    我们现在需要做的另一个重要步骤是添加所需的依赖项。 这些是 rdflib.jssolid.js 。

    本地数据结构

    接下来,我们可以定义如何构造我们的容器。 例如bin可以有标题和 body ( 内容),也可以有 URI ( 更新后有用) 。

    // Bin structurevar bin = {
     url:'',
     title:'',
     body:''}

    选择词汇表

    对于这个特定的应用,我们可以使用两个非常常见的词汇表,SIOCDublin Core Terms 。 你可以在 load() 函数中看到它们的用法,例如。 具体来说,我们将使用 title 谓词( 在代码中称为 vocab.dct('title') ) 和 content 谓词( 作为 vocab.sioc('content') ) 。

    决定存放新纸盒的位置

    要创建容器,我们必须定义一个默认容器,我们将它的投递到。 现在我们可以创建一个名为 defaultContainer的全局变量。 这里变量的值可以是你的帐户上的bins 容器,你已经用。

    var defaultContainer ='https://user.databox.me/Public/bins/'

    用户界面/html

    用户界面相当简单。 一对 div,一个用于查看器,另一个用于编辑器。 当前的示例缺少一些类的CSS定义( 比如 。 hidden ),可以从 Github repo ( 链接下方) 获得。

    <divclass="content center-text hidden"id="view">
     <h1id="view-title"></h1>
     <br>
     <divid="view-body"></div>
    </div>
    <divclass="content center-text hidden"id="edit">
     <inputtype="text"id="edit-title"class="block"placeholder="Title...">
     <br>
     <textareaid="edit-body"class="block"placeholder="Paste text here..."></textarea>
     <br>
     <buttonid="submit"class="btn">Publish</button>
    </div>

    现在让我们准备一些功能,使我们的应用程序的面包和黄油。

    创建新的纸盒

    创建新的箱子很容易。 它涉及使用 solid.js 将bin数据发布到 defaultContainer 。 我们可以创建一个 publish() 函数来处理这个步骤。 这里函数将从编辑器中读取标题和 body 元素的值。

    functionpublish () {
     bin.title=document.getElementById('edit-title').valuebin.body=document.getElementById('edit-body').value}

    接下来,我们将创建一个新的图形对象,在其中添加两个三元组,一个用于标题,一个用于 body 。 我们还将把图的序列化值存储在新的data 变量中。

    functionpublish () {
     bin.title=document.getElementById('edit-title').valuebin.body=document.getElementById('edit-body').valuevar graph =$rdf.graph()
     var thisResource =$rdf.sym('')
     graph.add(thisResource, vocab.dct('title'), $rdf.lit(bin.title))
     graph.add(thisResource, vocab.sioc('content'), $rdf.lit(bin.body))
     var data =new$rdf.Serializer(graph).toN3(graph)
    }

    最后,我们将使用 solid.js 将新的bin投递到服务器。 如果帖子成功,我们将把网址栏更新到查看器。 否则,我们必须处理错误。

    这是最后一个函数。

    functionpublish () {
     bin.title=document.getElementById('edit-title').valuebin.body=document.getElementById('edit-body').valuevar graph =$rdf.graph()
     var thisResource =$rdf.sym('')
     graph.add(thisResource, vocab.dct('title'), $rdf.lit(bin.title))
     graph.add(thisResource, vocab.sioc('content'), $rdf.lit(bin.body))
     var data =new$rdf.Serializer(graph).toN3(graph)
     solid.web.post(defaultContainer, data).then(function(meta) {
     // viewwindow.location.search="?view="+encodeURIComponent(meta.url)
     }).catch(function(err) {
     // do something with the errorconsole.log(err)
     });
    }

    阅读/查看纸盒

    现在我们有了创建新的容器的方法,让我们创建一个读取和显示容器的相应函数。

    我们可以使用 solid.js 来获取一个bin的内容。 让我们调用这个获取函数 load 。 我们的函数有两个参数- 一个是bin的URL,另一个是指示是否需要显示编辑器的标志。

    functionload (url, showEditor) {
     solid.web.get(url).then(function(response) {
     }).catch(function(err) {
     // do something with the errorconsole.log(err)
     });
    }

    函数 solid.web.get() 在成功时返回响应,我们可以从这个响应获取解析的图形对象( 通过 rdflib.js 解析。) 。 这个图形对象有一些方法,让我们可以查询特定的三元组图- 换句话说,graph.any() 。 我们将使用这里方法获取一个bin的标题和 body 。

    functionload (url, showEditor) {
     solid.web.get(url).then(function(response) {
     var graph =response.parsedGraph();
     // set urlbin.url=response.url;
     var subject =$rdf.sym(response.url);
     // add titlevar title =graph.any(subject, vocab.dct('title'));
     if (title) {
     bin.title=title.value;
     }
     // add bodyvar body =graph.any(subject, vocab.sioc('content'));
     if (body) {
     bin.body=body.value;
     }
     }).catch(function(err) {
     // do something with the errorconsole.log(err)
     });
    }

    现在我们已经经使用正确的值设置了 bin 对象,可以以更新视图,这取决于我们是否必须显示编辑器。

    下面是我们的load 函数的最终版本。

    functionload (url, showEditor) {
     solid.web.get(url).then(function(g) {
     var graph =response.parsedGraph();
     // set urlbin.url=response.url;
     var subject =$rdf.sym(response.url);
     // add titlevar title =graph.any(subject, vocab.dct('title'));
     if (title) {
     bin.title=title.value;
     }
     // add bodyvar body =graph.any(subject, vocab.sioc('content'));
     if (body) {
     bin.body=body.value;
     }
     if (showEditor) {
     document.getElementById('edit-title').value=bin.titledocument.getElementById('edit-body').innerHTML=bin.bodydocument.getElementById('submit').setAttribute('onclick', 'update()')
     document.getElementById('edit').classList.remove('hidden')
     } else {
     document.getElementById('view-title').innerHTML=bin.titledocument.getElementById('view-body').innerHTML=bin.bodydocument.getElementById('view').classList.remove('hidden')
     document.getElementById('edit').classList.add('hidden')
     }
     }).catch(function(err) {
     // do something with the errorconsole.log(err);
     });
    }

    更新纸盒

    更新箱子非常类似于创建新的。 唯一的区别是,我们使用现有的bin的URI,然后传递给 solid.js" solid.web.put() 函数。

    functionupdate () {
     bin.title=document.getElementById('edit-title').valuebin.body=document.getElementById('edit-body').valuevar graph =$rdf.graph();
     var thisResource =$rdf.sym('');
     graph.add(thisResource, vocab.dct('title'), bin.title);
     graph.add(thisResource, vocab.sioc('content'), bin.body);
     var data =new$rdf.Serializer(graph).toN3(graph);
     solid.web.put(bin.url, data).then(function(meta) {
     // viewwindow.location.search="?view="+encodeURIComponent(meta.url)
     }).catch(function(err) {
     // do something with the errorconsole.log(err)
     });
    }

    路由不同的应用程序状态

    很好,现在我们有了所有重要的功能。 我们把所有东西都放在一起我们知道我们可以使用这个应用来创建和查看垃圾箱。 最后一步是添加处理这些不同状态的应用逻辑。 因为我们需要一个实用函数来解析当前的URL并返回不同的查询参数。

    你可以继续在你的应用程序中粘贴以下函数。

    // Utility function to parse URL query string valuesvar queryVals = (function(a) {
     if (a =="") return {}
     var b = {}
     for (var i =0; i <a.length; ++i)
     {
     var p=a[i].split('=', 2)
     if (p.length==1) {
     b[p[0]] ="" } else {
     b[p[0]] =decodeURIComponent(p[1].replace(/+/g, ""))
     }
     }
     return b
    })(window.location.search.substr(1).split('&'))

    每次需要检查查询参数并获取它的值时,都可以调用这里函数。

    接下来,我们可以继续创建一个 init() 函数来处理"路线"。 这里函数负责解析当前 URL,或者显示编辑器或者加载查看器。 它还会在提交按钮上设置 onclick() 事件,取决于编辑器是否用于创建新的站点或者更新旧的。

    functioninit() {
     if (queryVals['view'] && queryVals['view'].length>0) {
     load(queryVals['view'])
     } elseif (queryVals['edit'] && queryVals['edit'].length>0) {
     load(queryVals['edit'], true)
     } else {
     document.getElementById('submit').setAttribute('onclick', 'publish()')
     document.getElementById('edit').classList.remove('hidden')
     }
    }

    这个函数将在我们的应用程序的底部调用,在所有其他函数都被定义之后。

    就是这样,你们都集合了 ! 你可以将以下链接用于完整示例应用程序的源文件: solid-tutorial-pastebin

    请参见 "用户张贴注释"示例




    Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语