#感覺我們接觸到的一切都是精心設計的:網站、電話、地鐵地圖等等。即使是我們過去認為理所當然的東西:恆溫器、煙霧偵測器和汽車儀表板現在也得到了仔細的使用者體驗處理。
設計不僅僅是外觀和感覺:它還需要考慮使用者與我們的裝置/工具/螢幕/物件互動所需的各種方式。
這也適用於程式設計。
程式語言是一個龐大而複雜的世界。即使是許多程式設計勢利小人認為太「簡單」的 PHP,實際上也是函數和類別的相當複雜的組合,其行為方式非常不一致。
多年來,語法、方法和命名在數百萬不同的用戶和應用程式中不斷發展。大多數傾向於反映內部的底層構造 - 不一定是您想要如何使用它。
##當我在 2006 年左右開始寫 JavaScript 時,情況一團糟。以下是我如何找到具有特定類別的標籤並將其在 DOM 中移動的方法:
var uls = getElementsByTagName("ul"); var classToSearch = "foods"; for (var i = 0; i < uls.length; i++) { var classes = uls[i].getClasses(); for (var j = 0; j < classes.length; j++){ if (classes[j] == classToSearch){ myUL = uls[i]; } } } var $li = document.createElement('li'); $li.innerHTML = 'Steak'; myUL.innerHTML += $li;
完成!
jQuery 讓 JavaScript 再次變得有趣。在 2000 年代末,這種影響是如此巨大,以至於我記得我父親問我他在《華爾街日報》上讀到的「一些奇怪的事情」。但儘管效果巨大,jQuery 並沒有為 JavaScript 添加任何「新功能」。它只是將開發人員必須做的事情分解為非常清晰的模式。
他們沒有重新發明如何在頁面上找到內容,而是利用了人們已經知道的東西:CSS 選擇器。然後,只需收集大量常見操作並將它們組織成數十個函數即可。讓我們再次嘗試前面的範例,現在使用 jQuery:
var $li = $('<li>Steak</li>'); $("ul.foods").append($li);
2006 年,我買了一本 680 頁的 Ajax 書。有了 jQuery 出色的 API,它幾乎被這個取代了:
$.post();
雖然 API 已經開始代表“第三方服務”,但它僅僅意味著與系統對話的程式設計介面。就像 Twitter API 或 Facebook API 一樣,WordPress API 也存在。您不會進行原始資料庫查詢來建立帖子,對吧?您使用 wp_insert_post
。
但是許多設計漏洞困擾著 WordPress API。您可能使用 get_the_title
但 get_the_permalink
會產生錯誤,您使用 get_permalink
。嘿,當您有一個長達數十年的開源項目,涉及數千人的程式碼和數百萬用戶時:您會遇到一些怪癖。
透過掩蓋這些怪癖並根據您正在編寫的程式設計師(可能是您)的習慣和行為進行編寫,您可以節省大量時間。您可以在這裡設計正確的介面來對您日常使用的插件和主題進行編程。
為了加快工作速度並減少重複性任務,我創建了一個庫來處理我一直需要的命令和自訂設定。
以取得貼文縮圖的來源為例。事實證明,WordPress 沒有內建功能來根據貼文 ID(僅附件 ID)取得縮圖。
這意味著我經常發現自己這樣做:
$thumb_id = get_post_thumbnail_id( get_the_ID() ); $src = wp_get_attachment_thumb_url( $thumb_id ); echo '<img alt="" src="' . $src . '" />';
但是一定有更好的方法!
function get_thumbnail_src( $post ){ $thumb_id = get_post_thumbnail_id( $post ); $src = wp_get_attachment_thumb_url( $thumb_id ); return $src; } echo '<img alt="" src="' . get_thumbnail_src( get_the_ID() ) . '" />';
好多了!事實上,您發現自己一直在使用它,然後與公司的其他開發人員分享。
你的朋友遇到了麻煩,所以他打電話給你來調試,你看到:
echo '<img src="' . get_thumbnail_src( get_post() ) . '">';
看來他不小心使用了 get_post
而不是 get_the_ID
。你對他大喊。但是等一下,為什麼不讓它更容易被接受呢?
也許我們可以調整我們的函數,以便它可以採用 WP_Post
對象,並且仍然為用戶提供他們所期望的內容。讓我們回到該函數:
function get_thumbnail_src( $post ){ if ( is_object( $post ) && isset( $post->ID ) ){ $post = $post->ID; } else if ( is_array( $post ) && isset( $post['ID'] ) ) { $post = $post['ID']; } $thumb_id = get_post_thumbnail_id( $post ); $src = wp_get_attachment_thumb_url( $thumb_id ); return $src; }
因此,如果他們發送 WP_Post
物件或一個數組,您的函數仍然可以幫助他們獲得所需的內容。這是成功 API 的重要組成部分:隱藏混亂的內部結構。您可以為 get_thumbnail_src_by_post_id
和 get_thumbnail_src_by_wp_post_object.
製作單獨的函式
事實上,對於更複雜的轉換可能更可取,但是您可以透過將單一函數路由到正確的子程式來簡化介面。無論使用者發送什麼內容,該函數都會始終傳回圖像來源的字串。
讓我們繼續:如果他們什麼都沒發送怎麼辦?
function get_thumbnail_src( $post = false ) { if ( false === $post ) { $post = get_the_ID(); } else if ( is_object( $post ) && isset( $post->ID ) ) { $post = $post->ID; } else if ( is_array( $post ) && isset( $post['ID'] ) ) { $post = $post['ID']; } $thumb_id = get_post_thumbnail_id( $post ); $src = wp_get_attachment_thumb_url( $thumb_id ); return $src; }
我们再次进行了简化,因此用户无需发送帖子,甚至无需发送帖子 ID。在循环中时,所需要做的就是:
echo '<img src="'.get_thumbnail_src().'" />';
我们的函数将默认为当前帖子的 ID。这正在变成一个非常有价值的功能。为了确保它能很好地发挥作用,让我们将它包装在一个类中,这样它就不会污染全局命名空间。
/* Plugin Name: JaredTools Description: My toolbox for WordPress themes. Author: Jared Novack Version: 0.1 Author URI: http://upstatement.com/ */ class JaredsTools { public static function get_thumbnail_src( $post = false ) { if (false === $post ) { $post = get_the_ID(); } else if ( is_object( $post ) && isset( $post->ID ) ) { $post = $post->ID; } else if ( is_array( $post ) && isset( $post['ID'] ) ) { $post = $post['ID']; } $thumb_id = get_post_thumbnail_id( $post ); $src = wp_get_attachment_thumb_url( $thumb_id ); return $src; } }
并且请不要在您的类前面添加 WP
。我将其设为公共静态函数,因为我希望它可以在任何地方访问,并且它不会改变:输入或执行不会更改函数或对象。
该函数的最终调用是:
echo '<img src="'.JaredsTools::get_thumbnail_src().'">';
让我们继续处理更复杂的需求。当我编写插件时,我发现我总是需要生成不同类型的错误和/或更新消息。
但是基于事件的语法一直困扰着我:
add_action( 'admin_notices', 'show_my_notice'); functon show_my_notice(){ echo '<div class="updated"><p>Your thing has been updated</p></div>'; }
WordPress 遵循这种基于事件的架构有很多充分的理由。但这并不直观,除非您想坐下来记住不同的过滤器和操作。
让我们将此匹配作为最简单的用例:我需要显示管理员通知。我喜欢首先设计这个 API:我找出在代码中引用该函数的最佳方式。我希望它读起来像这样:
function thing_that_happens_in_my_plugin($post_id, $value){ $updated = update_post_meta($post_id, $value); if ($updated){ JaredsTools::show_admin_notice("Your thing has been updated") } else { JaredsTools::show_admin_notice("Error updating your thing", "error"); } }
一旦我设计了端点,我就可以满足设计要求:
class JaredsTools { public static function show_admin_notice($message, $class = 'updated'){ add_action('admin_notices', function() use ($message, $class){ echo '<div class="'.$class.'"><p>'.$message.'</p></div>'; }); } }
好多了!现在我不需要创建所有这些额外的函数或记住疯狂的钩子名称。在这里,我使用 PHP 匿名函数(也称为“闭包”),它让我们可以将函数直接绑定到操作或过滤器。
这可以让您避免在文件中出现大量额外的函数。 use
命令让我们将参数从父函数传递到子闭包中。
现在另一位同事打电话给您。她不知道为什么她的管理通知没有变成红色:
JaredsTools::show_admin_notice("Error updating your thing", "red");
这是因为她正在发送“红色”(她希望将盒子变成红色),而实际上她应该发送触发红色的类名称。但为什么不让它变得更容易呢?
public static function show_notice( $message, $class = 'updated' ) { $class = trim( strtolower( $class ) ); if ( 'yellow' == $class ) { $class = 'updated'; } if ('red' == $class ) { $class = 'error'; } add_action( 'admin_notices', function() use ( $text, $class ) { echo '<div class="'.$class.'"><p>' . $text . '</p></div>'; }); }
我们现在已经接受了更多的用户容忍度,这将使我们在几个月后回来使用它时更容易分享。
在构建了其中一些之后,以下是我学到的一些原则,这些原则使这些原则对我和我的团队真正有用。
1.首先进行设计,让函数的构建符合人们想要使用它的方式。
2. 拯救你的键盘!为常见任务创建快捷方式。
3. 提供合理的默认值。
4. 保持最小化。让您的库来处理处理。
5. 对输入要宽容,对输出要精确。
6. 也就是说,使用尽可能少的函数参数,最多四个是一个很好的参数。之后,您应该将其设为选项数组。
7. 将您的库组织成单独的类,以涵盖不同的领域(管理、图像、自定义帖子等)。
8. 包含示例代码的文档。
在 Upstatement,我们的 Timber 库使构建主题变得更加容易,而 Jigsaw 提供了节省时间的快捷方式来自定义每个安装。
这些工具节省的时间让我们可以花更多时间构建每个网站或应用程序的新的和创新的部分。通过执行深奥的命令(例如向管理帖子表添加一列)并制作简单的界面:我们公司的任何设计师或开发人员都可以使用与专业 WordPress 开发人员相同的能力完全自定义每个网站。
以上是增強 WordPress:打造改進的 API 和函式庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!