Mastodon:社交媒体集中化的联合答案。

Mastodon:社交媒体集中化的联合答案。

时间:2020-9-27 作者:admin
在本文中,将介绍Mastodon,这是一个基于分散式Internet精神而建立的社交媒体网络。分散的网络面临很多挑战,不一定适合胆小者,但有充分的理由坚持不懈。

2020年7月15日,发生了Twitter历史上最大的骗局之一。通过智能社交工程,一群人设法访问了Twitter的管理工具,从而使他们可以直接从多个知名帐户发布推文。

超过130个有影响力的Twitter帐户被黑客入侵。在几分钟之内,苹果,比尔·盖茨,埃隆·马斯克等人的个人档案要求个人将比特币发送到加密货币钱包,并承诺将所发送的钱加倍并以慈善姿态返还。

在最初的推文发布后的几分钟内,在Twitter删除了骗局消息之前,已经进行了300多笔交易,价值超过18万美元。

有了集中的结构,只需要欺骗一个拥有管理权限的人就可以访问这些备受瞩目的帐户。在类似情况下,动机更险恶的人可能会瞄准股市崩盘,人为制造的政治紧张局势,甚至是全球动荡。

集权的利弊

集中化是一把双刃剑。其核心思想是基于社交媒体平台对数据的存储,所有权和保护。虽然这听起来很糟糕,但有很多好处。集中式平台的第一个也是最大的优势是易于使用。例如,当您忘记密码或帐户被黑客入侵时,具有集中式结构的平台可以轻松恢复它们,因为它们将所有数据存储在服务器上。

但是这种保护意识是有代价的。您的数据(如tweet,retweet,likes和share)由公司存储和拥有。这些公司每年都有财务KPI,而您的数据是它们赚钱的好方法,主要是用于有针对性的广告时。这种平台的另一个缺点是它们不是开源的,这意味着用户与其所使用的平台之间没有透明性。作为用户,您不知道幕后情况或数据处理方式。

Mastodon:社交媒体集中化的联合答案。

那么,如果有一个具有分散结构的平台,您拥有所发布的内容并且可以看到您的数据被用于什么呢?长期以来,人们一直在尝试创建这样的平台-App.net,Peach,Diaspora和Ello是一些较著名的示例。

但是去中心化社交媒体的最新开拓者具有上述所有优势。

输入Mastodon

Mastodon于2016年发布。在许多人眼中,该网络是社交媒体去中心化的第一步。尽管Mastodon在外观和功能上与Twitter相似,但它们通过分散和联合来专注于其用户群的安全和隐私。它的所有数据分布在大量独立的服务器上,这些服务器称为“实例”。每个实例都有自己的服务条款,行为准则和审核策略,同时可以与其他服务器作为联邦网络无缝协作。

Mastodon的创始人Eugen Rochko解释说,该平台的工作原理与电子邮件非常相似。电子邮件用户可以轻松连接,即使一个人使用Gmail而另一个人使用Outlook也是如此。Mastodon及其实例也是如此。尽管用户可以自由地与大量实例进行交互,但是每个实例还可以使用他们所反对的策略或内容来阻止来自其他服务器的内容,而不会失去对整个Mastodon网络的访问权限。

Mastodon:社交媒体集中化的联合答案。

Mastodon入门

Mastodon入门并不像加入Facebook或Twitter那样容易。由于该平台是类似于电子邮件的联合服务,因此Mastodon可让您注册许多运行Mastodon客户端的网站,类似于在Gmail,Hotmail或Protonmail等服务上创建电子邮件帐户的方式。

没有一个中心位置可以创建Mastodon帐户。相反,您可以选择要加入的社区并在其中创建一个帐户。

mstdn.social适用于想要发现和探索Mastodon的人们,这是一个很好的起点。如果您在此实例上注册,则可以通过用户名和实例名称的组合来发现您创建的帐户。例如,可以向我发送消息的我的完整用户名是@ alextraykov @ mstdn.social。您可以将您的个人资料名称作为Twitter句柄和电子邮件地址的组合来查看。

Mastodon:社交媒体集中化的联合答案。

您不需要为每个不同的Mastodon实例创建新帐户。但是,如果愿意,您可以具有与您感兴趣的各种实例相匹配的单独身份。如上所述,由于Mastodon是联合身份的,因此您可以与来自不同服务器的其他用户进行交互,而无需在同一服务器上注册。这是平台最强大的功能。

但是手机呢?是否有一个应用程序,您可以在上下班途中滚动嘟嘟声和增强声音?

没有适用于Android和iOS的官方应用。但是由于Mastodon是开源的,因此有许多第三方应用程序可让您检查帐户。对于Android,最受欢迎的选择是Tusky,对于iOS,则是Toot!或桅杆。这是移动,桌面和网络应用程序的完整列表

Mastodon和去中心化社交媒体的最终结论

在稳定增长的同时,Mastodon还远没有像Twitter或任何主要的集中式社交网络那样庞大。由于缺少正式的应用程序,入门流程和更复杂的服务器结构,Mastodon的学习曲线比我们每天使用的成熟社交媒体更为陡峭。但这并不能阻止每年成千上万的新用户加入,寻求比他们目前拥有的更诚实的替代方案。

分散式社交平台的未来尚不清楚。Mastodon是针对诸如Fediverse的互联网模型之类的网络上其他事物的首批开拓性步骤之一。我鼓励您戴上探险家的帽子,朝着互联网的这些新视野航行

Mastodon:社交媒体集中化的联合答案。

亚历山大·特雷科夫(Alexander Traykov)

Alexander Traykov是Toptal Core的产品设计师。当不推像素,链接原型或编写代码时,他喜欢骑着山地自行车撕碎小径,煮咖啡并在大自然中度过时光。

Eleventy(或11ty)是Node.js静态站点生成器(SSG)。SSG在构建时执行大多数渲染工作,以创建一组静态HTML,CSS和JavaScript文件。生成的页面不必具有服务器端依赖项,例如运行时或数据库。

这带来了几个主要好处:

  • 托管很简单:您正在提供HTML文件
  • 系统很安全:没有什么可破解的
  • 性能可能很棒。

Eleventy已变得越来越受欢迎,并在Web开发中引起了知名人士的关注。它是内容站点和博客的理想选择,但已适用于在线商店和报告系统。

在大多数情况下,您将使用Eleventy从Markdown文档生成HTML页面,这些页面会将内容插入由诸如Nunchucks之类的引擎提供动力的模板中。但是,本教程还演示了如何将Eleventy用作所有资产的完​​整构建系统。您不一定需要单独的系统,例如npm脚本,webpack或Gulp.js,但是您仍然可以享受自动构建和实时重新加载的乐趣。

您需要一个JavaScript框架吗?

一些SSG采用客户端JavaScript框架,例如React或Vue.js。您可以将框架与Eleventy一起使用,但未强制执行。

我认为,除非您要创建复杂的应用程序,否则可能不需要JavaScript框架。而且,如果您要创建应用程序,那么SSG不是正确的工具!盖茨比球迷可能会不同意,所以请在Twitter上挑战/嘲笑我

给我看代码

Eleventy声称很简单,但是在超越基础知识时可能会令人生畏。本教程演示了如何使用页面和博客/文章来构建一个简单的网站-这项任务通常由WordPress处理。

完整代码可在https://github.com/craigbuckler/11ty-starter上获得。您可以通过在终端中输入以下命令,在Windows,macOS或Linux上下载,安装并启动它:

git clone https://github.com/craigbuckler/11ty-starter
cd 11ty-starter
npm i
npx eleventy --serve

然后在浏览器中导航到主页http:// localhost:8080

以下步骤描述了如何从头开始构建站点。

安装Eleventy

像任何Node.js项目一样,从创建目录并初始化package.json文件开始:

mkdir mysite
cd mysite
npm init

然后将Eleventy安装为开发依赖项:

