Changeset 1688504
- Timestamp:
- 06/30/2017 08:04:04 PM (9 years ago)
- Location:
- optimality/trunk
- Files:
-
- 11 edited
-
index.php (modified) (12 diffs)
-
markup/html.php (modified) (20 diffs)
-
markup/media.php (modified) (2 diffs)
-
markup/page.php (modified) (5 diffs)
-
markup/post.php (modified) (2 diffs)
-
markup/section.php (modified) (1 diff)
-
markup/site.php (modified) (2 diffs)
-
markup/sitemap.php (modified) (4 diffs)
-
markup/term.php (modified) (4 diffs)
-
markup/user.php (modified) (4 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
optimality/trunk/index.php
r1685786 r1688504 5 5 * Plugin URI: https://wordpress.org/plugins/optimality 6 6 * Description: Optimizes website's content delivery, images, database, permalink structure, search engines and social media markup. 7 * Version: 0. 4.07 * Version: 0.5.0 8 8 * License: GPLv2 or later 9 9 * Author: Optimality … … 57 57 Html::PREDNS => NULL, 58 58 Html::MINIFY => NULL, 59 Html::STATIC => NULL, 59 60 Style::MINIFY => NULL, 60 61 Style::CDNLIB => NULL, … … 147 148 { 148 149 wp_clear_scheduled_hook( __NAMESPACE__ ); 149 Style::cleanCache(); Script::cleanCache(); 150 Style::cleanCache(); Script::cleanCache(); Html::cleanCache(); 150 151 }); 151 152 … … 153 154 add_action(__NAMESPACE__, function() 154 155 { 155 @$this->option[Site::DBTEMP]&& Site::cleanTemp();156 @$this->option[Post::DBAUTO]&& Post::cleanAuto();157 @$this->option[Post::DBEDIT]&& Post::cleanEdit();158 @$this->option[Post::DBMETA]&& Post::cleanMeta();159 @$this->option[Term::DBLINK]&& Term::cleanLink();160 @$this->option[Comment::DBSPAM]&& Comment::cleanSpam();161 @$this->option[Comment::DBPING]&& Comment::cleanPing();162 @$this->option[Comment::DBMETA]&& Comment::cleanMeta();156 isset($this->option[Site::DBTEMP]) && Site::cleanTemp(); 157 isset($this->option[Post::DBAUTO]) && Post::cleanAuto(); 158 isset($this->option[Post::DBEDIT]) && Post::cleanEdit(); 159 isset($this->option[Post::DBMETA]) && Post::cleanMeta(); 160 isset($this->option[Term::DBLINK]) && Term::cleanLink(); 161 isset($this->option[Comment::DBSPAM]) && Comment::cleanSpam(); 162 isset($this->option[Comment::DBPING]) && Comment::cleanPing(); 163 isset($this->option[Comment::DBMETA]) && Comment::cleanMeta(); 163 164 }); 164 165 165 if ( @$this->option[Image::MINIFY])166 if (isset($this->option[Image::MINIFY])) 166 167 { 167 168 add_filter('wp_image_editors', [Image::class, 'mount']); … … 175 176 function __constructFront() 176 177 { 177 if ( @$this->option[Html::UNMETA])178 if (isset($this->option[Html::UNMETA])) 178 179 { 179 180 remove_action('wp_head', 'adjacent_posts_rel_link_wp_head'); … … 187 188 } 188 189 189 if ( @$this->option[Html::UNEMOJ])190 if (isset($this->option[Html::UNEMOJ])) 190 191 { 191 192 remove_filter('comment_text_rss' , 'wp_staticize_emoji'); … … 196 197 } 197 198 198 if ( @$this->option[Html::PREDNS])199 if (isset($this->option[Html::PREDNS])) 199 200 { 200 201 remove_action('wp_head', 'wp_resource_hints', 2); 201 202 } 202 203 203 if ( @$this->option[Section::UNBASE])204 if (isset($this->option[Section::UNBASE])) 204 205 { 205 206 add_filter('request' , [Section::class, 'query'], 10, 1); … … 207 208 } 208 209 209 if ( @$this->option[Comment::UNLINK])210 if (isset($this->option[Comment::UNLINK])) 210 211 { 211 212 add_filter('comment_reply_link', [Comment::class, 'route'], 10, 1); 212 213 } 213 214 214 if ( @$this->option[User::UNLINK])215 if (isset($this->option[User::UNLINK])) 215 216 { 216 217 add_filter('author_link', [User::class, 'route'], 10, 2); 217 218 } 218 219 219 if ( @$this->option[Media::UNLINK])220 if (isset($this->option[Media::UNLINK])) 220 221 { 221 222 add_filter('attachment_link', [Media::class, 'route'], 10, 2); 222 223 } 223 224 224 if ( @$this->option[Image::SRCSET])225 if (isset($this->option[Image::SRCSET])) 225 226 { 226 227 remove_filter('the_content', 'wp_make_content_images_responsive'); 227 228 } 228 229 229 if ( @$this->option[Style::CDNLIB])230 if (isset($this->option[Style::CDNLIB])) 230 231 { 231 232 add_filter('style_loader_src', [Style::class, 'serve'], 10, 2); 232 233 } 233 234 234 if ( @$this->option[Script::MINIFY])235 if (isset($this->option[Script::MINIFY])) 235 236 { 236 237 remove_action('comment_form', 'wp_comment_form_unfiltered_html_nonce'); 237 238 } 238 239 239 if ( @$this->option[Script::CDNLIB])240 if (isset($this->option[Script::CDNLIB])) 240 241 { 241 242 add_filter('script_loader_src', [Script::class, 'serve'], 10, 2); … … 246 247 switch (true) 247 248 { 248 case is_admin() :249 249 case is_feed() : 250 250 case is_robots() : return; … … 263 263 } 264 264 265 $ishtml = preg_grep(Html::HEADER, headers_list()); 266 $method = strtoupper(@$_SERVER['REQUEST_METHOD']); 267 268 if ($static = isset( $this->option[ Html::STATIC ] ) && 269 $ishtml && empty($_REQUEST) && $method === 'GET' && 270 !is_user_logged_in() && !defined('DOING_CRON')) 271 { 272 Html::serve(@$_SERVER['HTTP_ACCEPT_ENCODING']); 273 } 274 265 275 $markup = new $markup(get_queried_object()); 266 276 … … 270 280 } 271 281 272 ob_start(function($string) use($markup) 273 { 274 return $markup->build($string, $this->option); 282 $ishtml && ob_start(function($string) use($markup, $static) 283 { 284 return call_user_func(array($markup, $static ? 285 'cache' : 'build'), $string, $this->option); 275 286 }); 276 287 }); 277 288 278 289 279 @$this->option[Plugin::WIDGET]&& add_action('admin_bar_menu', function($widget)290 isset($this->option[Plugin::WIDGET]) && add_action('admin_bar_menu', function($widget) 280 291 { 281 292 $this->addWidget($widget, NULL, ucwords(__NAMESPACE__ ), $this->urlPlugin()); … … 324 335 $this->addOption(Html::PREDNS , __('Prefetch DNS' ), $module, 'binary', __('Reduce DNS lookup time by pre-resolving all external domains.')); 325 336 $this->addOption(Html::MINIFY , __('Optimize HTML' ), $module, 'binary', __('Remove comments, unnecessary whitespace and empty nodes.')); 337 $this->addOption(Html::STATIC , __('Cache HTML' ), $module, 'binary', __('Cache dynamic HTML content and serve it as static HTML files.')); 338 $this->addAction(Html::STATIC , __('Clean HTML Cache' ), 'trash', [Html::class, 'cleanCache'], [Html::class, 'countCache']); 326 339 $this->addOption(Style::MINIFY , __('Optimize Styles' ), $module, 'binary', __('Combine files, flatten imports, remove comments and cache.')); 327 340 $this->addAction(Style::MINIFY , __('Clean Style Cache' ), 'trash', [Style::class, 'cleanCache'], [Style::class, 'countCache']); -
optimality/trunk/markup/html.php
r1685786 r1688504 5 5 class Html extends \DOMDocument 6 6 { 7 const HEADER = '/^Content-Type\:\s*text\/html/'; 7 8 const OGMETA = '/^(og|article|profile):(.+)$/'; 8 9 const CUSTOM = 'html_custom'; … … 11 12 const PREDNS = 'html_predns'; 12 13 const MINIFY = 'html_minify'; 14 const STATIC = 'html_static'; 13 15 const CDNURL = 'html_cdnurl'; 14 16 const SEMETA = 'html_semeta'; … … 19 21 const SMDESC = 'html_smdesc'; 20 22 23 public $proto; 21 24 public $root; 22 25 public $head; 23 26 public $body; 24 27 public $meta = []; 25 public $type;26 28 public $ruid; 27 29 public $slug; … … 35 37 public $user; 36 38 public $site; 37 public $ attr;38 public $ file;39 public $text; 40 public $path; 39 41 40 42 41 43 function __construct($object) 42 44 { 43 $this-> type = 'CreativeWork';45 $this->proto = $object; 44 46 } 45 47 … … 54 56 } 55 57 56 $this-> attr= array58 $this->text = array 57 59 ( 58 60 ':name' => $this->name, … … 67 69 ); 68 70 69 $this-> file= array71 $this->path = array 70 72 ( 71 73 __CDNURL__ => $option[static::CDNURL], … … 120 122 ( 121 123 'twitter:card' => 'summary_large_image', 122 'twitter:title' => ucfirst(strtr(@$option[static::SMNAME], $this-> attr)),123 'twitter:description' => ucfirst(strtr(@$option[static::SMDESC], $this-> attr)),124 'twitter:image' => strtr($this->image ?: $this->site->image, $this-> file),124 'twitter:title' => ucfirst(strtr(@$option[static::SMNAME], $this->text)), 125 'twitter:description' => ucfirst(strtr(@$option[static::SMDESC], $this->text)), 126 'twitter:image' => strtr($this->image ?: $this->site->image, $this->path), 125 127 'twitter:creator' => $this->user ? $this->user->twit : NULL, 126 128 'twitter:site' => $this->site ? $this->site->twit : NULL, 127 129 128 130 'og:type' => 'website', 129 'og:title' => ucfirst(strtr(@$option[static::SMNAME], $this-> attr)),130 'og:description' => ucfirst(strtr(@$option[static::SMDESC], $this-> attr)),131 'og:image' => strtr($this->image ?: $this->site->image, $this-> file),131 'og:title' => ucfirst(strtr(@$option[static::SMNAME], $this->text)), 132 'og:description' => ucfirst(strtr(@$option[static::SMDESC], $this->text)), 133 'og:image' => strtr($this->image ?: $this->site->image, $this->path), 132 134 'og:url' => $this->route, 133 135 'og:locale' => $this->site->lang, … … 154 156 ( 155 157 '@context' => 'http://schema.org', 156 '@type' => $this->type,157 'name' => ucfirst(strtr(@$option[static::SENAME], $this-> attr)),158 'description' => ucfirst(strtr(@$option[static::SEDESC], $this-> attr)),159 'image' => strtr($this->image ?: $this->site->image, $this-> file),158 '@type' => 'Thing', 159 'name' => ucfirst(strtr(@$option[static::SENAME], $this->text)), 160 'description' => ucfirst(strtr(@$option[static::SEDESC], $this->text)), 161 'image' => strtr($this->image ?: $this->site->image, $this->path), 160 162 'url' => $this->route, 161 'author' => $this->user ? $this->user->goog : NULL, 162 'publisher' => $this->site ? $this->site->goog : NULL, 163 'datePublished' => $this->date, 164 'dateModified' => $this->edit, 163 164 //'author' => $this->user ? $this->user->goog : NULL, 165 //'publisher' => $this->site ? $this->site->goog : NULL, 166 //'datePublished' => $this->date, 167 //'dateModified' => $this->edit, 165 168 ); 166 169 } … … 215 218 function build($string, $option) 216 219 { 217 $this->preserveWhiteSpace = empty(@$option[static::MINIFY]);218 @$this->loadHTML($string , LIBXML_COMPACT|LIBXML_NOBLANKS);220 $this->preserveWhiteSpace = !isset($option[static::MINIFY]); 221 @$this->loadHTML($string, LIBXML_COMPACT | LIBXML_NOBLANKS); 219 222 220 223 $schema = new \DOMXPath($this); $linked = [ ]; … … 230 233 } 231 234 232 if ($object = @$this->meta['viewport'])233 {234 $values = preg_split('/\s*,\s*/', $object->getAttribute( 'content' ));235 $values = array_diff($values, ['maximum-scale=1.0', 'user-scalable=0']);236 $object->setAttribute('content', implode(', ', $values));237 }238 239 235 if ($source = @$option[static::CUSTOM]) 240 236 { … … 245 241 // SEO 246 242 247 if ( @$option[static::SEMETA])243 if (isset($option[static::SEMETA])) 248 244 { 249 245 if (!($object = @$schema->query('/html/head/title[1]')[0])) … … 253 249 } 254 250 255 $object->nodeValue = ucfirst(strtr(@$option[static::SENAME], $this-> attr));256 257 $this->setMeta('description', ucfirst(strtr(@$option[static::SEDESC], $this-> attr)));251 $object->nodeValue = ucfirst(strtr(@$option[static::SENAME], $this->text)); 252 253 $this->setMeta('description', ucfirst(strtr(@$option[static::SEDESC], $this->text))); 258 254 $this->addJson(array_filter($this->getJson($option)), 'application/ld+json'); 259 255 } … … 261 257 // SMO 262 258 263 if ( @$option[static::SMMETA])259 if (isset($option[static::SMMETA])) 264 260 { 265 261 $this->root->setAttribute('prefix', 'og: http://ogp.me/ns#'); … … 273 269 // DNS 274 270 275 if ( @$option[static::PREDNS])271 if (isset($option[static::PREDNS])) 276 272 { 277 273 $filter = '//link[@rel="stylesheet"]|//script[@src]|/html/body//img[@src]'; … … 294 290 // CSS 295 291 296 if ( @$option[Style::MINIFY])292 if (isset($option[Style::MINIFY])) 297 293 { 298 294 $bundle = new Style(); … … 361 357 // JS 362 358 363 if ( @$option[Script::MINIFY])359 if (isset($option[Script::MINIFY])) 364 360 { 365 361 $bundle = new Script(); … … 417 413 // IMG 418 414 419 if ( @$option[Image::SRCSET])415 if (isset($option[Image::SRCSET])) 420 416 { 421 417 $cdndir = wp_parse_url(__CDNURL__, PHP_URL_PATH); … … 442 438 // DOM 443 439 444 if (@$option[static::MINIFY]) 445 { 440 if (isset($option[static::MINIFY])) 441 { 442 if ($object = @$this->meta['viewport']) 443 { 444 $values = preg_split('/\s*,\s*/', $object->getAttribute( 'content' )); 445 $values = array_diff($values, ['maximum-scale=1.0', 'user-scalable=0']); 446 $object->setAttribute('content', implode(', ', $values)); 447 } 448 446 449 foreach ($schema->query('//comment()') as $object) 447 450 { … … 457 460 } 458 461 459 count($linked) && header('Link: ' . implode(',', $linked));462 count($linked) && header('Link: ' . implode(',', $linked)); 460 463 return $string; 461 464 } 462 465 463 466 467 function cache($string, $option) 468 { 469 if ($string = $this->build($string, $option)) 470 { 471 $handle = sprintf('~%s.html', md5(__TARGET__)); 472 473 file_put_contents($target = __CDNDIR__ . $handle, $string); 474 file_put_contents($target . '.gz' , gzencode($string , 9)); 475 } 476 477 return $string; 478 } 479 480 481 static function serve($accept) 482 { 483 $source = sprintf(__CDNDIR__ . '~%s.html', md5( __TARGET__ )); 484 485 if ($encode = $accept && (strpos($accept, 'gzip') !== false)) 486 { 487 $source .= '.gz'; 488 } 489 490 if (file_exists($source) && time() - filemtime($source) < 600) 491 { 492 header('Vary: Accept-Encoding, Cookie'); 493 $encode && header('Content-Encoding: gzip'); 494 @readfile($source) && exit(); 495 } 496 } 497 498 464 499 static function encap($result) 465 500 { … … 470 505 }, $result ?: [ ]); 471 506 } 507 508 509 // ACTIONS 510 511 static function countCache() 512 { 513 return count(glob(__CDNDIR__ . '~*.{html}', GLOB_BRACE)); 514 } 515 516 517 static function cleanCache() 518 { 519 return count(array_filter(glob(__CDNDIR__ . '~*.{html,html.gz}', GLOB_BRACE), 'unlink')) / 2; 520 } 472 521 } 473 522 -
optimality/trunk/markup/media.php
r1683276 r1688504 18 18 parent::__construct($object); 19 19 20 $this->type = 'ImageObject';21 20 $this->ruid = $object->ID; 22 21 $this->slug = $object->post_name; … … 29 28 $this->edit = date(DATE_W3C, strtotime($object->post_modified)); 30 29 $this->user = $object->post_author; 30 } 31 32 33 function getJson($option) 34 { 35 return array_merge(parent::getJson($option), 36 [ 37 '@type' => 'ImageObject', 38 'headline' => $this->name, 39 'caption' => $this->lead, 40 'datePublished' => $this->date, 41 'dateModified' => $this->edit, 42 'author' => $this->user->goog, 43 'publisher' => $this->site->goog, 44 ]); 31 45 } 32 46 -
optimality/trunk/markup/page.php
r1685786 r1688504 19 19 parent::__construct($object); 20 20 21 $this->type = 'WebPage';22 21 $this->ruid = $object->ID; 23 22 $this->slug = $object->post_name; … … 35 34 function __invoke($target, $option) 36 35 { 37 if ( @$option[static::SEMETA])36 if (isset($option[static::SEMETA])) 38 37 { 39 38 add_filter('post_class', function($vector) … … 43 42 } 44 43 45 if ( @$option[Comment::UNLINK])44 if (isset($option[Comment::UNLINK])) 46 45 { 47 46 if ($source = @$_GET['replytocom']) … … 51 50 } 52 51 53 if ( @$option[Comment::UNPAGE])52 if (isset($option[Comment::UNPAGE])) 54 53 { 55 54 if (get_query_var('cpage')) … … 76 75 77 76 77 function getJson($option) 78 { 79 return array_merge(parent::getJson($option), 80 [ 81 '@type' => 'WebPage', 82 'headline' => $this->name, 83 'datePublished' => $this->date, 84 'dateModified' => $this->edit, 85 'commentCount' => $this->notes, 86 'author' => $this->user->goog, 87 'publisher' => $this->site->goog, 88 ]); 89 } 90 91 78 92 static function fetch() 79 93 { -
optimality/trunk/markup/post.php
r1685786 r1688504 15 15 const SMDESC = 'post_smdesc'; 16 16 17 public $section;18 public $terms = [];19 20 17 21 18 function __construct($object) 22 19 { 23 20 parent::__construct($object); 24 25 $this->type = 'Article';26 21 } 27 22 28 23 29 function __invoke($target,$option)24 function getMeta($option) 30 25 { 31 if (is_array($result = get_the_terms($this->ruid, 'category'))) 32 { 33 $this->section = @$result[0]->name; 34 } 26 $object = get_the_terms($this->proto, 'category'); 35 27 36 if (is_array($result = get_the_terms($this->ruid, 'post_tag'))) 37 { 38 foreach ($result as $object) $this->terms[] = $object->name; 39 } 28 return array_merge(parent::getMeta($option), 29 [ 30 'article:section' => empty($object) ? NULL : $object[0]->name, 31 'article:tag' => array_map(function($object) 32 { 33 return $object->name; 40 34 41 return parent::__invoke($target, $option); 35 }, get_the_terms($this->proto, 'post_tag') ?: []), 36 ]); 42 37 } 43 38 … … 45 40 function getJson($option) 46 41 { 42 $object = get_the_terms($this->proto, 'category'); 43 47 44 return array_merge(parent::getJson($option), 48 45 [ 49 'headline' => $this->name, 50 'articleSection' => $this->section, 51 'keywords' => implode(',' , $this->terms), 52 'commentCount' => $this->notes, 53 ]); 54 } 46 '@type' => 'Article', 47 'articleSection' => empty($object) ? NULL : $object[0]->name, 48 'keywords' => implode(',', array_map(function($object) 49 { 50 return $object->name; 55 51 56 57 function getMeta($option) 58 { 59 return array_merge(parent::getMeta($option), 60 [ 61 'article:section' => $this->section, 62 'article:tag' => $this->terms, 52 }, get_the_terms($this->proto, 'post_tag') ?: [])), 63 53 ]); 64 54 } -
optimality/trunk/markup/section.php
r1685786 r1688504 22 22 function __invoke($target, $option) 23 23 { 24 if ( $option[static::UNBASE])24 if (isset($option[static::UNBASE])) 25 25 { 26 26 if (strpos($target, $this->route) !== 0) -
optimality/trunk/markup/site.php
r1683276 r1688504 23 23 parent::__construct($object); 24 24 25 $this->type = 'WebSite';26 25 $this->ruid = NULL; 27 26 $this->name = get_bloginfo('name'); … … 34 33 $this->twit = get_option('twitter'); 35 34 $this->site = $this; 35 } 36 37 38 function getJson($option) 39 { 40 return array_merge(parent::getJson($option), 41 [ 42 '@type' => 'WebSite', 43 'publisher' => $this->goog, 44 ]); 36 45 } 37 46 -
optimality/trunk/markup/sitemap.php
r1685786 r1688504 10 10 11 11 public $root; 12 public $file; 12 public $path; 13 14 15 function __invoke($target, $option) 16 { 17 $this->path = array 18 ( 19 __CDNURL__ => $option[Html::CDNURL], 20 ); 21 } 13 22 14 23 … … 34 43 35 44 $source = $this->createElement('image:loc'); 36 $source->nodeValue = strtr($entity->image, $this-> file);45 $source->nodeValue = strtr($entity->image, $this->path); 37 46 $branch->appendChild($source); 38 47 … … 49 58 50 59 51 function __invoke($target, $option)52 {53 $this->file = array54 (55 __CDNURL__ => $option[Html::CDNURL],56 );57 }58 59 60 60 function build($string, $option) 61 61 { … … 66 66 $this->root->setAttribute('xmlns:image', 'http://www.google.com/schemas/sitemap-image/1.1'); 67 67 68 if ( @$option[Site::SEMETA])68 if (isset($option[Site::SEMETA])) 69 69 { 70 70 array_map([$this, 'addNode'], Site::fetch()); 71 71 } 72 72 73 if ( @$option[Page::SEMETA])73 if (isset($option[Page::SEMETA])) 74 74 { 75 75 array_map([$this, 'addNode'], Page::fetch()); 76 76 } 77 77 78 if ( @$option[Post::SEMETA])78 if (isset($option[Post::SEMETA])) 79 79 { 80 80 array_map([$this, 'addNode'], Post::fetch()); 81 81 } 82 82 83 if ( @$option[Section::SEMETA])83 if (isset($option[Section::SEMETA])) 84 84 { 85 85 array_map([$this, 'addNode'], Section::fetch()); 86 86 } 87 87 88 if ( @$option[Term::SEMETA])88 if (isset($option[Term::SEMETA])) 89 89 { 90 90 array_map([$this, 'addNode'], Term::fetch()); 91 91 } 92 92 93 if ( @$option[User::SEMETA] && !@$option[User::UNLINK])93 if (isset($option[User::SEMETA]) && !isset($option[User::UNLINK])) 94 94 { 95 95 array_map([$this, 'addNode'], User::fetch()); 96 96 } 97 97 98 if ( @$option[Media::SEMETA] && !@$option[Media::UNLINK])98 if (isset($option[Media::SEMETA]) && !isset($option[Media::UNLINK])) 99 99 { 100 100 array_map([$this, 'addNode'], Media::fetch()); -
optimality/trunk/markup/term.php
r1685794 r1688504 13 13 const SMDESC = 'term_smdesc'; 14 14 15 public $ items;15 public $posts; 16 16 17 17 … … 20 20 parent::__construct($object); 21 21 22 $this->type = 'ItemList';23 22 $this->ruid = $object->term_id; 24 23 $this->slug = $object->slug; … … 26 25 $this->desc = $object->description; 27 26 $this->route = get_term_link($object); 28 $this->items = [ ]; 29 } 30 31 32 function __invoke($target, $option) 33 { 34 foreach (@$GLOBALS['wp_query']->posts ?: [] as $offset => $object) 35 { 36 $this->items[] = array 37 ( 38 '@type' => 'ListItem', 39 'position' => $offset + 1, 40 'url' => get_permalink($object), 41 ); 42 } 43 44 return parent::__invoke($target, $option); 27 $this->posts = @$GLOBALS['wp_query']->posts ?: []; 45 28 } 46 29 … … 48 31 function getJson($option) 49 32 { 33 $offset = 0; 34 50 35 return array_merge(parent::getJson($option), 51 36 [ 52 'publisher' => NULL, 53 'author' => NULL, 54 'numberOfItems' => count($this->items), 55 'itemListElement' => $this->items, 37 '@type' => 'ItemList', 38 'numberOfItems' => count($this->posts), 39 'itemListElement' => array_map(function($object) use(&$offset) 40 { 41 return 42 [ 43 '@type' => 'ListItem', 44 'position' => ++$offset, 45 'url' => get_permalink($object) 46 ]; 47 48 }, $this->posts), 56 49 ]); 57 50 } -
optimality/trunk/markup/user.php
r1685786 r1688504 24 24 parent::__construct($object); 25 25 26 $this->type = 'Person';27 26 $this->ruid = $object->ID; 28 27 $this->slug = $object->data->user_nicename; … … 46 45 function __invoke($target, $option) 47 46 { 48 if ( @$option[static::UNLINK])47 if (isset($option[static::UNLINK])) 49 48 { 50 49 return static::route($target, NULL); … … 52 51 53 52 return parent::__invoke($target, $option); 54 }55 56 57 function getJson($option)58 {59 return array_merge(parent::getJson($option),60 [61 'givenName' => $this->fname,62 'familyName' => $this->lname,63 ]);64 53 } 65 54 … … 79 68 80 69 70 function getJson($option) 71 { 72 return array_merge(parent::getJson($option), 73 [ 74 '@type' => 'Person', 75 'givenName' => $this->fname, 76 'familyName' => $this->lname, 77 ]); 78 } 79 80 81 81 static function route($origin, $userid) 82 82 { -
optimality/trunk/readme.txt
r1685786 r1688504 20 20 * Reduces DNS lookup time by pre-resolving all external domains. 21 21 * Removes comments, unnecessary whitespace and empty nodes from HTML. 22 * Combines stylesheets, flattens imports, removes comments and caches. 22 * Caches dynamic HTML content and serves it as static HTML files. 23 * Combines CSS files, flattens imports, removes comments and caches. 23 24 * Serves popular CSS libraries from content delivery networks. 24 * Combines scripts, defers loading, removes comments and caches.25 * Combines JS files, defers loading, removes comments and caches. 25 26 * Serves popular JS libraries from content delivery networks. 26 27 * Strips metadata and compresses thumbnail images (requires ImageMagick). … … 77 78 == Changelog == 78 79 80 = 0.5.0 = 81 * Feature: HTML cache 82 * Feature: Schema markup fine-tunning 83 * Feature: Code fine-tuning for faster processing 84 * Bug Fix: Process only 'text/html' responses 85 79 86 = 0.4.0 = 80 87 * Feature: ItemList schema instead CollectionPage for taxonomies
Note: See TracChangeset
for help on using the changeset viewer.