Skip to content

Commit

Permalink
v0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasott committed Jun 4, 2016
1 parent 39f74d3 commit da889ee
Show file tree
Hide file tree
Showing 470 changed files with 16,068 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.log
*.DS_Store
*Thumbs.db
134 changes: 134 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Webmention Plugin for Craft CMS

This plugin provides a [Webmention](https://www.w3.org/TR/webmention/) endpoint for [Craft CMS](https://craftcms.com).

## Installation

1. Download & unzip the file and place the `webmention/` directory into your `craft/plugins/` directory.
2. -OR- do a `git clone https://github.com/matthiasott/webmention.git` directly into your `craft/plugins` folder. You can then update it with `git pull`.
3. In the Craft Control Panel go to Settings > Plugins and click the “Install” button next to “Webmention”.


## Configuration

### Webmention endpoint
In order to receive Webmentions, the Webmention endpoint for your site needs to be discoverable by the server sending the Webmention. So you will need to add the following line in the <head> section of your main layout template:

```
<link rel="webmention" href="{{ craft.webmention.endpointUrl }}" />
```

And/or you can set an HTTP Link header by adding this line to your main layout template:

```
{% header "Link: <" ~ craft.webmention.endpointUrl ~ ">; rel=\"webmention\"" %}
```

The plugin comes with a „human-friendly“ endpoint that will present a form with input fields for `source` and `target` to users visiting your sites endoint route. The Twig template for the Webmention endpoint will extend your standard template and is copied to `craft/templates/webmention/_index.html` on install. You can then adjust the template to your need. Note: Even if you define a different route for the endpoint, the plugin will still look for the template in this folder.

### Displaying Webmentions
To output all Webmentions for the current request URL, you can use the following helper in your templates:

```
{{ craft.webmention.showWebmentions(craft.request.url) }}
```

### Display a Webmention form for the current URL
You can output a form in your entry template that provides the user with the opportunity to send you the URL of a response.
Simply use this helper:
```
{{ craft.webmention.webmentionForm(craft.request.url) }}
```

## Craft Plugin Settings

The Webmention plugin comes with a settings page for the Craft backend. You can change the following options:

* **Webmention Endpoint Route (Slug)**
Set the URL slug of your Webmention endpoint. Defaults to `webmention`, but you can insert anything that makes sense to you.

* **Webmention Endpoint Layout Template**
The Twig template for the Webmention endpoint will extend your standard template. Tell the plugin which template to use. Default is `_layout`.

* **Maximum Length of Webmention Text**
Set the maximum character count for summaries, comments and text excerpts from posts. Default: `420`

* **Parse Brid.gy Webmentions**
Toggle if you want the plugin to parse [Brid.gy](https://brid.gy) Webmentions.

* **Avatar Storage Folder**
The plugin saves user photos (avatars) for incoming Webmentions for better performance and to avoid exploits. You can set the name of the folder where user avatars will be stored.
*Note: For now, this will create a new subfolder in your default assets folder. So there has to be at least one asset source defined! ;)*
Also, if you change this value, avatars that have been stored before won't be moved to the new path.

## Features

### Receiving Webmentions

When the plugin receives a Webmention, it performs several checks and then parses the source’s HTML with both [php-mf2](https://github.com/indieweb/php-mf2), a generic [microformats-2](http://microformats.org/wiki/microformats-2) parser, and Aaron Parecki’s [php-comments helper](https://github.com/indieweb/php-comments), which returns author info as well as truncated post text for an [h-entry](http://indiewebcamp.com/h-entry). The plugin will try to get all attributes for the data model from the parsed h-entry and also the representative h-card. If no user photo is provided, it will also try to get one from Gravatar as a fallback, using the author’s email from the h-card.

The following attributes are looked up:

* `author_name`
* `author_photo`
* `author_url`
* `published`
* `name`
* `text`
* `target`
* `source`
* `url`
* `site`
* `type`

Lastly, the Webmention record is saved to the database. Already existing Webmentions (which is determined by a comparison of the `source` and `target` of the POST request) are updated in the database.

### XSS Protection
To prevent Cross Site Scripting (XSS) attacks, the HTML of the source first gets decoded (which for example converts `&#00060script>` into `<script>`) and is then purified with [CHTMLPurifier](http://www.yiiframework.com/doc/api/CHtmlPurifier), Yii’s wrapper for [HTML Purifier](http://htmlpurifier.org/), which “removes all malicious code with a thoroughly audited, secure yet permissive whitelist”.

### Brid.gy

You can use Brid.gy for receiving Webmentions for posts, comments, retweets, likes, etc. from Twitter, Instagram, Facebook, Flickr, and Google+. This plugin will understand the Webmention and set the 'type' of the Webmention accordingly. So if someone retweets a tweet with a URL you shared, the Webmention will be of the type 'retweet'. To determine the interaction type, the plugin looks at the brid.gy URL format, for more information on the different types of URLs visit [the section about source URLs on the brid.gy website](https://brid.gy/about#source-urls).

If you don't use Brid.gy you can easily deactivate the parsing in the plugin settings.

### HTTP Responses

The Webmention plugin validates and processes the request and then returns HTTP status codes for certain errors or the successful processing of the Webmention:
* If the URLs provided for `source` and `target` do not match an http(s) scheme, a **400 Bad Request** status code is returned.
* If the specified target URL is not found, a **400 Bad Request** status code is returned.
* Also, if the provided `source` is not linking back to `target`, the answer will be a resounding **400 Bad Request**!
* On success, the plugin responds with a status of **200 OK**.

**Note: Currently, the plugin does not process the Webmention verification asynchronously yet.**

## Thank You!
Thanks to everyone who helped me setting this up:
* [Aaron Parecki](https://aaronparecki.com/) (@aaronpk) for support and feedback – and also for the great work he does related to Webmention.
* [Bastian Allgeier](http://bastianallgeier.com) (@bastianallgeier) for allowing me to get highly inspired by his [Kirby Webmentions Plugin](https://github.com/bastianallgeier/kirby-webmentions)
* [Tom Arnold](https://www.webrocker.de/) (@webrocker) for relentlessly sending test Webmentions. ;)
* [Jeremy Keith](https://adactio.com) (@adactio) for the feedback and also for giving the initial spark.
* Everyone at the IndieWebCamp Düsseldorf 2016 and the IndieWeb Community

## Changelog

### 0.1.0

* First version

## Roadmap
* Process Webmentions asynchronously
* Provide an interface for managing Webmentions (deletion!) in the backend
* Provide an easy way to change how Webmentions are displayed (e. g. grouping y/n)
*

## License

Code released under [the MIT license](https://github.com/matthiasott/webmention/LICENSE).

## Author

Matthias Ott
<mail@matthiasott.com>
<https://matthiasott.com>
<https://twitter.com/m_ott>
21 changes: 21 additions & 0 deletions webmention/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2016 Matthias Ott

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
134 changes: 134 additions & 0 deletions webmention/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Webmention Plugin for Craft CMS

This plugin provides a [Webmention](https://www.w3.org/TR/webmention/) endpoint for [Craft CMS](https://craftcms.com).

## Installation

1. Download & unzip the file and place the `webmention/` directory into your `craft/plugins/` directory.
2. -OR- do a `git clone https://github.com/matthiasott/webmention.git` directly into your `craft/plugins` folder. You can then update it with `git pull`.
3. In the Craft Control Panel go to Settings > Plugins and click the “Install” button next to “Webmention”.


## Configuration

### Webmention endpoint
In order to receive Webmentions, the Webmention endpoint for your site needs to be discoverable by the server sending the Webmention. So you will need to add the following line in the <head> section of your main layout template:

```
<link rel="webmention" href="{{ craft.webmention.endpointUrl }}" />
```

And/or you can set an HTTP Link header by adding this line to your main layout template:

```
{% header "Link: <" ~ craft.webmention.endpointUrl ~ ">; rel=\"webmention\"" %}
```

The plugin comes with a „human-friendly“ endpoint that will present a form with input fields for `source` and `target` to users visiting your sites endoint route. The Twig template for the Webmention endpoint will extend your standard template and is copied to `craft/templates/webmention/_index.html` on install. You can then adjust the template to your need. Note: Even if you define a different route for the endpoint, the plugin will still look for the template in this folder.

### Displaying Webmentions
To output all Webmentions for the current request URL, you can use the following helper in your templates:

```
{{ craft.webmention.showWebmentions(craft.request.url) }}
```

### Display a Webmention form for the current URL
You can output a form in your entry template that provides the user with the opportunity to send you the URL of a response.
Simply use this helper:
```
{{ craft.webmention.webmentionForm(craft.request.url) }}
```

## Craft Plugin Settings

The Webmention plugin comes with a settings page for the Craft backend. You can change the following options:

* **Webmention Endpoint Route (Slug)**
Set the URL slug of your Webmention endpoint. Defaults to `webmention`, but you can insert anything that makes sense to you.

* **Webmention Endpoint Layout Template**
The Twig template for the Webmention endpoint will extend your standard template. Tell the plugin which template to use. Default is `_layout`.

* **Maximum Length of Webmention Text**
Set the maximum character count for summaries, comments and text excerpts from posts. Default: `420`

* **Parse Brid.gy Webmentions**
Toggle if you want the plugin to parse [Brid.gy](https://brid.gy) Webmentions.

* **Avatar Storage Folder**
The plugin saves user photos (avatars) for incoming Webmentions for better performance and to avoid exploits. You can set the name of the folder where user avatars will be stored.
*Note: For now, this will create a new subfolder in your default assets folder. So there has to be at least one asset source defined! ;)*
Also, if you change this value, avatars that have been stored before won't be moved to the new path.

## Features

### Receiving Webmentions

When the plugin receives a Webmention, it performs several checks and then parses the source’s HTML with both [php-mf2](https://github.com/indieweb/php-mf2), a generic [microformats-2](http://microformats.org/wiki/microformats-2) parser, and Aaron Parecki’s [php-comments helper](https://github.com/indieweb/php-comments), which returns author info as well as truncated post text for an [h-entry](http://indiewebcamp.com/h-entry). The plugin will try to get all attributes for the data model from the parsed h-entry and also the representative h-card. If no user photo is provided, it will also try to get one from Gravatar as a fallback, using the author’s email from the h-card.

The following attributes are looked up:

* `author_name`
* `author_photo`
* `author_url`
* `published`
* `name`
* `text`
* `target`
* `source`
* `url`
* `site`
* `type`

Lastly, the Webmention record is saved to the database. Already existing Webmentions (which is determined by a comparison of the `source` and `target` of the POST request) are updated in the database.

### XSS Protection
To prevent Cross Site Scripting (XSS) attacks, the HTML of the source first gets decoded (which for example converts `&#00060script>` into `<script>`) and is then purified with [CHTMLPurifier](http://www.yiiframework.com/doc/api/CHtmlPurifier), Yii’s wrapper for [HTML Purifier](http://htmlpurifier.org/), which “removes all malicious code with a thoroughly audited, secure yet permissive whitelist”.

### Brid.gy

You can use Brid.gy for receiving Webmentions for posts, comments, retweets, likes, etc. from Twitter, Instagram, Facebook, Flickr, and Google+. This plugin will understand the Webmention and set the 'type' of the Webmention accordingly. So if someone retweets a tweet with a URL you shared, the Webmention will be of the type 'retweet'. To determine the interaction type, the plugin looks at the brid.gy URL format, for more information on the different types of URLs visit [the section about source URLs on the brid.gy website](https://brid.gy/about#source-urls).

If you don't use Brid.gy you can easily deactivate the parsing in the plugin settings.

### HTTP Responses

The Webmention plugin validates and processes the request and then returns HTTP status codes for certain errors or the successful processing of the Webmention:
* If the URLs provided for `source` and `target` do not match an http(s) scheme, a **400 Bad Request** status code is returned.
* If the specified target URL is not found, a **400 Bad Request** status code is returned.
* Also, if the provided `source` is not linking back to `target`, the answer will be a resounding **400 Bad Request**!
* On success, the plugin responds with a status of **200 OK**.

**Note: Currently, the plugin does not process the Webmention verification asynchronously yet.**

## Thank You!
Thanks to everyone who helped me setting this up:
* [Aaron Parecki](https://aaronparecki.com/) (@aaronpk) for support and feedback – and also for the great work he does related to Webmention.
* [Bastian Allgeier](http://bastianallgeier.com) (@bastianallgeier) for allowing me to get highly inspired by his [Kirby Webmentions Plugin](https://github.com/bastianallgeier/kirby-webmentions)
* [Tom Arnold](https://www.webrocker.de/) (@webrocker) for relentlessly sending test Webmentions. ;)
* [Jeremy Keith](https://adactio.com) (@adactio) for the feedback and also for giving the initial spark.
* Everyone at the IndieWebCamp Düsseldorf 2016 and the IndieWeb Community

## Changelog

### 0.1.0

* First version

## Roadmap
* Process Webmentions asynchronously
* Provide an interface for managing Webmentions (deletion!) in the backend
* Provide an easy way to change how Webmentions are displayed (e. g. grouping y/n)
*

## License

Code released under [the MIT license](https://github.com/matthiasott/webmention/LICENSE).

## Author

Matthias Ott
<mail@matthiasott.com>
<https://matthiasott.com>
<https://twitter.com/m_ott>
89 changes: 89 additions & 0 deletions webmention/WebmentionPlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
namespace Craft;

class WebmentionPlugin extends BasePlugin
{
function init()
{
// Require dependencies (composer)
require CRAFT_PLUGINS_PATH.'/webmention/vendor/autoload.php';
}

public function getName()
{
return Craft::t('Webmention');
}

public function getVersion()
{
return '0.1.0';
}

public function getDeveloper()
{
return 'Matthias Ott';
}

public function getDeveloperUrl()
{
return 'https://matthiasott.com';
}
public function getDocumentationUrl()
{
return 'https://github.com/matthiasott/webmention';
}
public function getDescription()
{
return 'Receive Webmentions and show them on your site.';
}

public function hasCpSection()
{
return true;
}

public function registerSiteRoutes()
{
// Get endpoint slug from plugin settings
$settings = craft()->plugins->getPlugin('webmention')->getSettings();
$endpointSlug = $settings->endpointSlug;
// Return route for webmention endpoint
return array(
$endpointSlug => array('action' => 'webmention/webmention/handleRequest'),
);
}
protected function defineSettings()
{
// Define Plugin Settings for the CP
return array(
'layout' => array(AttributeType::String, 'required' => false, 'default' => '_layout'),
'endpointSlug' => array( AttributeType::String, 'label' => 'Webmention Endpoint Route (Slug)', 'default' => 'webmention' ),
'maxTextLength' => array( AttributeType::String, 'label' => 'Maximum length for Webmention text', 'default' => '420' ),
'useBridgy' => array( AttributeType::Bool, 'default' => true ),
'avatarPath' => array( AttributeType::String, 'label' => 'Avatar storage path', 'default' => 'avatars/' ),
);
}
public function getSettingsUrl()
{
return 'webmention';
}
public function onBeforeInstall()
{
$craftTemplateFolder = realpath(CRAFT_TEMPLATES_PATH);

if ((!IOHelper::isWritable($craftTemplateFolder)))
{
throw new Exception(Craft::t('Your Template folder is not writeable by PHP. '
. 'Webmention needs PHP to have permissions to create template files. Give PHP write permissions to '
. $craftTemplateFolder . ' and try to install again.'));
}
}
public function onAfterInstall()
{
craft()->webmention_install->run();
}
public function onBeforeUninstall()
{
craft()->webmention_uninstall->run();
}
}
Loading

0 comments on commit da889ee

Please sign in to comment.