npm i @11ty/eleventy --save-dev

注意:此项目将模块安装为开发依赖项,因为它们仅需要在开发计算机上运行。某些具有自动构建过程的主机可能会要求您使用标准的运行时依赖项。

呈现您的第一页

创建一个src目录,所有源文件都将驻留在该目录中,然后在其中创建一个index.md文件。添加主页内容,例如:

‐‐‐
title: 11ty starter site
‐‐‐

This is a demonstration website using the [11ty static site generator](https://www.11ty.dev/). It shows pages, blog posts, lists, and tags.

The whole build process is managed through 11ty.

‐‐‐破折号之间的内容称为前题。它定义了有关页面的名称-值元数据,可用于设置Eleventy和模板的参数。title此处仅设置了a,但是您很快就会添加说明,日期,标签和其他数据。

.eleventy.js必须在项目的根文件夹中创建一个名为Eleventy的配置文件。这个简单的示例代码返回一个对象,该对象指定以下内容:

  1. src源文件的源目录
  2. build在其中创建网站文件的目录
// 11ty configuration
module.exports = config => {

  // 11ty defaults
  return {

    dir: {
      input: 'src',
      output: 'build'
    }

  };
};

要构建站点并启动由Browsersync驱动的实时重新加载服务器,请输入以下内容:

npx eleventy --serve

Eleventy呈现在src目录中找到的所有内容,并将结果内容输出到build

$ npx eleventy --serve
Writing build/index.html from ./src/index.md.
Wrote 1 file in 0.12 seconds (v0.11.0)
Watching...
[Browsersync] Access URLs:
 ---------------------------------------
       Local: http://localhost:8080
    External: http://172.27.204.106:8080
 ---------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 ---------------------------------------
[Browsersync] Serving files from: build

在这种情况下,build/index.html可以通过在浏览器中加载URL http:// localhost:8080来访问创建的单个文件。

Mastodon:社交媒体集中化的联合答案。

在创建的HTML文件build/index.html包含从markdown文件呈现的内容src/index.md

<p>This is a demonstration website using the <a href="https://www.11ty.dev/">11ty static site generator</a>. It shows pages, blog posts, lists, and tags.</p>
<p>The whole build process is managed through 11ty.</p>

可以使用Ctrl| 停止Eleventy服务器。CmdC

注意:在网站开发过程中几乎不需要停止Eleventy,因为新文件会自动呈现。但是,以下部分添加了更多配置选项,因此需要重新启动。

创建模板

Eleventy几乎可以使用任何JavaScript模板引擎。Nunchucks是一个很好的选择,因为它是全面的,并在11ty.dev的整个文档中使用。

将前面的内容更改src/index.md为此:

‐‐‐
title: 11ty starter site
description: This is a demonstration website generated using the 11ty static site generator.
layout: page.njk
‐‐‐

这指示Eleventy使用page.njkNunchucks模板进行布局。默认情况下,Eleventy _includes在源目录(src/)的子目录中查找模板。那里的任何文件都不会自己渲染,而是在构建过程中使用。

在以下位置创建此新模板src/_includes/page.njk

{% include "partials/htmlhead.njk" %}

<main>
{% block content %}

  <h1>{{ title }}</h1>

  {{ content | safe }}

{% endblock %}
</main>

{% include "partials/htmlfoot.njk" %}

该模板将title定义的内容放在页面<h1>标题的标题中,并替换{{ content }}为Markdown生成的HTML。(它使用safeNunchucks过滤器来输出HTML,而不会转义引号和尖括号。)

这两个{% include %}定义引用了模板中包含的文件。在创建一个HTML头文件src/_includes/partials/htmlhead.njk,该文件还使用页面的titledescription

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{{ title }}</title>
  <meta name="description" content="{{ description }}">
</head>
<body>

然后在以下位置创建HTML页脚src/_includes/partials/htmlfoot.njk

</body>
</html>

停止并重新启动Eleventy npx eleventy --serve

build\index.html现在,呈现的文件包含一个完整的HTML页面:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>11ty starter site</title>
  <meta name="description" content="This is a demonstration website generated using the 11ty static site generator.">
</head>
<body>

  <h1>11ty starter site</h1>

  <p>This is a demonstration website using the <a href="https://www.11ty.dev/">11ty static site generator</a>. It shows pages, blog posts, lists, and tags.</p>
  <p>The whole build process is managed through 11ty.</p>

</body>
</html>

注意:当您在浏览器中查看源代码时,还将看到BrowserSync在元素之后<script>添加了。这用于触发实时重新加载,并且不会出现在最终版本中(请参见下面的“构建生产站点”部分)。<body>

创建更多页面

现在,您可以创建更多内容,例如强制性的“关于我们”部分。

src/about/index.md

‐‐‐
title: About us
description: What we do.
‐‐‐

Some information about us.

src/about/team.md

‐‐‐
title: Our team
description: Information about us.
‐‐‐

Who are we and what we do.

src/about/privacy.md

‐‐‐
title: Privacy policy
description: We keep your details private.
‐‐‐

Our privacy policy.

这些文件都没有在其前面引用模板。Eleventy允许您通过创建目录来定义目录中所有文件的默认值<directory-name>.json file。在这种情况下,它名为src/about/about.json。它将JSON值设置为在页面的前端未明确定义时使用的JSON值:

{
  "layout": "page.njk"
}

重新运行npx eleventy --serve并检查build文件夹,以查看网站如何开始成形:

  • index.html:主页
  • about/index.html:关于我们页面
  • about/team/index.html:团队页面
  • about/privacy/index.html:隐私政策页面

因此,您可以在浏览器中使用类似slug的URL。例如,http:// localhost:8080 / about / team /显示团队页面index.html文件。

不幸的是,不可能在页面之间导航!您需要菜单…

创建导航菜单

Eleventy提供了一个标准的导航插件,可通过输入以下内容进行安装:

npm i @11ty/eleventy-navigation --save-dev

.eleventy.js在最后return声明之前,必须在配置文件中引用插件:

// 11ty configuration
module.exports = config => {

  /* --- PLUGINS --- */

  // navigation
  config.addPlugin( require('@11ty/eleventy-navigation') );


  // 11ty defaults
  return {

    dir: {
      input: 'src',
      output: 'build'
    }

  };
};

eleventyNavigation:必须在菜单中所需的每个页面中定义最重要的部分。本节设置以下内容:

  1. key页面菜单的A。这可能与相同,title但通常更短。
  2. 可选的parent,引用父页面的key
  3. 可选order号码;较低的值首先出现在菜单中。

首页中的内容src/index.md可以相应地更新:

‐‐‐
title: 11ty starter site
description: This is a demonstration website generated using the 11ty static site generator.
layout: page.njk
eleventyNavigation:
  key: home
  order: 100
‐‐‐

关于页面src/about/index.md

‐‐‐
title: About us
description: What we do.
eleventyNavigation:
  key: about
  order: 200
‐‐‐

团队页面位于src/about/team.md

‐‐‐
title: Our team
description: Information about us.
eleventyNavigation:
  key: team
  parent: about
  order: 210
‐‐‐

隐私政策页面位于src/about/privacy.md

‐‐‐
title: Privacy policy
description: We keep your details private.
eleventyNavigation:
  key: privacy
  parent: about
  order: 220
‐‐‐

注意:使用order10或更高倍数的值可以稍后在其他页面之间插入页面,而无需任何手动重新编号。

现在可以在src/_includes/page.njk以下位置将导航菜单添加到页面模板:

{% include "partials/htmlhead.njk" %}

<header>
  <nav>
    {{ collections.all | eleventyNavigation | eleventyNavigationToHtml | safe }}
  </nav>
</header>

<main>
...

这是一些神奇的Eleventy插件代码,它检查所有页面并使用eleventyNavigation()功能过滤它们以创建层次结构列表。使用eleventyNavigationToHtml()功能将该列表呈现器呈现为HTML 。

重新npx eleventy --serve加载任何页面以查看菜单。

Mastodon:社交媒体集中化的联合答案。

现在,您可以导航到eleventyNavigation前件中定义的任何页面。

改善导航

导航插件返回基本的HTML列表:

<ul>
  <li><a href="/">home</a></li>
  <li>
    <a href="/about/">about</a>
    <ul>
      <li><a href="/about/team/">team</a></li>
      <li><a href="/about/privacy/">privacy</a></li>
    </ul>
  </li>
</ul>

这对于大多数站点已经足够,但是您可以对其进行改进。例如:

  • 提供将菜单显示到特定级别的选项,例如仅在页眉中显示顶层,在页脚中显示所有页面
  • 高亮显示活动页面,同时使其不可单击
  • 为活动菜单项和打开菜单项设置样式类。

实现此目的的一种方法是创建一个可重用的简码,使用过WordPress的任何人都会熟悉它。简码和任何可选参数运行一个函数,该函数返回放置在模板中的HTML字符串。

停止Eleventy服务器并更新src/_includes/page.njk模板以{% navlist %}<header><footer>部分中使用简码:

{% include "partials/htmlhead.njk" %}

<header>
  <nav>
    {% navlist collections.all | eleventyNavigation, page, 1 %}
  </nav>
</header>

<main>
{% block content %}

  <h1>{{ title }}</h1>

  {{ content | safe }}

{% endblock %}
</main>

<footer>
  <nav>
    {% navlist collections.all | eleventyNavigation, page, 2 %}
  </nav>
</footer>

{% include "partials/htmlfoot.njk" %}

navlist简码传递三个参数:

  1. 通过该eleventyNavigation()函数过滤的每个页面,该函数返回页面对象的分层列表。每个页面定义一个children子页面数组。
  2. 目前page
  3. 可选的level。的value值1仅返回顶级HTML。2返回顶层和所有直接子页面。

navlist简码必须使用注册.addShortcode()的功能.eleventy.js在之前return的语句。它传递了一个短代码名称和要调用的函数:

  /* --- SHORTCODES --- */

  // page navigation
  config.addShortcode('navlist', require('./lib/shortcodes/navlist.js'));

您现在可以在中导出函数lib/shortcodes/navlist.js。下面的代码递归地检查所有页面以生成适当的HTML(如果很难遵循,请不要担心)。

注意:简码文件src不是文件夹的一部分,因此已在文件夹外部创建,但是您也可以在中定义它src/_includes

// generates a page navigation list
const
  listType      = 'ul',
  elementActive = 'strong',
  classActive   = 'active',
  classOpen     = 'open';

// pass in collections.all | eleventyNavigation, (current) page, and maximum depth level
module.exports = (pageNav, page, maxLevel = 999) => {

  function navRecurse(entry, level = 1) {

    let childPages = '';

    if (level < maxLevel) {
      for (let child of entry.children) {
        childPages += navRecurse(child, level++);
      }
    }

    let
      active = (entry.url === page.url),
      classList = [];

    if ((active && childPages) || childPages.includes(`<${ elementActive }>`)) classList.push(classOpen);
    if (active) classList.push(classActive);

    return (
      '<li' +
      (classList.length ? ` class="${ classList.join(' ') }"` : '') +
      '>' +
      (active ? `<${ elementActive }>` : `<a href="${ entry.url }">`) +
      entry.title +
      (active ? `</${ elementActive }>` : '</a>') +
      (childPages ? `<${ listType }>${ childPages }</${ listType }>` : '') +
      '</li>'
    );

  }

  let nav = '';
  for (let entry of pageNav) {
    nav += navRecurse(entry);
  }

  return `<${ listType }>${ nav }</${ listType }>`;

};

重新运行npx eleventy --serve并导航到“ 关于”页面。标头<nav>HTML现在包含以下内容:

<ul>
  <li><a href="/">home</a></li>
  <li class="active"><strong>about</strong></li>
</ul>

页脚<nav>HTML包含以下内容:

<ul>
  <li><a href="/">home</a></li>
  <li class="open active">
    <strong>about</strong>
    <ul>
      <li><a href="/about/team/">team</a></li>
      <li><a href="/about/privacy/">privacy</a></li>
    </ul>
  </li>
</ul>

添加文章/博客文章

文章或博客文章与标准页面不同。它们通常标有日期,并以相反的时间顺序显示在索引页上。

创建一个新src/articles目录并添加一些Markdown文件。在这个例子中,命名为六个文件artice-01.mdarticle-06.md已经建立,但你通常用更好的名字来创建更具有可读性SEO友好的URL。

内容示例article/article-01.md

‐‐‐
title: The first article
description: This is the first article.
date: 2020-09-01
tags:
  - HTML
  - CSS
‐‐‐

This is an article post.

## Subheading

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

每个帖子指定一个日期和一个或多个标签(HTMLCSS在这里使用)。Eleventy自动为每个标签创建一个集合。例如,一个HTML集合是所有带有标记的帖子的数组HTML。您可以使用该集合以有趣的方式编制索引或显示这些页面。

最近的article-06.md文件draft设置了一个值,并标明了远期的日期:

‐‐‐
title: The sixth article
description: This is the sixth article.
draft: true
date: 2029-09-06
tags:
  - HTML
  - CSS
  - JavaScript
‐‐‐

这表示该帖子在该日期过去并且draft已被删除之前,不应发布(在实时站点上)。Eleventy没有实现此功能,因此您必须创建自己的自定义集合,该集合忽略草稿。

在的顶部添加几行以.eleventy.js检测开发模式并返回当前日期时间:

// 11ty configuration
const
  dev  = global.dev  = (process.env.ELEVENTY_ENV === 'development'),
  now = new Date();

module.exports = config => {
...
}

然后定义一个post通过.addCollection()return语句之前调用而命名的集合。以下代码提取md目录中的所有文件,src/articles但删除设置位置draft或将来的发布日期(除非您使用的是开发模式):

  // post collection (in src/articles)
  config.addCollection('post', collection =>

    collection
      .getFilteredByGlob('./src/articles/*.md')
      .filter(p => dev || (!p.data.draft && p.date <= now))

  );

src/_includes/post.njk为帖子创建一个新模板。这是基于page.njk模板的,但是该content块还显示了从该post集合中提取的文章日期,字数和下一个/上一个链接:

{% extends "page.njk" %}

{% block content %}

  <h1>{{ title }}</h1>

  {% if date %}<p class="time"><time datetime="{{ date }}">{{ date }}</time></p>{% endif %}

  <p class="words">{{ content | wordcount }} words</p>

  {{ content | safe }}

  {% set nextPost = collections.post | getNextCollectionItem(page) %}
  {% if nextPost %}<p>Next article: <a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a></p>{% endif %}

  {% set previousPost = collections.post | getPreviousCollectionItem(page) %}
  {% if previousPost %}<p>Previous article: <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a></p>{% endif %}

{% endblock %}

最后,定义一个src/articles/article.json文件设置post.njk为默认模板:

{
  "layout": "post.njk"
}

运行npx eleventy --serve,然后浏览至http:// localhost:8080 / articles / article-01 /

Mastodon:社交媒体集中化的联合答案。

创建文章/博客索引页面

尽管您可以从一个帖子导航到另一个帖子,但在http:// localhost:8080 / articles /上创建索引页面以按相反的时间顺序显示所有帖子(从最新到最新)将很有用。

Eleventy提供了一个分页功能,该功能可以通过遍历一组数据(例如posts上面创建的集合)来创建任意数量的页面。

src/articles/index.md使用以下内容创建一个新文件:

‐‐‐
title: Article index
description: A list of articles published on this site.
layout: page.njk
eleventyNavigation:
  key: articles
  order: 900
pagination:
  data: collections.post
  alias: pagelist
  reverse: true
  size: 3
‐‐‐

The following articles are available.

前端物料配置执行以下操作:

  1. 它设置标准page.njk模板。
  2. 它将页面添加为articles菜单项。
  3. 它创建一个名为pagelistfrom 的列表collections.post,将其反向(最新的帖子优先),并且每页最多允许三项。Eleventy将撰写六篇文章,生成两页,每页三篇文章。

现在修改其中的contentsrc/_includes/page.njk以包括一个新的pagelist.njk部分:

{% block content %}

  <h1>{{ title }}</h1>

  {{ content | safe }}

  {% include "partials/pagelist.njk" %}

{% endblock %}

src/_includes/partials/pagelist.njk使用代码创建该部分,以遍历pagelist分页对象并输出每个帖子的链接,标题,日期和描述:

{% if pagelist %}
<aside class="pagelist">

  {%- for post in pagelist -%}
  <article>

    <h2><a href="{{ post.url }}">{{ post.data.title }}</a></h2>

    {% if post.data.date %}<p class="time"><time datetime="{{ post.data.date }}">{{ post.data.date }}</time></p>{% endif %}

    <p>{{ post.data.description }}</p>

  </article>
  {%- endfor -%}

</aside>
{% endif %}

在此代码下,您可以添加下一个上一个链接以浏览分页索引:

{% if pagination.href.previous or pagination.href.next %}
<nav class="pagenav">

  {% if pagination.href.previous %}
    <p><a href="{{ pagination.href.previous }}">previous</a></p>
  {% endif %}

  {% if pagination.href.next %}
    <p><a href="{{ pagination.href.next }}">next</a></p>
  {% endif %}

</nav>
{% endif %}

在重新开始构建过程之前,请设置ELEVENTY_ENV环境变量development以确保草稿和以后的帖子包含在构建中。在Linux / macOS上,输入:

ELEVENTY_ENV=development

或在Windows cmd提示符下:

set ELEVENTY_ENV=development

或Windows Powershell:

$env:ELEVENTY_ENV="development"

重新运行npx eleventy --serve并刷新浏览器。菜单中将出现一个新的文章链接,该链接显示了http:// localhost:8080 / articles /上的三篇最新文章:

Mastodon:社交媒体集中化的联合答案。

接下来的链接指向的文章在进一步网页的http://本地主机:8080 /用品/ 1 /

创建自定义过滤器

上面的屏幕截图显示的日期是不友好的JavaScript字符串。Eleventy提供了可以修改数据并返回字符串的过滤器。当Markdown生成的内容通过safe过滤器输出未编码的HTML:时,您已经看到了这种用法{{ content | safe }}

lib/filters/dateformat.js使用以下代码创建一个新文件。它导出两个函数:

  1. ymd()它将日期YYYY-MM-DD转换为HTML datetime属性的机器可读格式,并且
  2. friendly()它将日期转换为人类可读的格式,例如1 January, 2020
// date formatting functions
const toMonth = new Intl.DateTimeFormat('en', { month: 'long' });


// format a date to YYYY-MM-DD
module.exports.ymd = date => (

  date instanceof Date ?
    `${ date.getUTCFullYear() }-${ String(date.getUTCMonth() + 1).padStart(2, '0') }-${ String(date.getUTCDate()).padStart(2, '0') }` : ''

);


// format a date to DD MMMM, YYYY
module.exports.friendly = date => (

  date instanceof Date ?
    date.getUTCDate() + ' ' + toMonth.format(date) + ', ' + date.getUTCFullYear() : ''

);

您还可以创建一个过滤器,以显示帖子中的单词数量,该数量将四舍五入到最接近的十位并用逗号分隔符设置格式,并估算读取时间。lib/filters/readtime.js使用以下代码创建:

// format number of words and reading time
const
  roundTo     = 10,
  readPerMin  = 200,
  numFormat   = new Intl.NumberFormat('en');

module.exports = count => {

  const
    words     = Math.ceil(count / roundTo) * roundTo,
    mins      = Math.ceil(count / readPerMin);

  return `${ numFormat.format(words) } words, ${ numFormat.format(mins) }-minute read`;

};

.eleventy.jsreturn语句之前的任何位置注册过滤器:

  /* --- FILTERS --- */

  // format dates
  const dateformat = require('./lib/filters/dateformat');
  config.addFilter('datefriendly', dateformat.friendly);
  config.addFilter('dateymd', dateformat.ymd);

  // format word count and reading time
  config.addFilter('readtime', require('./lib/filters/readtime'));

然后更新src/_includes/post.njk使用dateymddatefriendly以及readtime过滤器:

  {% if date %}<p class="time"><time datetime="{{ date | dateymd }}">{{ date | datefriendly }}</time></p>{% endif %}

  <p class="words">{{ content | wordcount | readtime }}</p>

然后将文章索引的部分更改src/_includes/partials/pagelist.njk为使用dateymddatefriendly过滤器:

{% if post.data.date %}<p class="time"><time datetime="{{ post.data.date | dateymd }}">{{ post.data.date | datefriendly }}</time></p>{% endif %}

重新启动构建npx eleventy --serve并刷新浏览器。加载任何文章以查看友好的日期,格式化的字数和阅读时间估计:

Mastodon:社交媒体集中化的联合答案。

产生的HTML:

<p class="time"><time datetime="2020-09-05">5 September, 2020</time></p>

<p class="words">80 words, 1-minute read</p>

使用JavaScript模板处理图像

Eleventy可以使用中的.addPassthroughCopy()功能从任何文件夹复制文件.eleventy.js。例如,要将所有文件复制src/images/到中build/images/,您可以添加:

config.addPassthroughCopy('src/images');

如果您的图像已经过优化,那可能就足够了,但是自动的构建时优化可以减少文件数量。在这一点上,开发人员经常转向另一个系统,例如npm脚本,webpack或Gulp.js,但这可能不是必需的。

JavaScript是Eleventy中的一流模板选项。任何结尾的文件.11ty.js都将在构建过程中处理。该文件必须使用以下内容导出JavaScript class

  1. 一种data()将最重要的设置作为JavaScript对象返回的方法
  2. 一个render()方法—通常返回一个字符串,但它也可以运行同步或异步过程并返回true

要减小图像尺寸,请安装imagemin以及JPEGPNGSVG文件的插件:

npm i imagemin imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev

在中创建images目录src,添加一些图像,然后src/images/images.11ty.js使用以下代码创建一个新文件:

// image minification
const
  dest = './build/images',

  fsp = require('fs').promises,
  imagemin = require('imagemin'),
  plugins = [
    require('imagemin-mozjpeg')(),
    require('imagemin-pngquant')({ strip: true }),
    require('imagemin-svgo')()
  ];

module.exports = class {

  data() {

    return {
      permalink: false,
      eleventyExcludeFromCollections: true
    };

  }

  // process all files
  async render() {

    // destination already exists?
    try {
      let dir = await fsp.stat(dest);
      if (dir.isDirectory()) return true;
    }
    catch(e){}

    // process images
    console.log('optimizing images');

    await imagemin(['src/images/*', '!src/images/*.js'], {
      destination: dest,
      plugins
    });

    return true;

  }
};

重新运行npx eleventy --serve图像的优化版本将复制到该build/images/文件夹中。

注意:如果build/images找到目录,以上代码将结束。这是在每次构建过程中放弃对相同图像进行重新处理的简单解决方案,可确保Eleventy保持快速运行。如果添加其他图像,请build/images首先删除文件夹以确保它们均已生成。可以使用更好的选项,但是它们需要更多的代码!

现在可以在Markdown或模板文件中添加图像。例如,中的<header>定义src/_includes/page.njk可以具有徽标和英雄图像:

<header>

  <p class="logo"><a href="/"><img src="/images/logo.svg" width="50" height="50" alt="11ty starter">11ty starter</a></p>

  <nav>
    {% navlist collections.all | eleventyNavigation, page, 1 %}
  </nav>

  <figure><img src="/images/{% if hero %}{{ hero }}{% else %}orb.jpg{% endif %}" width="400" height="300" alt="decoration" /></figure>

</header>

hero可以根据需要在前面设置一个值,例如,在src/articles/articles.json

{
  "layout": "post.njk",
  "hero": "phone.jpg"
}

Mastodon:社交媒体集中化的联合答案。

使用转换处理CSS

可以用类似的方式处理CSS或使用任何其他构建系统。但是,在这种情况下,Eleventy变换是一个不错的选择。转换是传递当前呈现的字符串内容和文件路径的函数。然后,他们返回该内容的修改版本。

我考虑过使用Sass进行CSS预处理,但是带有一些插件的PostCSS可以实现一种轻量级的替代方案,该替代方案仍支持局部,变量,混合和嵌套。在项目中安装PostCSS模块:

npm i postcss postcss-advanced-variables postcss-nested postcss-scss cssnano --save-dev

然后lib/transforms/postcss.js使用以下代码创建文件。.css当构建在development模式下运行时,它会在处理,最小化和添加源映射之前验证文件正在传递:

// PostCSS CSS processing

/* global dev */

const
  postcss = require('postcss'),
  postcssPlugins = [
    require('postcss-advanced-variables'),
    require('postcss-nested'),
    require('cssnano')
  ],
  postcssOptions = {
    from: 'src/scss/entry.scss',
    syntax: require('postcss-scss'),
    map: dev ? { inline: true } : false
  };

module.exports = async (content, outputPath) => {

  if (!String(outputPath).endsWith('.css')) return content;

  return (
    await postcss(postcssPlugins).process(content, postcssOptions)
  ).css;

};

转换必须在语句之前使用.addTransform()函数in 进行注册。的通话将触发一个完整的网站重建时一个文件中,更改目录:.eleventy.jsreturn.addWatchTarget()src/scss/

  // CSS processing
  config.addTransform('postcss', require('./lib/transforms/postcss'));
  config.addWatchTarget('./src/scss/');

创建一个src/scss/main.scss文件,并包含您需要的任何SCSS或CSS代码。该示例代码将导入其他SCSS文件:

// settings
@import '01-settings/_variables';
@import '01-settings/_mixins';

// reset
@import '02-generic/_reset';

// elements
@import '03-elements/_primary';

// etc...

Eleventy不会直接处理CSS或SCSS文件,因此您必须src/scss/main.njk使用以下代码在处创建一个新的模板文件:

‐‐‐
permalink: /css/main.css
eleventyExcludeFromCollections: true
‐‐‐
@import 'main.scss';

这将导入您的main.scss文件并将其呈现到build/css/main.css转换函数进行相应处理之前。.njk如果您需要多个CSS 文件,则可以创建类似的SCSS / CSS和文件。

重新运行npx eleventy --serve并检查构建到的CSS文件的内容build/css/main.css。源映射确保在浏览器的开发人员工具中检查样式时CSS声明的原始源文件位置可用。

使用转换最小化HTML

可以使用类似的转换来使用html-minifier缩小HTML 。像这样安装它:

npm i html-minifier --save-dev

lib/transforms/htmlminify.js使用以下代码创建一个新文件。它验证.html文件正在处理中,并返回缩小版本:

// minify HTML
const htmlmin = require('html-minifier');

module.exports = (content, outputPath = '.html') => {

  if (!String(outputPath).endsWith('.html')) return content;

  return htmlmin.minify(content, {
    useShortDoctype: true,
    removeComments: true,
    collapseWhitespace: true
  });

};

和以前一样,.eleventy.jsreturn语句之前的某个位置注册转换:

  // minify HTML
  config.addTransform('htmlminify', require('./lib/transforms/htmlminify'));

注意:您可以考虑在开发过程中不要缩小甚至美化 HTML。也就是说,HTML空格会影响浏览器的呈现,因此通常最好以与生产相同的方式来构建代码。源代码查看将变得更加困难,但是浏览器开发人员工具会显示最终的DOM。

通过转换内联资产

通常需要在HTML中内联其他资源。SVG是主要的候选对象,因为图像成为DOM的一部分并且可以使用CSS进行操作。通过内联<style>元素中的CSS,元素中的JavaScript <script>或元素中的base64编码图像来减少HTTP请求也是可行的<img>

直列源模块可以处理所有的情况为您服务。与此安装:

npm i inline-source --save-dev

现在lib/transforms/inline.js,使用以下代码添加一个新文件,以检查和处理HTML内容:

// inline data
const { inlineSource } = require('inline-source');

module.exports = async (content, outputPath) => {

  if (!String(outputPath).endsWith('.html')) return content;

  return await inlineSource(content, {
    compress: true,
    rootpath: './build/'
  });

};

.eleventy.jsreturn语句之前注册转换:

  // inline assets
  config.addTransform('inline', require('./lib/transforms/inline'));

现在,添加inline属性的任何<img><link><script>标签。例如:

<img src="/images/logo.svg" width="50" height="50" alt="11ty starter" inline>

在构建过程中,转换将<img>使用导入的<svg>代码替换标记。

使用JavaScript模板处理JavaScript

客户端JavaScript可以通过转换来处理,但是命名的JavaScript模板<something>.11ty.js也是一个选项,因为它们由Eleventy自动处理(请参见上面的“使用JavaScript模板处理图像”部分)。

示例代码提供ES6脚本实现简单的暗/亮主题切换。Rollup.js用于将所有引用的模块捆绑main.js到一个文件中,并进行摇树操作以删除所有未使用的功能。然后,terser插件将生成的代码最小化。

使用以下命令安装Rollup.js模块:

npm i rollup rollup-plugin-terser --save-dev

然后在中创建js目录src并添加您的ES6脚本。一个单一的src/js/main.js入口脚本必须定义其进口等。例如:

import * as theme from './lib/theme.js';

src/js/javascript.11ty.js使用以下代码创建一个新文件,以将其处理src/js/main.js为一个捆绑包,并在开发模式下构建时添加源映射:

// JavaScript processing

/* global dev */

const
  jsMain = 'js/main.js',

  rollup = require('rollup'),
  terser = require('rollup-plugin-terser').terser,

  inputOpts = {
    input: './src/' + jsMain
  },

  outputOpts = {
    format: 'es',
    sourcemap: dev,
    plugins: [
      terser({
        mangle: {
          toplevel: true
        },
        compress: {
          drop_console: !dev,
          drop_debugger: !dev
        },
        output: {
          quote_style: 1
        }
      })
    ]
  }
  ;


module.exports = class {

  data() {

    return {
      permalink: jsMain,
      eleventyExcludeFromCollections: true
    };

  }

  // PostCSS processing
  async render() {

    const
      bundle = await rollup.rollup(inputOpts),
      { output } = await bundle.generate(outputOpts),
      out = output.length && output[0];

    let code = '';
    if (out) {

      // JS code
      code = out.code;

      // inline source map
      if (out.map) {
        let b64 = new Buffer.from(out.map.toString());
        code += '//# sourceMappingURL=data:application/json;base64,' + b64.toString('base64');
      }

    }

    return code;

  }
};

对JavaScript文件的任何更改都可以通过在.eleventy.js之前添加以下行来触发重建return

  config.addWatchTarget('./src/js/');

然后,生成的脚本可以包含在您的页面中,例如src/_includes/partials/htmlfoot.njk

<script type="module" src="/js/main.js"></script>

</body>
</html>

注意:示例代码将构建ES6模块,而不是编译为ES5。该脚本较小,但浏览器兼容性会受到更大的限制。就是说,这是一个逐步的增强,该站点无需JavaScript即可运行。

重新启动npx eleventy --serve,您的缩小脚本将加载并运行。现在可以通过其屡获殊荣的荣耀来查看最终站点:

Mastodon:社交媒体集中化的联合答案。

建立生产现场

对网站感到满意后,您可以在生产模式下构建它,而无需源地图和其他开发选项。

删除build文件夹并在Linux / macOS上设置ELEVENTY_ENVproduction

ELEVENTY_ENV=production

或Windows cmd提示:

set ELEVENTY_ENV=production

或Windows Powershell:

$env:ELEVENTY_ENV="production"

然后运行npx eleventy以构建完整站点。

/build目录中生成的文件可以上载到任何主机。每当将新代码推送到GitHub或类似的存储库时,一些静态网站专家服务就可以自动构建和发布您的网站。

Eleventy的下一步

示例项目演示了Eleventy的基础知识,并提供了一些用于构建不同类型的内容的选项。但是,Eleventy非常灵活,您可以自由使用自己喜欢的任何技术。有许多启动项目,每个项目采用的方法略有不同。

有关其他网站功能的建议:

  • 为列出相关文章的每个标签创建索引页面。记住Eleventy会自动为每个标签创建单独的集合。
  • 生成feed.xml列出所有帖子的RSS 文件。
  • 创建一个sitemap.xml列出所有页面的文件。
  • 构建一个404错误页面并生成适当的代码来处理它(例如.htaccessApache 的文件)。
  • 生成其他根文件,例如favicon.ico或Service Worker。
  • 使用Eleventy的分页功能从data生成页面
  • 并为将WordPress内容导入静态页面获得加分。

Eleventy为您服务吗?

静态网站生成器是任何主要提供内容更改频率不高的网站的理想解决方案。可以在Git存储库中对页面进行版本控制,开发更易于控制,测试简单,性能出色并且安全性问题消失了。(我wp-login.php对服务器日志中所有失败的尝试感到无比开心!)

许多SSG可供选择,但是如果您满足以下条件,Eleventy是一个不错的选择:

  • 是SSG的新手或对您当前的选择不满意
  • 例如Node.js,并希望在开发过程中使用JavaScript
  • 想跳上最新的酷事!

祝好运!       福州小程序开发

Mastodon:社交媒体集中化的联合答案。

克雷格·巴克勒

Craig是一位自由的英国Web顾问,他于1995年为IE2.0建立了他的第一页。自那时以来,他一直倡导标准,可访问性和最佳实践HTML5技术。他为公司和组织(包括英国议会,欧洲议会,能源与气候变化部,微软等)创建了企业规范,网站和在线应用程序。他为SitePoint写了1000多篇文章,您可以找到他

“互操作性”是使新产品或服务与现有产品或服务一起工作的行为:现代文明取决于允许您将任何碗碟放入洗碗机或将任何USB充电器放入任何汽车点烟器的标准和惯例。

但是互操作性只是赌注。对于真正竞争,创新,充满活力的市场,您需要对抗性的互操作性:这就是您创建新产品或服务的过程,而这些产品或服务可以插入到现有产品或服务中,而未经制造它们的公司的允许。想想第三方打印机墨水,替代应用商店或独立维修店,它们使用竞争对手制造商的兼容零件来修理您的汽车,手机或拖拉机。

对抗式互操作性曾经是技术瞬息万变的市场的驱动力,在这个市场中,最大的公司可以从堆垛的顶端变成废金属,眨眼间,小型的初创公司可以在不知道受到打击的公司之前推翻了占主导地位的公司。

但是,目前大量的高科技公司都拥有安全的法律,法规和法院判决,这些都极大地限制了对手的互操作性。从美国专利商标局在最初的软件专利和Alice决定之间的黑暗年代授予的大量荒谬的软件专利,到越来越多地使用“数字版权管理”以建立法律义务来使用您购买的产品为了让股东自负盈亏,Big Tech攀登了对抗梯,然后将其拉到了身后。

那可以而且应该改变。随着大型技术的日益集中,恢复对抗性的互操作性必须是解决该问题的方法:缩小大公司的规模使其错误的后果减少,并且剥夺了他们赖以游说以争取竞争规则的垄断利润。与他们更加努力。

几个月以来,我们一直在撰写对抗性互操作性的历史,理论和实践。该页面以一种便捷的资源将我们在该主题上的论述作为基础,您可以将其发送给您的朋友,国会议员,老师,投资者和老板,因为我们所有人都在努力寻找如何重新分散互联网权力并传播决策权的方法吸引了数百万个人和公司,而不是少数高科技巨头的高管。

  • 互操作性:修复互联网,而不是技术公司:从“无差异互操作性”(我不在乎是否将产品插入产品)到“合作互操作性”(请插入您的产品)我的产品)“对抗性互操作性”(晃来晃去,停止将您的产品插入我的产品!)。
  • Unix和对抗性的互操作性:定义计算的“一个怪异的反托拉斯技巧” 如何让一个残酷的垄断者坐在它的手上,而大大小小的竞争者都在制造它的一项发明的可互操作的版本?Unix的故事说明了这种方式。
  • alt.interoperability.adversarial alt的历史。层次结构显示了以协议而非产品为主导的Internet如何确保用户可以塑造其在线体验。恢复对互操作者的法律保护可能会使当今的大技术公司重新使用任何人都可以插入新服务的协议。
  • 对抗式互操作性:从更文明的时代恢复优雅的武器,以消灭当今的垄断地位:对抗式互操作性的历史及其在过去四十年中推动了技术革命的方式,以及我们如何做才能恢复它。
  • Gopher:在网守的要塞下挖掘对抗性互操作性时:在Web吞没Gopher之前,Gopher吞噬了大型机。
  • 互操作性和隐私:圈出一角:大型科技公司在互联网上制造了隐私垃圾箱大火,但现在他们说,除非我们根据法律禁止竞争对手将新服务插入其燃烧的垃圾箱中,否则它们无法解决。那太方便了,你不觉得吗?
  • 更新的周期破裂:大技术和大媒体如何滥用版权法杀害竞争者:有线电视的存在是由于对抗性的互操作性,这使其有能力破坏广播公司。如今,Big Cable正在竭尽所能阻止任何人破坏
  • “ IBM PC兼容”:对抗性互操作性如何从垄断中拯救PC:IBM花了十多年的时间才对大型机垄断采取了反托拉斯行动,但当它制造出第一台PC时,像Phoenix和Compaq这样的草率新贵得以克隆其ROM芯片,创建一个生机勃勃,发展迅速的市场。
  • SAMBA与SMB:网络互作用是对抗性的柔道:Microsoft通过将内部网锁定在称为SMB的专有网络协议中,从而接近拥有现代化的办公室……也就是说,直到一名博士候选人发布了SAMBA,这是一个免费/开放的产品可以与SMB进行互操作,并允许Mac,Unix系统和其他竞争对手与Windows机器生活在相同的LAN中。
  • 对商业模式的重罪轻蔑:利盟的反竞争遗产:打印机公司因滥用行为而臭名昭著,但利盟在2002年达到了一个新的低点,当时利盟认为版权使它有权决定谁可以将碳粉放入空的碳粉盒中。即使Lexmark失败了,它也开辟了其他公司热情追随的道路,成功地扭曲了版权,涵盖了从拖拉机零件到浏览器插件的所有内容。
  • 造币厂:晚期对抗性互操作性展示了我们所拥有的(以及我们失去了什么):对抗性互操作性的最后一次巨大挑战,是与金融部门抗争……并赢得了胜利!
  • Adblocking:那不怎么样?:早期的Web充满了侵入式弹出广告,而对抗性的互操作性使它们不可见。如今,封锁是有史以来最大的抵制活动,它比任何监管机构都在抑制不良广告和随之而来的监视方面做得更多。
  • 非洲人WhatsApp Modders是全球对抗性互操作性的大师:GB WhatsApp在叙利亚冲突中崭露头角,现已成为非洲的佼佼者,在非洲比Facebook本身更受人欢迎,并且必须与其他WhatsApp mod竞争,每个都针对不同类型的用户和用例进行了定制。

