PluginProbe
WPJAM Basic / trunk
WPJAM Basic vtrunk
wpjam-basic / extends / wpjam-seo.php

wpjam-seo.php in WPJAM Basic trunk, at extends/wpjam-seo.php

198 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Name: 简单 SEO
4 URI: https://mp.weixin.qq.com/s/LzGWzKCEl5SdJCQdBvFipg
5 Description: 简单 SEO 扩展实现最简单快捷的方式设置 WordPress 站点的 SEO。
6 Version: 2.0
7 */
8 class WPJAM_SEO{
9 public static function __callStatic($method, $args){
10 return wpjam_call_option(static::class, $method, ...$args);
11 }
12
13 public static function get_fields(){
14 if(file_exists(ABSPATH.'robots.txt')){
15 $robots_field = ['type'=>'view', 'value'=>'博客的根目录下已经有 robots.txt 文件。<br />请直接编辑或�
16 删除之后在后台自定义。'];
17 }else{
18 $site_url = parse_url(site_url());
19 $path = !empty($site_url['path']) ? $site_url['path'] : '';
20 $robots = wpjam_remove_pre_tab("User-agent: *
21 Disallow: /wp-admin/
22 Disallow: /wp-includes/
23 Disallow: /cgi-bin/
24 Disallow: $path/wp-content/plugins/
25 Disallow: $path/wp-content/themes/
26 Disallow: $path/wp-content/cache/
27 Disallow: $path/author/
28 Disallow: $path/trackback/
29 Disallow: $path/feed/
30 Disallow: $path/comments/
31 Disallow: $path/search/", 3);
32
33 $robots_field = ['type'=>'textarea', 'value'=>$robots];
34 }
35
36 if(file_exists(ABSPATH.'sitemap.xml')){
37 $wpjam_sitemap = '博客的根目录下已经有 sitemap.xml 文件。<br />删除之后才能使用插件自动生成的 sitemap.xml。';
38 }else{
39 $wpjam_sitemap = '首页/分类/标签:<a href="'.home_url('/sitemap.xml').'" target="_blank">'.home_url('/sitemap.xml').'</a>
40 <br />前1000篇文章:<a href="'.home_url('/sitemap-1.xml').'" target="_blank">'.home_url('/sitemap-1.xml').'</a>
41 <br />1000-2000篇文章:<a href="'.home_url('/sitemap-2.xml').'" target="_blank">'.home_url('/sitemap-2.xml').'</a>
42 <br />以此类推...';
43 }
44
45 $wp_sitemap = 'sitemap 地址:<a href="'.home_url('/wp-sitemap.xml').'" target="_blank">'.home_url('/wp-sitemap.xml').'</a>';
46
47 return [
48 'home_set' => ['title'=>'首页设置', 'type'=>'fieldset', 'wrap_tag'=>'fieldset', 'fields'=>[
49 'home_title' => ['title'=>'标题:', 'class'=>'regular-text, expandable', 'placeholder'=>'不填则使用标题'],
50 'home_description' => ['title'=>'描述:', 'type'=>'textarea'],
51 'home_keywords' => ['title'=>'�
52 �键字:', 'class'=>'regular-text, expandable'],
53 ]],
54 'post_set' => ['title'=>'文章和分类页', 'type'=>'fieldset', 'group'=>true, 'fields'=>[
55 'individual' => ['type'=>'select', 'options'=>['0'=>'自动获取摘要和�
56 �键字', '1'=>[
57 'label' => '单独设置 SEO TDK',
58 'fields' => ['list_table'=>['value'=>1, 'options'=>['1'=>'编辑和列表页都可设置', '0'=>'�
59 可在编辑页设置', 'only'=>'�
60 可在列表页设置']]]
61 ]]],
62 ], 'description' => ['文章摘要作为页面的 Meta Description,文章的标签作为页面的 Meta Keywords。<br />分类和标签的描述作为页面的 Meta Description,页面没有 Meta Keywords。', ['show_if'=>['individual', 0]]]],
63 'unique' => ['title'=>'确保生成并唯一', 'label'=>'如果当前主题或�
64 �他插件也会生成摘要和�
65 �键字,或当前主题不标准,可以通过勾选该选项「确保生成并唯一」。'],
66 'robots' => ['title'=>'robots.txt']+$robots_field,
67 'sitemap' => ['title'=>'Sitemap', 'options'=>[0=>['label'=>'使用 WPJAM 生成的','description'=>$wpjam_sitemap], 'wp'=>['label'=>'使用 WordPress �
68 置的','description'=>$wp_sitemap]]]
69 ];
70 }
71
72 public static function get_value($type='title'){
73 if($type == 'meta'){
74 return wpjam_fill(['description', 'keywords'], fn($k)=> self::get_value($k));
75 }
76
77 if(is_front_page()){
78 if(get_query_var('paged') < 2){
79 $value = self::get_setting('home_'.$type);
80 }
81 }elseif(is_tag() || is_category() || is_tax()){
82 if(get_query_var('paged') < 2){
83 if(self::get_setting('individual')){
84 $value = get_term_meta(get_queried_object_id(), 'seo_'.$type, true);
85 }
86
87 if(empty($value) && $type == 'description'){
88 $value = term_description();
89 }
90 }
91 }elseif(is_singular()){
92 if(self::get_setting('individual')){
93 $value = get_post_meta(get_the_ID(), 'seo_'.$type, true);
94 }
95
96 if(empty($value)){
97 if($type == 'description'){
98 $value = get_the_excerpt();
99 }elseif($type == 'keywords'){
100 $value = ($tags = get_the_tags()) ? implode(',', wp_list_pluck($tags, 'name')) : '';
101 }
102 }
103 }
104
105 if(!empty($value)){
106 $value = wp_strip_all_tags($value, true);
107
108 return $type == 'title' ? esc_textarea($value) : "<meta name='{$type}' content='".esc_attr($value)."' />\n";
109 }
110 }
111
112 public static function get_rewrite_rule(){
113 return [
114 ['sitemap\.xml?$', 'index.php?module=sitemap', 'top'],
115 ['sitemap-(.*?)\.xml?$', 'index.php?module=sitemap&action=$matches[1]', 'top'],
116 ];
117 }
118
119 public static function redirect($action){
120 if(!$action){
121 $items = array_merge([[home_url(), str_replace(' ', 'T', get_lastpostmodified('GMT')).'+00:00', 'daily', '1.0']], get_terms(['taxonomy'=>array_diff(array_keys(get_taxonomies(['public' => true])), ['post_format'])]));
122 }elseif(is_numeric($action)){
123 $items = wpjam_get_posts(['posts_per_page'=>1000, 'paged'=>$action, 'post_type'=>array_diff(array_keys(get_post_types(['public' => true])), ['page', 'attachment'])]);
124 }else{
125 $sitemap = apply_filters('wpjam_'.$action.'_sitemap', '');
126 }
127
128 $sitemap ??= implode(wpjam_map($items, function($item){
129 if(is_a($item, 'WP_Post')){
130 $item = [get_permalink($item->ID), str_replace(' ', 'T', $item->post_modified_gmt).'+00:00', 'weekly', 0.8];
131 }elseif(is_a($item, 'WP_Term')){
132 $item = [get_term_link($item), str_replace(' ', 'T', get_lastpostmodified('GMT')).'+00:00', 'daily', $item->taxonomy == 'category' ? 0.6 : 0.4];
133 }
134
135 return "\t<url>\n".implode(wpjam_map(['loc', 'lastmod', 'changefreq', 'priority'], fn($k, $i)=> "\t\t<{$k}>{$item[$i]}</{$k}>\n"))."\t</url>\n";
136 }));
137
138 header("Content-Type:text/xml");
139
140 echo '<?xml version="1.0" encoding="UTF-8"?>
141 <?xml-stylesheet type="text/xsl" href="'.(new WP_Sitemaps_Renderer())->get_sitemap_stylesheet_url().'"?>
142 <!-- generated-on="'.date('d. F Y').'" -->
143 <urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'."\n".$sitemap."\n".'</urlset>'."\n";
144
145 exit;
146 }
147
148 public static function filter_html($html){
149 $title = self::get_value('title');
150 $title = $title ? '<title>'.$title.'</title>' : '';
151
152 if($meta = self::get_value('meta')){
153 $title = ($title ?: '\1')."\n".implode($meta);
154 $html = wpjam_preg_replace('#<meta\s+name=([\'"])('.implode('|', array_keys($meta)).')\1(.*?)\/>#is', '', $html);
155 }
156
157 return $title ? wpjam_preg_replace('#(<title>[^<]*<\/title>)#is', $title, $html) : $html;
158 }
159
160 public static function add_hooks(){
161 if(self::get_setting('unique')){
162 add_filter('wpjam_html', [self::class, 'filter_html']);
163 }else{
164 wpjam_hook('wp_head', 'echo', fn()=> implode(self::get_value('meta')));
165 }
166
167 wpjam_hook('robots_txt', '.', fn($public)=> $public ? self::get_setting('robots') : '', 10, 2);
168 add_filter('document_title', fn($title)=> self::get_value('title') ?: $title);
169
170 self::get_setting('sitemap') || wpjam_route('sitemap', self::class);
171
172 if(self::get_setting('individual')){
173 wpjam_map([
174 'post' => ['context'=>'side', 'post_type'=>fn($v)=> $v != 'attachment' && is_post_type_viewable($v)],
175 'term' => ['action'=>'edit', 'taxonomy'=>fn($v)=> is_taxonomy_viewable($v)]
176 ], fn($v, $t)=> wpjam_register_meta_option($t, 'seo', $v+[
177 'title' => 'SEO设置',
178 'page_title' => 'SEO设置',
179 'submit_text' => '设置',
180 'list_table' => self::get_setting('list_table', 1),
181 'fields' => [
182 'seo_description' => ['title'=>'SEO描述', 'class'=>'large-text', 'default'=>'', 'type'=>'textarea'],
183 'seo_keywords' => ['title'=>'SEO�
184 �键字','class'=>'large-text', 'default'=>'']
185 ]
186 ]));
187 }
188 }
189 }
190
191 wpjam_register_option('wpjam-seo', [
192 'title' => 'SEO设置',
193 'model' => 'WPJAM_SEO',
194 'plugin_page' => 'wpjam-seo',
195 'current_tab' => 'seo',
196 'menu_page' => ['tab_slug'=>'seo', 'order'=>20, 'summary'=>__FILE__]
197 ]);
198