WordPress文章统计阅读时间估算

WordPress文章统计阅读时间估算

/**
* Gets the total word count and expected time to read the article
* @return type array
*/
function wp_reading_time_and_word_count() {
global $post;
// Predefined words-per-minute rate.
$words_per_minute = 225;
$words_per_second = $words_per_minute / 60;
// Count the words in the content.
$word_count = 0;
$text = trim( strip_tags( @get_the_content() ) );
if(!$text && is_object($post)){
$text = $post->post_content;
}
$word_count = substr_count( "$text ", ' ' );
// How many seconds (total)?
$seconds = floor( $word_count / $words_per_second );
$timereq = '';
if($seconds > 60){
$minutes = floor($seconds/60);
$seconds_left = $seconds % 60;
$timereq = 'PT'.$minutes.'M'.$seconds_left.'S';
}else{
$timereq = 'PT'.$seconds.'S';
}
return array('word_count' => esc_attr($word_count), 'timerequired' => esc_attr($timereq));
}

WordPress xmlrpc.php 存在SSRF漏洞

如果不使用离线发布文章,可以直接删掉xmlrpc.php这个文件,但是每次升级wordpress这个文件又会回来。彻底解决问题的办法,可以考虑通过APACHE的.htaccess屏蔽xmlrpc.php文件的访问。

配置代码如下:

# protect xmlrpc
<Files "xmlrpc.php">
Order Allow,Deny
Deny from all
</Files>

完美解决

每个WordPress网站5个有用的插件

我已经使用WordPress超过5年了,并且我玩过很多插件。插件是任何WordPress网站的重要组成部分。每个WordPress网站都是唯一的,我们用于该网站的插件将取决于该网站的功能。在这里,我将列出一些对任何WordPress网站都至关重要的插件,无论其功能如何。我将在这里讨论的插件与站点的功能无关。这些插件不会向网站的前端添加任何新内容(一个除外)。它们是有助于从后端进行站点维护和易用性的工具。

有很多插件,其中大多数都非常好。我在这里提到的插件是我一直在使用或已经在客户站点上使用过的插件,而且我知道它运行得很好。以下是没有特定顺序的插件。对于这些插件中的每一个,我们将研究为什么这些插件很重要,每种插件易于使用的插件以及企鹅的一些细节。

备份插件
安全插件
SEO插件
联系表格插件
增强所见即所得编辑器功能的插件
让我们详细了解它们:

备份插件
为什么备份插件很重要?

它们使您轻松备份网站。定期备份您的站点非常重要。即使您的托管服务提供备份,对您的站点进行备份仍然是一个好习惯。将备份存储在远离站点的位置也很重要,这样,如果站点受到恶意软件的影响,则可以从备份中还原它。将备份保存在云服务器(Dropbox,OneDrive,Amazon S3等)中始终是一个好主意。

备份插件为您提供了所有这些功能以及更多功能。只需单击一个按钮,便可以非常轻松地进行备份。他们为您提供了自动将备份文件通过电子邮件发送给您自己或将备份发送到云服务器的选项。您还可以计划备份,而不必担心它。

我已经使用了两个非常好的备用企鹅。

BackWpUP – https://wordpress.org/plugins/backwpup/
这是一个带有pro选项的免费插件。对于大多数网站,免费版本可以正常工作。它非常容易设置,并且还提供了一些教程来帮助您入门。免费版具有用于备份到Microsoft Azure,Dropbox,Rackspace云文件,FTP服务器,Web空间和Sugar Sync的选项。

UpDraftPlus – https://wordpress.org/plugins/updraftplus/
这也是一个带有pro选项的免费插件,对大型网站也可以使用。目前,我在客户的网站之一上使用它,其中包含很多图片。备份很快完成,并发送到Dropbox。设置非常简单,免费版本具有备份到Dropbox,Gogle驱动器,FTP,S3,Rackspace和电子邮件的选项。

安全插件
为什么安全插件很重要?