根据Creative Commons Attribution 4.0许可EFF深度链接重新发布

➤阅读科里·多克托洛(Cory Doctorow)的《如何摧毁监视资本主义》

Mastodon:社交媒体集中化的联合答案。

科里·多克托洛(Cory Doctorow)

Cory Doctorow(craphound.com)是科幻小说作家,活动家和新闻记者。他是许多小说的作者,最近出版的是《 RADICALIZED》和《 WALKAWAY》,这是一本图画小说,是关于成人的科幻小说,《真实生活》。信息不是免费的,这是一本关于在互联网时代谋生的书,而《国土》则是《小兄弟》的续集。他的最新著作是POESY THE MONSTER SLAYER,这是一本针对年轻读者的图画书。他的下一本书是《小兄弟》的成人续集《攻击面》。

在本文中,我们将探讨Windows终端,它是WSL2的理想伴侣。它快速,可配置,外观精美,并提供Windows和Linux开发的所有优势。

Windows已完全采用Linux,而WSL2使其成为一种无缝的乐趣。

您可以通过以下方式访问发行版的终端:

  1. 单击其开始菜单图标
  2. 在Powershell或命令提示符处输入wslbash
  3. 使用第三方终端选项(例如CmderConEmuHyper)启动配置文件%windir%\system32\bash.exe ~
  4. 通过按CtrlShiftP并键入/选择Terminal来将Linux设置为VS Code中的默认Shell:选择Default Shell,然后选择WSL Bash

