Allow Facebook bot to make previews of articles++

This commit is contained in:
nikolark committed 2015-03-31 15:18:27 +02:00
1 parent 2bdb0f1786
commit cfebb2ceff
5 files changed
+607 -11

No files matched your search

+364
View File
@@ -0,0 +1,364 @@
<?php
/*
Plugin Name: Open Graph
Plugin URI: http://wordpress.org/plugins/opengraph
Description: Adds Open Graph metadata to your pages
Author: Will Norris
Author URI: http://willnorris.com/
Version: 1.6
License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html)
Text Domain: opengraph
*/
// If you have the opengraph plugin running alongside jetpack, we assume you'd
// rather use our opengraph support, so disable jetpack's opengraph functionality.
add_filter('jetpack_enable_opengraph', '__return_false');
add_filter('jetpack_enable_open_graph', '__return_false');
/**
* Add Open Graph XML prefix to <html> element.
*
* @uses apply_filters calls 'opengraph_prefixes' filter on RDFa prefix array
*/
function opengraph_add_prefix( $output ) {
$prefixes = array(
'og' => 'http://ogp.me/ns#'
);
$prefixes = apply_filters('opengraph_prefixes', $prefixes);
$prefix_str = '';
foreach ( $prefixes as $k => $v ) {
$prefix_str .= $k . ': ' . $v . ' ';
}
$prefix_str = trim($prefix_str);
if (preg_match('/(prefix\s*=\s*[\"|\'])/i', $output)) {
$output = preg_replace('/(prefix\s*=\s*[\"|\'])/i', '${1}' . $prefix_str, $output);
} else {
$output .= ' prefix="' . $prefix_str . '"';
}
return $output;
}
add_filter('language_attributes', 'opengraph_add_prefix');
/**
* Add additional prefix namespaces that are supported by the opengraph plugin.
*/
function opengraph_additional_prefixes( $prefixes ) {
if ( is_author() ) {
$prefixes['profile'] = 'http://ogp.me/ns/profile#';
}
if ( is_singular() ) {
$prefixes['article'] = 'http://ogp.me/ns/article#';
}
return $prefixes;
}
/**
* Get the Open Graph metadata for the current page.
*
* @uses apply_filters() Calls 'opengraph_{$name}' for each property name
* @uses apply_filters() Calls 'twitter_{$name}' for each property name
* @uses apply_filters() Calls 'opengraph_metadata' before returning metadata array
*/
function opengraph_metadata() {
$metadata = array();
// defualt properties defined at http://ogp.me/
$properties = array(
// required
'title', 'type', 'image', 'url',
// optional
'audio', 'description', 'determiner', 'locale', 'site_name', 'video',
);
foreach ( $properties as $property ) {
$filter = 'opengraph_' . $property;
$metadata["og:$property"] = apply_filters($filter, '');
}
$twitter_properties = array('card');
foreach ( $twitter_properties as $property ) {
$filter = 'twitter_' . $property;
$metadata["twitter:$property"] = apply_filters($filter, '');
}
return apply_filters('opengraph_metadata', $metadata);
}
/**
* Register filters for default Open Graph metadata.
*/
function opengraph_default_metadata() {
// core metadata attributes
add_filter('opengraph_title', 'opengraph_default_title', 5);
add_filter('opengraph_type', 'opengraph_default_type', 5);
add_filter('opengraph_image', 'opengraph_default_image', 5);
add_filter('opengraph_url', 'opengraph_default_url', 5);
add_filter('opengraph_description', 'opengraph_default_description', 5);
add_filter('opengraph_locale', 'opengraph_default_locale', 5);
add_filter('opengraph_site_name', 'opengraph_default_sitename', 5);
// additional prefixes
add_filter('opengraph_prefixes', 'opengraph_additional_prefixes');
// additional profile metadata
add_filter('opengraph_metadata', 'opengraph_profile_metadata');
// additional article metadata
add_filter('opengraph_metadata', 'opengraph_article_metadata');
// twitter card metadata
add_filter('twitter_card', 'twitter_default_card', 5);
}
add_filter('wp', 'opengraph_default_metadata');
/**
* Default title property, using the page title.
*/
function opengraph_default_title( $title ) {
if ( empty($title) ) {
if ( is_singular() ) {
$title = get_the_title( get_queried_object_id() );
} else if ( is_author() ) {
$author = get_queried_object();
$title = $author->display_name;
} else if ( is_category() && single_cat_title( '', false ) ) {
$title = single_cat_title( '', false );
} else if ( is_tag() && single_tag_title( '', false ) ) {
$title = single_tag_title( '', false );
} else if ( is_archive() && get_post_format()) {
$title = get_post_format_string( get_post_format() );
} else if ( is_archive() && function_exists ("get_the_archive_title") && get_the_archive_title() ) { // new in version 4.1 to get all other archive titles
$title = get_the_archive_title();
}
}
return $title;
}
/**
* Default type property.
*/
function opengraph_default_type( $type ) {
if ( empty($type) ) {
if ( is_singular( array('post', 'page') ) ) {
$type = 'article';
} else if ( is_author() ) {
$type = 'profile';
} else {
$type = 'website';
}
}
return $type;
}
/**
* Default image property, using the post-thumbnail and any attached images.
*/
function opengraph_default_image( $image ) {
if ( empty($image) && is_singular() ) {
$id = get_queried_object_id();
$image_ids = array();
// As of July 2014, Facebook seems to only let you select from the first 3 images
$max_images = apply_filters('opengraph_max_images', 3);
// list post thumbnail first if this post has one
if ( function_exists('has_post_thumbnail') ) {
if ( is_singular() && has_post_thumbnail($id) ) {
$image_ids[] = get_post_thumbnail_id($id);
}
}
// then list any image attachments
$attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit',
'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC',
'orderby' => 'menu_order ID') );
foreach ( $attachments as $attachment ) {
if ( !in_array($attachment->ID, $image_ids) ) {
$image_ids[] = $attachment->ID;
if (sizeof($image_ids) >= $max_images) {
break;
}
}
}
// get URLs for each image
$image = array();
foreach ( $image_ids as $id ) {
$thumbnail = wp_get_attachment_image_src( $id, 'medium');
if ($thumbnail) {
$image[] = $thumbnail[0];
}
}
}
return $image;
}
/**
* Default url property, using the permalink for the page.
*/
function opengraph_default_url( $url ) {
if ( empty($url) ) {
if ( is_singular() ) {
$url = get_permalink();
} else if ( is_author() ) {
$url = get_author_posts_url( get_queried_object_id() );
}
}
return $url;
}
/**
* Default site_name property, using the bloginfo name.
*/
function opengraph_default_sitename( $name ) {
if ( empty($name) ) {
$name = get_bloginfo('name');
}
return $name;
}
/**
* Default description property, using the excerpt or content for posts, or the
* bloginfo description.
*/
function opengraph_default_description( $description ) {
if ( empty($description) ) {
if ( is_singular() ) {
$post = get_queried_object();
if ( !empty($post->post_excerpt) ) {
$description = $post->post_excerpt;
} else {
$description = $post->post_content;
}
} else if ( is_author() ) {
$id = get_queried_object_id();
$description = get_user_meta($id, 'description', true);
} else if ( is_category() && category_description() ) {
$description = category_description();
} else if ( is_tag() && tag_description() ) {
$description = tag_description();
} else if ( is_archive() && function_exists("get_the_archive_description") && get_the_archive_description() ) { // new in version 4.1 to get all other archive descriptions
$description = get_the_archive_description();
} else {
$description = get_bloginfo('description');
}
}
// strip description to first 55 words.
$description = strip_tags(strip_shortcodes($description));
$description = __opengraph_trim_text($description);
return $description;
}
/**
* Default locale property, using the WordPress locale.
*/
function opengraph_default_locale( $locale ) {
if ( empty($locale) ) {
$locale = get_locale();
}
return $locale;
}
/**
* Default twitter-card type.
*/
function twitter_default_card( $card ) {
$post_type = apply_filters('opengraph_type', null);
if ( $post_type == 'article' ) {
return "summary";
}
return '';
}
/**
* Output Open Graph <meta> tags in the page header.
*/
function opengraph_meta_tags() {
$metadata = opengraph_metadata();
foreach ( $metadata as $key => $value ) {
if ( empty($key) || empty($value) ) {
continue;
}
$value = (array) $value;
foreach ( $value as $v ) {
printf('<meta property="%1$s" name="%1$s" content="%2$s" />' . "\n",
esc_attr($key), esc_attr($v));
}
}
}
add_action('wp_head', 'opengraph_meta_tags');
/**
* Include profile metadata for author pages.
*/
function opengraph_profile_metadata( $metadata ) {
if ( is_author() ) {
$id = get_queried_object_id();
$metadata['profile:first_name'] = get_the_author_meta('first_name', $id);
$metadata['profile:last_name'] = get_the_author_meta('last_name', $id);
$metadata['profile:username'] = get_the_author_meta('nicename', $id);
}
return $metadata;
}
/**
* Include profile metadata for author pages.
*
* @link http://ogp.me/#type_article
*/
function opengraph_article_metadata( $metadata ) {
if ( is_singular() ) {
$post = get_queried_object();
$tags = wp_get_post_tags($post->ID);
// check if page/post has tags
if ( $tags ) {
foreach ( $tags as $tag ) {
$metadata['article:tag'][] = $tag->name;
}
}
$metadata['article:published_time'] = get_the_time( 'c', $post->ID );
$metadata['article:author:first_name'] = get_the_author_meta('first_name', $post->post_author);
$metadata['article:author:last_name'] = get_the_author_meta('last_name', $post->post_author);
$metadata['article:author:username'] = get_the_author_meta('nicename', $post->post_author);
}
return $metadata;
}
/**
* Helper function to trim text using the same default values for length and
* 'more' text as wp_trim_excerpt.
*/
function __opengraph_trim_text( $text ) {
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
return wp_trim_words($text, $excerpt_length, $excerpt_more);
}
+126
View File
@@ -0,0 +1,126 @@
=== Open Graph ===
Contributors: willnorris, pfefferle
Tags: social, opengraph, ogp, facebook
Requires at least: 2.3
Tested up to: 4.1
Stable tag: 1.6
License: Apache License, Version 2.0
License URI: http://www.apache.org/licenses/LICENSE-2.0.html
Adds Open Graph metadata to your posts and pages so that they look great when
shared on sites like Facebook and Google+.
== Description ==
The [Open Graph protocol][] enables any web page to become a rich object in a
social graph. Most notably, this allows for these pages to be used with
Facebook's [Like Button][] and [Graph API][] as well as within [Google+][]
posts.
The Open Graph plugin inserts the Open Graph metadata into WordPress posts and
pages, and provides a simple extension mechansim for other plugins and themes
to override this data, or to provide additional Open Graph data.
This plugin does not directly add social plugins like the Facebook Like Button
or the Google [+1 Button][] to your pages (though they're pretty simple to
add). It will however make your pages look great when shared using those kinds
of tools.
[Open Graph Protocol]: http://ogp.me/
[Like Button]: https://developers.facebook.com/docs/reference/plugins/like
[Graph API]: https://developers.facebook.com/docs/reference/api/
[Google+]: http://www.google.com/+
[+1 Button]: https://developers.google.com/+/plugins/+1button/
== Frequently Asked Questions ==
= How do I configure the Open Graph plugin? =
You don't; there's nothing to configure and there is no admin page. By
default, it will use whatever standard WordPress data it can to populate the
Open Graph data. There are very simple yet powerful filters you can use to
modify or extend the metadata returned by the plugin, described below.
= How do I extend the Open Graph plugin? =
There are two main ways to provide Open Graph metadata from your plugin or
theme. First, you can implement the filter for a specific property. These
filters are of the form `opengraph_{name}` where {name} is the unqualified Open
Graph property name. For example, if you have a plugin that defines a custom
post type named "movie", you could override the Open Graph 'type' property for
those posts using a function like:
function my_og_type( $type ) {
if ( get_post_type() == "movie" ) {
$type = "movie";
}
return $type;
}
add_filter( 'opengraph_type', 'my_og_type' );
This will work for all of the core Open Graph properties. However, if you want
to add a custom property, such as 'fb:admin', then you would need to hook into
the `opengraph_metadata` filter. This filter is passed an associative array,
whose keys are the qualified Open Graph property names. For example:
function my_og_metadata( $metadata ) {
$metadata['fb:admin'] = '12345,67890';
return $metadata;
}
add_filter( 'opengraph_metadata', 'my_og_metadata' );
Note that you may need to define the RDFa prefix for your properties. Do this
using the `opengraph_prefixes` filter.
== Changelog ==
Project maintined on github at
[willnorris/wordpress-opengraph](https://github.com/willnorris/wordpress-opengraph).
= version 1.6 (Dec 30, 2014) =
- implemented `get_the_archive_title` and `get_the_archive_description` (new in WordPress 4.1)
- basic twitter cards support (thanks to elroyjetson)
- replace `$post->post_title` with `get_the_title()` (see #[17][] for details)
[17]: https://github.com/willnorris/wordpress-opengraph/issues/17
= version 1.5.1 (Nov 13, 2012) =
- fix duplicate opengraph markup when used with jetpack plugin (for real)
= version 1.5 (Nov 13, 2012) =
- include descriptions on tag and category pages
- include profile metadata on author pages
- fix bug with 404 pages include extra og:image values
- general code cleanup (including removal of dependency on global vars)
- fix duplicate opengraph markup when used with jetpack plugin
= version 1.4 (Aug 24, 2012) =
- better default description
- include all images that are attached to a post, so that users can choose
which to use when sharing the page. If the post has a post thumbnail, that
is still used as the primary image.
= version 1.3 (May 21, 2012) =
- add 'opengraph_prefixes' filter for defining additional prefixes
- add new basic properties, and remove some old ones. This is a breaking
change for anyone that was using the old properties, but they can always be
added using the 'opengraph_metadata' filter. (see [f476552][] for details)
- updates to many default values, particularly for individual posts and pages
(thanks pfefferle)
- add basic support for array values (see [d987eb7][])
[f476552]: https://github.com/willnorris/wordpress-opengraph/commit/f47655202d59c0e5b5032b4b86764f7a87813640
[d987eb7]: https://github.com/willnorris/wordpress-opengraph/commit/d987eb76e2da1431e5df3311fde3d9c2407b06f5
= version 1.2 (Feb 21, 2012) =
- switch to newer RDFa prefix syntax rather than XML namespaces (props
pfefferle)
= version 1.1 (Nov 7, 2011) =
- fix function undefined error when theme doesn't support post thumbnails
= version 1.0 (Apr 24, 2010) =
- initial public release
+94 -5
View File
@@ -171,8 +171,6 @@ add_filter( 'excerpt_more', 'neuf_excerpt_more' );
/* Save user meta options */
function neuf_save_user_meta() {
global $wpdb;
$user_id = (int) $_POST['user_id'];
$meta_key = $_POST['meta_key']; // TODO: sanitize
$meta_value = $_POST['meta_value']; // TODO: sanitize
@@ -202,8 +200,6 @@ add_action( 'wp_ajax_neuf_save_user_meta', 'neuf_save_user_meta' );
/* Save user meta options */
function neuf_get_user_meta() {
global $wpdb;
$user_id = (int) $_GET['user_id'];
$meta_key = $_GET['meta_key']; // TODO: sanitize
$single = (bool) $_GET['single'];
@@ -241,7 +237,7 @@ function get_feed_url() {
if(is_user_logged_in()) {
$user = wp_get_current_user();
$feedkey = get_usermeta($user->ID, 'feed_key');
$feedkey = get_user_meta($user->ID, 'feed_key', true);
$feedurl .= "?feedkey=$feedkey";
}
return $feedurl;
@@ -307,4 +303,97 @@ add_action( 'customize_register', 'neuf_customize_register' );
require_once('neuf_widgets.php');
/* The following allows the Facebook bot and the login page to leak
the title, excerpt and image info to users that are not logged in.
*/
add_action( 'restrict_site_access_handling', 'my_restrict_site_access_handling' );
function my_restrict_site_access_handling( $rsa_restrict_approach) {
global $wp;
$rsa_options = (array) get_option( 'rsa_options' );
if( $rsa_restrict_approach == 4 && !empty($rsa_options['page']) && ($page_id = get_post_field('ID', $rsa_options['page']))) {
$wp->query_vars_restricted = $wp->query_vars; // Backup for later
}
}
function get_restricted_post() {
global $wp;
if( $wp->query_vars_restricted == null ) {
return null;
}
$q = new WP_Query($wp->query_vars_restricted);
if (!$q->have_posts()) {
return null;
}
return $q->posts[0];
}
function restricted_title($title){
$post = get_restricted_post();
if($post == null) {
return $title;
}
return $post->post_title;
}
add_filter('wp_title', 'restricted_title');
add_filter('opengraph_title', 'restricted_title');
/* Mostly copied from opengraph plugin */
function restricted_image($image){
$post = get_restricted_post();
if($post == null) {
return $image;
}
$id = $post->ID;
$image_ids = array();
// As of July 2014, Facebook seems to only let you select from the first 3 images
$max_images = 3;
// list post thumbnail first if this post has one
if ( has_post_thumbnail($id) ) {
$image_ids[] = get_post_thumbnail_id($id);
}
// then list any image attachments
$attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit',
'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC',
'orderby' => 'menu_order ID') );
foreach ( $attachments as $attachment ) {
if ( !in_array($attachment->ID, $image_ids) ) {
$image_ids[] = $attachment->ID;
if (sizeof($image_ids) >= $max_images) {
break;
}
}
}
// get URLs for each image
$image = array();
foreach ( $image_ids as $id ) {
$thumbnail = wp_get_attachment_image_src( $id, 'full');
if ($thumbnail) {
$image[] = $thumbnail[0];
}
}
return $image;
}
add_filter('opengraph_image', 'restricted_image');
function restricted_url($url){
$post = get_restricted_post();
if($post == null) {
return $url;
}
if ( is_singular() ) {
$url = get_permalink($post->ID);
}
return $url;
}
add_filter('opengraph_url', 'restricted_url');
?>
-3
View File
@@ -11,7 +11,6 @@
<meta name="x-user-id" content="<?php echo $user->ID; ?>" />
<meta name="x-siteurl" content="<?php echo get_option('siteurl'); ?>" />
<title><?php wp_title('|', true, true); ?></title>
<link rel="icon" type="image/png" href="favicon.ico" />
<link rel="alternate" type="application/rss+xml" href="<?php echo get_feed_url(); ?>" title="aktiv.neuf.no - Nyheter" />
@@ -19,8 +18,6 @@
<link href='//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,700,800,600' rel='stylesheet' type='text/css'>
<?php wp_head(); ?>
<script src="<?php bloginfo( 'stylesheet_directory' ); ?>/dist/scripts/vendor.js"></script>
<script>jQuery.migrateMute = true;</script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.js"></script>
<script src="<?php bloginfo( 'stylesheet_directory' ); ?>/dist/scripts/main.js"></script>
+23 -3
View File
@@ -2,7 +2,8 @@
/*
* Template Name: Login
*/
?>
$restricted_post = get_restricted_post();
?>
<?php get_header(); ?>
@@ -10,11 +11,30 @@
<div id="content">
<div class="introduction">
<h3>Logg inn for å fortsette</h3>
<?php the_post(); the_content(); ?>
<?php if($restricted_post && $restricted_post->post_type == 'post'): ?>
<div class="restricted-post">
<div class="text-body">
<div>
<h3 class="entry-title"><a href="#"><?php echo $restricted_post->post_title; ?></a></h3>
<div class="entry-meta byline"><span class="meta-prep meta-prep-author">av </span><span class="author vcard"><a href="<?php echo get_author_posts_url($restricted_post->post_author); ?>"><?php echo the_author_meta( 'display_name' , $restricted_post->post_author); ?></a></span>, <span class="entry-date"><?php echo get_the_time(get_option( 'date_format' ) ." ". get_option( 'time_format' ), $restricted_post->ID ); ?></span></div>
</div>
<?php echo get_the_post_thumbnail($restricted_post->ID, 'full'); ?>
<?php echo wp_trim_words( $restricted_post->post_content ) ?>
</div>
</div>
<?php endif; ?>
<div class="text-body">
<?php if($restricted_post && $restricted_post->post_type == 'post'): ?>
<h4>Logg inn for å lese resten</h4>
<?php else: ?>
<h4>Logg inn for å fortsette</h4>
<?php endif; ?>
<?php the_post(); the_content(); ?>
</div>
</div>
<div class="login-form">
<h4>Logg inn</h4>
<?php
$args = array(
'form_id' => 'loginform-custom',