安全插件可以保护您的WordPress网站。任何WordPress网站都需要安全插件。我遇到了很多人,他们说他们没有任何电子商务,或者说他们的网站很小,因此他们不使用安全插件。但是,无论大小,无论是否电子商务,都需要确保您的网站安全。网站由于密码不足,插件或主题中的漏洞或网站不是最新版本而被黑客入侵。服务器漏洞也可能导致您的网站被黑客入侵。因此,您的网站必须安全。

几个最受欢迎的安全性插件,以及每个插件的一些功能。

WordFence – https://www.wordfence.com/
为您提供详细的IP信息
扫描恶意软件
维修档案
阻止蛮力攻击
国家封锁
的iThemes安全- https://ithemes.com/security/
暴力保护
文件更改检测
强大的密码执行
隐藏登录名和管理员
SEO插件
搜索引擎将流量吸引到您的网站,因此您要确保您具有用户要搜索的术语。SEO插件使您可以更轻松地为每个页面添加关键字和元描述,并在您的网站上发布。实际上,它们具有许多有助于SEO的功能。

最受欢迎的SEO插件是Yoast SEO(以前称为Yoast的WordPress SEO)。它有一个免费和高级版本。易于安装,并具有许多功能-帖子标题和元描述,面包屑,XML Sitemaps等。对于一个小型网站,免费版本应该是相当不错的。

谷歌分析

我想在此提及Google Analytics(分析),因为它与您的SEO紧密相关。Google Analytics(分析)是一项网络分析服务,可跟踪和报告网站流量。如果您想改善SEO,则还应该使用Google Analytics(分析)跟踪您的网站。它为您提供有关网站的大量统计信息,例如访问您的网站的人数,他们浏览过的页面,网站上最受欢迎的页面等。它还为您提供有关人们用来搜索您的网站的关键字的信息。这有助于SEO,因为您可以评估关键字并进行改进。

Google Analytics(分析)是免费的。您可以使用您的Google帐户登录并获取您网站的跟踪代码。设置网站后,您可以登录Google Analytcs网站查看数据,也可以安装Google Analytics(分析)插件,该插件将在wp-admin仪表板中向您显示数据。有许多不同的Google Analytics(分析)插件。我提到了我使用的那个。

联络表格
联系表格是任何网站中最重要的部分。它们必须简单易用。最受欢迎的联系表单插件是Contact Form 7。设置非常容易,您的网站上可以有不同类型的联系表。您可以指定必填字段,在下拉列表中可以具有多个电子邮件地址等。可以自定义样式以匹配您的主题(为此您需要了解一些CSS)。您还可以在带有reCaptcha的表单中添加验证码功能。

增强所见即所得编辑器功能的插件
所见即所得编辑器使在帖子和页面上编写内容变得非常容易。它提供了许多工具来通过更改字体大小和颜色来设置文本样式。但是,默认的“所见即所得”编辑器中缺少一些功能。TinyMCEAdvanced改进了编辑器的功能。他们可以直接从编辑器中添加功能,例如添加表格或为文本添加背景色等。当您要在帖子或页面中插入简单表格时,它非常方便。

该TinyMCE的小工具插件,让你在你的侧边栏一个可爱的小部件。您可以使用它而不是文本窗口小部件,并在侧栏中获得帖子/页面编辑器的所有功能。

这里还有一些可以提及的插件,这些插件可能对大多数站点有用。

JetPack – 打包在一起的大量不同插件。您可以启用或禁用单个模块。

Wp缓存 –帮助缓存站点,以便页面加载更快

损坏的链接检查器 –如果站点上有很多页面,则可以使用此插件跟踪不同页面/帖子中的所有链接。它可以显示链接是否断开,以便您进行修复。

Wp帮助 –有用的小插件,您可以在其中编写有用的说明来管理站点。

使用Ajax添加WordPress帖子

许多WordPress主题和插件都带有一些演示数据(帖子和页面),用户可以在激活插件时安装它们。这些WordPress帖子和页面旨在为用户提供设置主题或插件的先机,并为他们提供一些随时可用的虚拟数据供您使用。