Windows Terminal (可从Microsoft Store下载)提供了进一步的选择,但您不会后悔安装它。新的应用程序功能:

  • 支持WSL2,SSH,Powershell,cmd和其他命令行
  • 多个选项卡和拆分窗格
  • 可配置的主题,背景图像和透明效果
  • 搜索框
  • 自定义键绑定
  • GPU加速文字渲染
  • 美观的新字体Cascadia Code
  • 资源使用率低(每个选项卡通常10MB)
  • 自动更新(如果使用Microsoft Store)
  • 好的文件
  • 而且它是开源的

Mastodon:社交媒体集中化的联合答案。

如何安装Windows Terminal

安装Windows Terminal的最简单方法是通过Microsoft Store:

ms-windows-store://pdp/?ProductId=9n0dx20hk701

如果此链接失败,请尝试在浏览器中打开Microsoft Store或从Windows“开始”菜单启动Microsoft Store应用程序,然后搜索“终端”。

注意:注意不要选择早期的“ Windows Terminal Preview”应用程序。

Mastodon:社交媒体集中化的联合答案。

点击获取并等待几秒钟以完成安装。

如果您无权访问商店,则可以从GitHub下载最新版本

Windows终端的应用程序图标,现在在Windows开始菜单。为了更容易访问,请右键单击该图标,然后选择“ 固定到开始”或“ 更多”,然后选择“ 固定到任务栏”