在Chamber Dashboard插件中,尽管我们有大量的文档和几个演示站点供用户查看,但是对于某些用户而言,要直观地看到其主题的业务目录页面仍然不容易。因此,我们决定添加一些演示内容,这些内容将在用户首次在其站点上激活Business Directory插件时安装。

用于添加演示数据的按钮
演示数据按钮在欢迎页面上以模态显示。使用jQuery .dialog()函数显示模式。


$("#demo_content_buttons").dialog({
modal: true,
buttons: [
{
text: "Ok",
click: function() {
$( this ).dialog( "close" );
}
}
]
});

这是用于添加演示数据按钮的html。“ loader” div将显示何时添加数据以及完成数据时,消息将显示在success_message div中。最初,加载器div使用jQuery隐藏。


function cdash_install_demo_content_button(){
?>
<div id="demo_content_buttons">
<p>Welcome to the Business Directory plugin! Install demo content now, then check out the Business Directory page to see a sample Directory, or dismiss this notice to get started with uploading your own listings.</p>
<p class="demo_content button cdash_admin button-primary">Install Demo Content</p>
<p class="demo_content_decline button cdash_admin button-primary">No Thanks!</p>
<p id="loader">Loading...</p>
<p class="cdash_demo_success_message"></p>
</div>
<?php
}
$("#loader").css("display", "none");

设置瞬态
此功能的基本要求之一是,演示数据安装按钮仅在用户首次安装并激活插件时才显示。已经使用过它的用户在将其插件更新到新版本时不应看到它。因此,为了照顾这两种情况,我添加了一个瞬态。首次激活插件时,瞬态将设置为true。仅在未设置瞬变的情况下,演示数据按钮才会显示。


//If plugin is activated for the first time, set the transient
function cdash_show_demo_buttons(){
//$demo_content_install = get_transient('cdash_demo_content_install');
if(false === get_transient('cdash_demo_content_install')){
//show the Install Demo Content button
cdash_install_demo_content_button();
}
set_transient('cdash_demo_content_install', 'true');
}

如果插件已更新,则瞬变也设置为true。这样可以确保如果用户只是在更新插件,他们将不会看到弹出窗口询问他们是否要安装演示数据。


function cdash_set_demo_transient(){
set_transient('cdash_demo_content_install', 'true');
}
add_action( 'upgrader_process_complete', 'cdash_set_demo_transient');

Ajax调用演示数据
实际的演示数据将通过单击“安装”按钮时触发的Ajax调用添加。

$(".demo_content.button").click(function(event){
event.preventDefault();
$.ajax({
url: ajaxurl,
type:'post',
data: {
'action': 'cdash_add_demo_data',
},
beforeSend: function() {
$('#loader').show();
$(".demo_content_decline").hide();
},
complete: function(){
$('#loader').hide();
$(".dashboard_page_cdash-about .ui-dialog-buttonpane").show();
},
success: function(response){
$(".cdash_demo_success_message").html(response);
},
});
});

Ajax函数调用cdash_add_demo_data()函数。该功能添加了业务类别,演示业务和几个演示页面。如果页面或帖子已经存在,将不再创建。


function cdash_add_demo_data(){
$response = '';
//Create demo business categories
cdash_demo_bus_categories();
//Creating demo businesses
$demo_post_id = cdash_insert_demo_business();
//Creating demo pages
$demo_page_id = cdash_add_demo_pages();
//Check if there the post or page exists
if ( ($demo_post_id != 0) || $demo_page_id !=0 )
{
//If post or page does not exists
$response = 'Demo data successfully added.';
}
else {
//Post or page exists
$response = 'The data already exists.';
}
// Return the String
die($response);
}
// creating Ajax call for WordPress
add_action( 'wp_ajax_cdash_add_demo_data', 'cdash_add_demo_data' );

让我们更详细地看一下添加演示内容功能。使用wp_insert_term()添加类别。添加业务类别的功能将检查该类别是否已经存在,以避免任何重复的类别。

下一步是添加业务。演示内容位于数组中。演示按钮将在自定义帖子类型“ business”中安装3个新帖子。第一步是创建post对象。