Windows Terminal入门

首次运行时,Windows Terminal以Powershell作为默认配置文件启动。下拉菜单可用于启动其他选项卡并访问设置

Mastodon:社交媒体集中化的联合答案。

尽管可以在全局设置中禁用生成,但是Terminal会自动为您安装的所有WSL发行版和Windows Shell生成配置文件。

管理标签和窗格

通过单击+图标或CtrlShift+ 打开默认配置文件的新标签T。要打开其他配置文件的标签,请从下拉菜单中选择该标签,或按CtrlShiftN,其中N是配置文件的编号。

AltShiftD复制并拆分窗格。每次使用时,活动窗格都会沿最长轴分成两部分:

Mastodon:社交媒体集中化的联合答案。

强制创建:

  • 垂直窗格中,按AltShift+
  • 水平窗格,按AltShift+-

要在新窗格中打开另一个配置文件,请在Alt从下拉菜单中选择时按住该键。

按住Alt并使用光标键在键盘上的活动窗格之间切换。可以通过按住AltShift并使用光标键相应地调整大小来调整窗格的大小。

可以通过双击文本来重命名选项卡。您还可以通过右键单击标签并选择菜单选项来更改名称或颜色:

Mastodon:社交媒体集中化的联合答案。

这只会影响当前标签页;它不会永久更改配置文件。

要关闭活动窗格或选项卡,请按AltShiftW或输入终端的标准退出命令(通常为exit)。

字体大小

活动终端的文本大小可以使用Ctrl+Ctrl+ 调整大小-。或者,按住Ctrl并滚动鼠标滚轮。

卷动

使用滚动条浏览终端输出。或者,按住Ctrl并按下光标上移,光标下移Page UpPage Down使用键盘进行导航。

CtrlShiftF打开搜索框:

Mastodon:社交媒体集中化的联合答案。

输入任何术语,然后使用向上和向下图标搜索终端输出。单击该Aa图标可以激活和取消激活大小写匹配。

复制和粘贴

默认情况下,复制和粘贴必然CtrlShiftCCtrlShiftV分别,虽然CtrlCCtrlV也可以工作。

注意:请警惕CtrlC可以终止Linux应用程序,因此Shift建议使用。

全局设置中提供了一个自动选择时复制选项,您还可以通过右键单击鼠标来粘贴当前剪贴板项目。

设定值

可从下拉菜单或Ctrl,(逗号)访问设置。该配置在单个settings.json文件中定义,因此可能会提示您选择文本编辑器。VS Code是一个不错的选择,尽管如果您希望在不使用颜色编码和语法检查的情况下进行编辑,则记事本就可以了。