// Create post object
$demo_content = "Create a description for your business here, or install the Member Updater plugin so your members can update their own listings!";
$demo_bus_data = array(
array (
'title' => 'Karleton’s Bakery',
'content' => $demo_content,
'post_category' => 'Restaurants',
'featured_image' => 'images/demo_content/bakery_photogy-karlis-dambrans.jpg',
),
array (
'title' => 'Wong’s Coffee & Tea',
'content' => $demo_content,
'post_category' => 'Restaurants',
'featured_image' =>'images/demo_content/coffee_shopphotoby-jason-wong.jpg',
),
array (
'title' => 'Brendon’s Camera',
'content' => $demo_content,
'post_category' => 'Retail Shops',
'featured_image' =>'images/demo_content/camera_shop_photoby-brendan-church.jpg',
),
);

下一步是遍历post对象并插入post。


foreach ($demo_bus_data as $bus_demo) {
if ( post_exists( $bus_demo['title'] ) ) {
$demo_post_id = 0;
}else{
//post exists
$add_pages = array(
'post_title' => $bus_demo['title'],
'post_content' => $bus_demo['content'],
'post_status' => 'publish',
'post_type' => 'business'
);
// Insert the post into the database
$demo_post_id = wp_insert_post( $add_pages );
}

然后,需要设置帖子的类别。

wp_set_object_terms( $demo_post_id, $bus_demo['post_category'], 'business_category', $append );

由于演示数据用于企业目录,因此我想为演示企业添加特色图片。我将图像添加到插件内的文件夹中,并从路径生成了图像URL。url和post_id用于将图像上传到媒体库并将其添加到帖子中。cdash_insert_attachment_from_url()使用来自
https://gist.github.com/m1r0/f22d5237ee93bcccb0d9的代码 添加特色图片。

//attach the image files as featured image for each post
$getImageFile = plugins_url( $bus_demo['featured_image'], dirname(__FILE__) );
$url = $getImageFile;
$attach_id = cdash_insert_attachment_from_url($url, $demo_post_id);
set_post_thumbnail( $demo_post_id, $attach_id );

用于插入具有内容和特色图像的演示业务的完整代码。

function cdash_insert_demo_business(){
//Code to create a post with demo data
global $wpdb;
$user_id = get_current_user_id();
// Create post object
$demo_content = "Create a description for your business here, or install the Member Updater plugin so your members can update their own listings!";
$demo_bus_data = array(
array (
'title' => 'Karleton’s Bakery',
'content' => $demo_content,
'post_category' => 'Restaurants',
'featured_image' => 'images/demo_content/bakery_photogy-karlis-dambrans.jpg',
),
array (
'title' => 'Wong’s Coffee & Tea',
'content' => $demo_content,
'post_category' => 'Restaurants',
'featured_image' =>'images/demo_content/coffee_shopphotoby-jason-wong.jpg',
),
array (
'title' => 'Brendon’s Camera',
'content' => $demo_content,
'post_category' => 'Retail Shops',
'featured_image' =>'images/demo_content/camera_shop_photoby-brendan-church.jpg',
),
);
foreach ($demo_bus_data as $bus_demo) {
if ( post_exists( $bus_demo['title'] ) ) {
$demo_post_id = 0;
}else{
//post exists
$add_pages = array(
'post_title' => $bus_demo['title'],
'post_content' => $bus_demo['content'],
'post_status' => 'publish',
'post_type' => 'business'
);
// Insert the post into the database
$demo_post_id = wp_insert_post( $add_pages );
wp_set_object_terms( $demo_post_id, $bus_demo['post_category'], 'business_category', $append );
//attach the image files as featured image for each post
$getImageFile = plugins_url( $bus_demo['featured_image'], dirname(__FILE__) );
$url = $getImageFile;
$attach_id = cdash_insert_attachment_from_url($url, $demo_post_id);
set_post_thumbnail( $demo_post_id, $attach_id );
}
}
return $demo_post_id;
}

添加帖子后,还将添加两个新页面。这些页面的添加类似于帖子,只是“ post_type”将是“ page”而不是“ business”(这是自定义帖子类型)。由于页面没有类别或特色图像,因此仅创建post对象并循环遍历即可添加页面。该功能还检查页面是否已存在,以避免重复页面。

如何使用wp.template,WordPress的Underscore.js模板方法

像许多开发人员机构一样,我们有一些不同的受众群体,包括客户(当前和潜在)和其他开发人员。我们的目标是为拥有广泛技术知识的所有受众提供服务。即使您不是专业的开发人员,我们也知道许多人仍然在自己的网站上使用自己的技术进行教育,并且我们希望为您提供帮助!如果有我们不了解的内容(或者您希望看到与WordPress相关的任何内容,甚至101!),请告诉我们。没有愚蠢的问题。

就是说,让我们开始有趣的事情:WordPress的Underscore.js模板方法 wp.template

如果您还不熟悉,wp.template()那是WordPress核心“ wp-util”脚本提供的一个很棒的JavaScript小实用程序方法。它的核心是使用 Underscorejs .template() 方法。

WordPress使用此实用程序为所有主干视图加载模板,但是使用主干不是必需的。首先,我将演示如何使用 wp.template() 少量jQuery将一些JavaScript数据输出到HTML模板中,然后作为奖励,我们将重新构建 wp.template() 具有某些附加功能的模块。

请记住:这只是一个尽可能简单的示例,而不是您要复制/粘贴到生产代码中的示例。请继续遵循标准的最佳做法,包括将JavaScript放入自己的文件中,避免使用匿名函数,对文本字符串进行国际化等。

默认情况下,该方法需要ID为的脚本标签tmpl-my-template-name。因为所有的WordPress都使用此模板方法/系统,所以您将需要确保正确添加ID前缀,以免与页面上可能加载的其他模板冲突。该脚本标签还应具有“ text/template” 类型。1个

让我们开始吧:

<?php
function zao_item_status_tmpl() {
?>
<script type="text/template" id="tmpl-zao-item-status">
<span class="zao-status" data-id="{{ data.id }}">
<# if ( data.status.name ) { #>
<div class="zao-item-status">
<span class="zao-status-color" style="display: inline-block;background-color:{{ data.status.color }};width:10px; height:10px;"></span>
{{{ data.open }}}
{{ data.status.name }}
{{{ data.close }}}
</div>
<# } else { #>

<# } #>
</span>
</script>
<?php }

因此,现在我们可以使用具有唯一ID的PHP函数准备好合适的脚本模板标记了tmpl-zao-item-status。如您所见,这不是100%标准的HTML。您可以看到我们正在使用基于Mustache启发的数据变量以及Underscorejs逻辑块。

从食典:

WordPress使用定义了自己的插值标签,_.template( options )以避免在某些asp_tags启用了PHP的配置中不兼容。WordPress特定的插值语法受Mustache模板语法的启发:

插值(未转义): {{{ }}}
插值(转义): {{ }}
评估: <# #>
需要理解的重要一点是<# and #>,它表示原始JavaScript输出的打开/关闭,因此您可以执行逻辑运算符之类的操作(如if 上述示例中的语句)。您还可以看到在输出data.open 和data.close 参数时,我们正在利用未转义的插值,因为这些参数将包含HTML,并且我们不希望转义。

在这一点上,让我们进入WordPress,以便我们可以实际看到它。

将此代码段添加到主题的functions.php文件或自定义插件中的某个位置:

<?php
// Output this at the top of the post-edit screen just below the title input.
add_action( 'edit_form_after_title', function() {
?>
<span class="zao-status"><span style="display: inline-block;background-color:red;width:10px; height:10px;"></span> Please wait...</span>
<?php
} );

如果转到新帖子或编辑后的屏幕,应该会看到以下内容:

这对我们没有多大帮助。我们将需要一些JavaScript设置来获取更新的状态并更新状态标记。为简化起见,我们将通过设置短暂的延迟来简单地伪造AJAX请求。您还可以使用Zao Mock API之类的东西 来模拟一些API请求/响应。

JavaScript:

<?php
function zao_item_status_js() {
?>
<script type="text/javascript">
// Wait for the dom to be ready..
jQuery( function( $ ) {
// Get the template function corresponding to our template markup.
var template = wp.template( 'zao-item-status' ); // uses script tag ID minus "tmpl-"
// Let's wait a tick, so we can see it go from yellow to green.
setTimeout( function() {
// Let's fake some data (maybe this is data from an API request?)
var tmplData = {
id: 1,
status: {
name: 'Success!',
color: 'green'
},
open: '<span class="status-name" style="color:green">',
close: '</span>'
};
// Send the data to our new template function, get the HTML markup back.
var html = template( tmplData );
// Now let's replace the contents of the existing markup with our updated template markup.
$( '.zao-status' ).html( html );
}, 1000 );
});
</script>
<?php
}

代码注释应该是不言自明的,但要概括一下:

wp.template() 使用我们之前创建的脚本标签的ID 减去 前缀进行调用tmpl-
通过设置一秒钟的延迟来伪造API请求
生成数据对象,并将其传递给我们的新模板函数,该函数返回已编译的HTML
使用该HTML并替换现有的HTML。
现在,我们在PHP函数中提供了JavaScript输出,可以将其连接到页脚中。我们几乎需要完成所有工作,因此让我们更新edit_form_after_title匿名函数:

<?php
// Output this at the top of the post-edit screen just below the title input.
add_action( 'edit_form_after_title', function() {
// Hook in our template script tag to the footer.
add_action( 'admin_footer', 'zao_item_status_tmpl' );
// Hook in our custom JS for updating the status.
add_action( 'admin_footer', 'zao_item_status_js' );
// Now, enqueue the WP util script so we can use wp.template
wp_enqueue_script( 'wp-util' );
// Make the initial output have a yellow status square
?>
<span class="zao-status"><span style="display: inline-block;background-color:#ffe24d;width:10px; height:10px;"></span> Please wait...</span>
<?php
} );

这样,我们应该看到状态从黄色(“请稍候……”)变为绿色(“成功!”)。

希望这个基本示例可以帮助您开始 wp.template() 在自己的工作中使用,但是如果您有任何疑问,请在下面留下评论。

此示例代码段的完整输出可以在此处找到。

如果您仍然与我在一起:既然我们已经介绍了WordPress实用程序的基础知识,那么您可能会对基于wp.template() 我创建的类似实用程序_templatize感兴趣。该脚本通过结合模板获取和数据发送略微简化了上述步骤,并且还提供了允许通过向模板传递HTML字符串(与tmpl- dom中的script标记绑定)来创建模板的功能。另外,您可以看到上面的代码片段已更新为在此处使用_templatize。

WordPress使用自带方法生成和验证密码的方法

在WordPress中主要用到两个函数wp_hash_password()和wp_check_password()来对文本进行生成密文和对密文的验证。wp_hash_password() 把一个文本生成加密密文。

function wp_hash_password($password) {
global $wp_hasher;
if ( emptyempty($wp_hasher) ) {
require_once( ABSPATH . WPINC . '/class-phpass.php');
// By default, use the portable hash from phpass
$wp_hasher = new PasswordHash(8, true);
}
return $wp_hasher->HashPassword( trim( $password ) );
}

wp_check_password()通过把生成的密文和文本密码进行比对来验证密码。


function wp_check_password($password, $hash, $user_id = '') {
global $wp_hasher;
if ( emptyempty($wp_hasher) ) {
require_once( ABSPATH . WPINC . '/class-phpass.php');
// By default, use the portable hash from phpass
$wp_hasher = new PasswordHash(8, true);
}
$check = $wp_hasher->CheckPassword($password, $hash);
return apply_filters( 'check_password', $check, $password, $hash, $user_id );
}

简易的使用方法


//生成加密密文
$password = wp_hash_password("qcqx");
//把密文和文本验证
echo wp_check_password("qcqx",$password ) ;
//输出 1,对比成功