settings.json 控制项:

  1. 全局设置,适用于所有配置文件
  2. 配置文件设置,用于定义配置文件
  3. 自定义配色方案设置,以及
  4. 绑定设置

该文件使用以下格式:

// This file was initially generated by Windows Terminal
{

  // general settings, e.g.
  "initialRows": 40,

  // profile settings
  "profiles":
  {

    "defaults":
    {
      // settings that apply to all profiles
    }
    "list":
    [
      // list of individual profiles, e.g.
      {
        "guid": "{81d1dceb-c123-5678-90a1-123abc456def}",
        "name": "Windows PowerShell",
        "commandline": "powershell.exe"
      },
      {
        "guid": "{91d1dceb-c123-5678-90a1-123abc456def}",
        "name": "Ubuntu",
        "source": "Windows.Terminal.Wsl"
      }
    ]

  }

  // custom color schemes, e.g.
  "schemes": [
    {
      "name": "My new theme",
      "cursorColor": "#FFFFFF",
      "selectionBackground": "#FFFFFF",
      "background" : "#0C0C0C",
      "foreground" : "#CCCCCC"
    }
  ],

  // custom key bindings, e.g.
  "keybindings:
  [
    { "command": "find", "keys": "ctrl+shift+f" }
  ]

}

默认值在中定义defaults.json。在下拉菜单中Alt单击“设置”,按住不放即可将其打开。

警告:请勿更改默认文件!使用它来查看默认设置,并在必要时在中添加或更改设置settings.json

全局设置

以下全局设置是最有用的,尽管在终端文档中记录了更多的全局设置。

"defaultProfile" 定义启动Windows终端时用作默认配置文件的GUID。

设置"copyOnSelect"true自动将选定的文本复制到剪贴板,而无需按CtrlShiftC

设置"copyFormatting"false仅复制纯文本而没有任何样式。(我希望这是所有应用程序的默认设置!)

"initialColumns"和设置"initialRows"为水平和垂直尺寸的字符数。

"tabWidthMode" 可以设置为:

  1. "equal":每个标签的宽度相同(默认)
  2. "titleLength":每个标签都设置为其标题的宽度,或者
  3. "compact":不活动的标签会缩小到其图标的宽度。

"disabledProfileSources"设置一个防止配置文件自动生成的数组。例如:

  "disabledProfileSources": [
    "Windows.Terminal.Wsl",
    "Windows.Terminal.Azure",
    "Windows.Terminal.PowershellCore"
  ],

这将禁用所有生成的配置文件。删除您要保留的任何一个。

个人资料设置

新配置文件由定义创建一个对象组"profiles""list"阵列。一个WSL2 Ubuntu示例:

{
  "guid": "{91d1dceb-c123-5678-90a1-123abc456def}",
  "name": "Ubuntu",
  "source": "Windows.Terminal.Wsl",
  "startingDirectory": "//wsl$/Ubuntu/home/username/",
  "colorScheme": "Tango Dark",
  "useAcrylic": true,
  "acrylicOpacity": 0.75,
  "hidden": false
},

每个配置文件均使用以下设置进行定义:

设置 描述
"guid" 唯一标识符(必填)。对于新的配置文件,可以在guidgen.com上在线生成GUID。
"source" 配置文件生成器。仅在自动添加了配置文件且不得对其进行编辑时使用。
"commandline" 假设未"source"设置,则运行的可执行文件。例如,这可能是SSH命令,例如"ssh yourname@domain.com"
"startingDirectory" 目录中的壳开始于对于WSL发行版,这是最好设置为"//wsl$/Ubuntu/home/username/"那里username的用户在安装过程中创建
"name" 下拉菜单中显示的个人资料名称
"tabTitle" 标签标题中显示的名称
"suppressApplicationTitle" true迫使"tabTitle""name"在bash
"icon" 下拉菜单和标签中显示的图标的完整路径,例如"C:/images/tux.png"。24位PNG是最好的选择;不幸的是,不支持SVG
"hidden" 如果设置true,则配置文件不显示在下拉菜单中
"fontFace" 使用特定的字体
"fontSize" 使用特定的字体磅值整数
"fontWeight" 使用特定的字体粗细。这可以是一个整数的OpenType或关键词:"normal""thin""extra-light""light""semi-light""medium""semi-bold""bold""extra-bold""black""extra-black"
"padding" 在窗口边缘的文本周围填充。可以设置一个,两个或四个逗号分隔的值,例如"1, 2, 3, 4"分别设置左,上,右和下
"antialiasingMode" 抗锯齿方法。设置为"grayscale"(默认)"cleartype",或"aliased"
"cursorShape" 游标类型。设置为"bar"(默认), ,"vintage""underscore""filledBox"或者"emptyBox"
"cursorHeight" "vintage"光标的高度,定义为25和之间的整数100
"cursorColor" 光标颜色,定义为"#rgb""#rrggbb"

特定于主题的设置包括:

设置 描述
"colorScheme" 定义的配色方案的名称defaults.json"schemes"列表中的列表settings.json请参见下文
"useAcrylic" 设置true为使用毛玻璃背景效果
"acrylicOpacity" 0(完全透明)到1(完全不透明)的丙烯酸不透明度
"backgroundImage" 背景图像的完整路径,例如 "C:/images/background.png"
"backgroundImageOpacity" 背景图像的不透明度从0(完全透明)到1(完全不透明)

最后,添加"experimental.retroTerminalEffect": true到配置文件以实现复古CRT效果!…

Mastodon:社交媒体集中化的联合答案。

配色方案设置

"colorScheme"可以将每个配置文件设置为中包含的任何配色方案的名称defaults.json。例如:

"Campbell"

Mastodon:社交媒体集中化的联合答案。

"Campbell Powershell"

Mastodon:社交媒体集中化的联合答案。

"One Half Dark"

Mastodon:社交媒体集中化的联合答案。

"One Half Light"

Mastodon:社交媒体集中化的联合答案。

"Tango Dark"

Mastodon:社交媒体集中化的联合答案。

"Tango Light"

Mastodon:社交媒体集中化的联合答案。

"Vintage"

Mastodon:社交媒体集中化的联合答案。

创建自己的配色方案

您可以在中的"schemes"数组中定义自己的方案对象settings.json。每种颜色均以十六进制值定义。例如:

"schemes": [
  {
    "name": "My New Theme",
    "foreground": "#EEEEEE",
    "background": "#111111",
    "cursorColor": "#FFFFFF",
    "black": "#000000",
    "red": "#CC0000",
    "green": "#4E9A06",
    "yellow": "#C4A000",
    "blue": "#3465A4",
    "purple": "#75507B",
    "cyan": "#06989A",
    "white": "#EEEEEE",
    "brightBlack": "#555753",
    "brightRed": "#EF2929",
    "brightGreen": "#8AE234",
    "brightYellow": "#FCE94F",
    "brightBlue": "#729FCF",
    "brightPurple": "#AD7FA8",
    "brightCyan": "#34E2E2",
    "brightWhite": "#FFFFFF"
  }
],

然后可以通过将该方案添加"name"到配置文件的"colorScheme"设置中来使用该方案。例如:

"colorScheme": "My New Theme"

绑定设置

中的"keybindings"数组settings.json会覆盖或补充中设置的默认键绑定defaults.json。每个键绑定都定义为带有"command"和的对象"keys"。例如:

// Ctrl + Shift + F to open the search box
{ "command": "find", "keys": "ctrl+shift+f" },

在某些情况下,"command"可能是"action"具有一个或多个参数的应用程序。例如:

// Ctrl + Shift + 1 to open the first profile in a new tab
{
  "command": { "action": "newTab", "index": 0 },
  "keys": "ctrl+shift+1"
},

"keys"值接受改性剂ctrl+shift+alt+随后:

类型
功能键 f1-f24
字母数字键 a-z, 0-9
符号键 -=[]\;',./
光标键 downleftrightuppagedownpageuppgdnpgupendhomeplus
动作键 tabenterescescapespacebackspacedeleteinsert
数字键盘 numpad_0-numpad_9numpad0-numpad9numpad_addnumpad_plusnumpad_decimalnumpad_periodnumpad_dividenumpad_minusnumpad_subtractnumpad_multiply

例如,如果您想使用Ctrl+ 打开搜索框F,则可以在"keybindings"数组中添加一行settings.json

"keybindings":
[
  { "command": "find", "keys": "ctrl+f" }
]

搜索框也将用CtrlShift+ 打开,F因为该设置是在defaults.json-中定义的,除非您将组合键分配给另一个命令。

命令行选项

Windows Terminal可以通过运行快捷方式或任何Windows或Linux终端启动wt.exe。支持以下选项:

选项 描述
--help-h-?/? 显示帮助
--maximized, -M 发射最大化
--fullscreen, -F 启动全屏

您还可以传递由分号分隔的命令列表。命令用于定义新的选项卡和窗格以及其他控制参数:

命令 参数 描述
new-tab --profile或者-p--startingDirectory或者-dcommandline--title 打开一个新标签页
split-pane --horizontal-H--vertical-V--profile-p--startingDirectory-dcommandline--title 打开一个新窗格
focus-tab --target 要么 -t 聚焦标签

例子

以下示例必须从标准cmd命令行或快捷方式执行。

使用UbuntuWindows Powershell选项卡打开Windows Terminal :

wt -p "Ubuntu" ; new-tab -p "Windows PowerShell"

打开Windows终端用UbuntuWindows Powershell以及Command Prompt配置文件在不同的窗格:

wt -p "Ubuntu" ; split-pane -V -p "Windows PowerShell" ; split-pane -H -p "Command Prompt"

Mastodon:社交媒体集中化的联合答案。

Windows Terminal 文档中提供了从Linux Shell或Powershell启动Windows Terminal的更多示例。

终端对待

希望您喜欢Windows Terminal的介绍。如前所述,它是WSL2的理想伴侣。它快速,可配置,外观精美,并提供Windows和Linux开发的所有优势。

版权所有:https://www.eraycloud.com 转载请注明出处