{"id":231352,"date":"2022-12-18T19:12:00","date_gmt":"2022-12-18T16:12:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231352"},"modified":"2022-12-18T19:12:18","modified_gmt":"2022-12-18T16:12:18","slug":"wordpress-widgetit-refaktorointi-osa-7","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fi\/wordpress-widgetit-refaktorointi-osa-7\/","title":{"rendered":"WordPress-widgetit: Refaktorointi, osa 7"},"content":{"rendered":"\n<p>Muutamassa viimeisess\u00e4 viestiss\u00e4 olemme tehneet paljon ty\u00f6t\u00e4 saattaaksemme koodin uudelleenmuodostukseen, jota k\u00e4sitell\u00e4\u00e4n t\u00e4ss\u00e4 artikkelissa.<\/p>\n<p>Erityisesti olemme k\u00e4sitelleet:<\/p>\n<ul>\n<li>koukut,<\/li>\n<li><a href=\"https:\/\/tommcfarlin.com\/wordpress-widgets-part-4\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">rekisteri<\/a>, _<\/li>\n<li>ja <a href=\"https:\/\/wordpress.mediadoma.com\/fi\/wordpress-widgetit-refaktorointi-osa-3\/\" title=\"tilaajat\">tilaajat<\/a>.<\/li>\n<\/ul>\n<p>Kaikki n\u00e4m\u00e4 vaikuttavat siihen, mit\u00e4 aiomme tehd\u00e4 t\u00e4n\u00e4\u00e4n.<\/p>\n<h2>WordPress Widget Boilerplate: Refactoring, osa 7<\/h2>\n<p>Ne, jotka ovat perehtyneet <a href=\"https:\/\/codex.wordpress.org\/Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WordPress Widgets -sovellusliittym\u00e4\u00e4n<\/a>, tiet\u00e4v\u00e4t todenn\u00e4k\u00f6isesti, ett\u00e4 se ei ole juurikaan muuttunut viime vuosina.<\/p>\n<p>Lis\u00e4ksi se koostuu oikeastaan \u200b\u200bvain nelj\u00e4st\u00e4 funktiosta (joista yksi on rakentaja):<\/p>\n<ol>\n<li>Rakentaja on vastuussa widgetin useiden ominaisuuksien asettamisesta, yleisimmin sen nimest\u00e4 ja kuvauksesta.<\/li>\n<li>Widget-toiminto vastaa widgetin sis\u00e4ll\u00f6n render\u00f6imisest\u00e4.<\/li>\n<li>Lomaketoiminto vastaa lomakkeen n\u00e4ytt\u00e4misest\u00e4 WordPressin hallinta-alueella, kun ty\u00f6skentelet widgetin kanssa.<\/li>\n<li>P\u00e4ivitystoiminto on vastuussa tietokantaan tallennettujen valintojen p\u00e4ivitt\u00e4misest\u00e4 (tai alustuksen ja niiden valintojen tallentamisesta, joita ei ehk\u00e4 viel\u00e4 ole tietokannassa).<\/li>\n<\/ol>\n<p>Mukava asia on, ett\u00e4 t\u00e4m\u00e4 erityinen l\u00e4hestymistapa saavutetaan perim\u00e4ll\u00e4 <a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP_Widget-<\/a> luokan toiminnallisuus.<\/p>\n<p>Ongelmana on kuitenkin se, ett\u00e4 yhdell\u00e4 luokalla on paljon ty\u00f6t\u00e4.<\/p>\n<p>Sen sijaan meid\u00e4n pit\u00e4isi erottaa jokainen toiminto omaan toiminta-alueeseensa.<\/p>\n<p>Kuten miss\u00e4 tahansa ohjelmoinnissa, on olemassa tapoja, joilla jotkut asiat ovat selkeit\u00e4, kuinka ne voidaan tehd\u00e4, ja sitten on joitain asioita, jotka voidaan tehd\u00e4 useilla tavoilla.<\/p>\n<p>Aion esitt\u00e4\u00e4 sen, miten suhtaudun siihen t\u00e4ll\u00e4 hetkell\u00e4. T\u00e4m\u00e4 voi muuttua tulevaisuudessa tai ehk\u00e4 ei, ja muut voivat suhtautua asiaan eri tavalla.<\/p>\n<p>Siit\u00e4 huolimatta toteutus tulee olemaan paljon oliokeskeisempi ja antaa jokaiselle luokalle omat vastuunsa.<\/p>\n<p>Ensimm\u00e4inen kysymys kuitenkin on, kuinka jaetaan luokka, jossa on nelj\u00e4 funktiota ja joka perii yl\u00e4luokan?<\/p>\n<h3>Bootstrapin p\u00e4ivitys<\/h3>\n<p>Ensinn\u00e4kin, meid\u00e4n on s\u00e4\u00e4dett\u00e4v\u00e4 joitain asioita laajennuksen k\u00e4ynnistyspalkissa. Nimitt\u00e4in meid\u00e4n on teht\u00e4v\u00e4 seuraava:<\/p>\n<ol>\n<li>luoda rekisterin ja asettaa sen saataville projektin kautta,<\/li>\n<li>p\u00e4ivit\u00e4 Plugin-luokka niin, ett\u00e4 se hyv\u00e4ksyy rekisterin ja lataa tilaajat,<\/li>\n<li>tarkista bootstrap<\/li>\n<\/ol>\n<p>T\u00e4ss\u00e4 on katsaus kaikkiin kolmeen yll\u00e4 olevaan.<\/p>\n<h3>1 Luo rekisteri<\/h3>\n<p>Koska olemme k\u00e4sitelleet t\u00e4t\u00e4 jo aiemmin sarjassa, pit\u00e4isi olla selv\u00e4\u00e4, kuinka t\u00e4m\u00e4 tehd\u00e4\u00e4n.<\/p>\n<p>Katso ensin <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-00-instantiate-the-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">seuraava koodi<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/\/ Setup a filter so we can retrieve the registry throughout the plugin.\n$registry = new Registry();\nadd_filter('wpwBoilerplateRegistry', function() use ($registry) {\n    return $registry;\n});<\/code><\/pre>\n<p>Huomaa seuraavaksi, ett\u00e4 luomme rekisterin (puhumme sen nimiavaruudesta hetkellisesti) ja liit\u00e4mme sen sitten mukautettuun suodattimeen, jonka avulla voimme k\u00e4ytt\u00e4\u00e4 sit\u00e4 koko laajennuksen aikana milloin tahansa.<\/p>\n<h3>2 P\u00e4ivit\u00e4 Plugin Class<\/h3>\n<p>Seuraavaksi meid\u00e4n on p\u00e4ivitett\u00e4v\u00e4 ydinlaajennusluokka (joka sijaitsee <strong>src<\/strong> &#8211; hakemistossa) niin, ett\u00e4 se viittaa rekisteriin ja lataa <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-01-update-the-plugin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">kaikki rekister\u00f6idyt tilaajat<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplate;\n\nuse WordPressWidgetBoilerplateUtilitiesRegistry;\n\n\/**\n * The base class for this plugin. Maintains a copy of the registry and starts\n * all of the objects that should hook into WordPress.\n *\/\nclass Plugin\n{\n    \/**\n     * @var Registry a reference to the simple container used to maintain plugin objects\n     *\/\n    private $registry;\n\n    \/**\n     * @param Registry $registry a reference to the simple container used to maintain plugin objects\n     *\/\n    public function __construct(Registry $registry)\n    {\n        $this-&gt;registry = $registry;\n    }\n\n    \/**\n     * Iterates through each of the subscribers maintained in the registry and registers them\n     * to the proper WordPress hook.\n     *\/\n    public function start()\n    {\n        array_map(function ($subscriber) {\n            add_action($subscriber-&gt;getHook(), [$subscriber, 'load']);\n        }, $this-&gt;registry-&gt;getRegisteredSubscribers());\n    }\n}<\/code><\/pre>\n<p>Huomaa kuitenkin, ett\u00e4 emme ole viel\u00e4 m\u00e4\u00e4ritt\u00e4neet yht\u00e4\u00e4n tilaajaa. Aloitimme t\u00e4m\u00e4n aiemmin sarjassa ja nyt on aika palata siihen, mutta teemme sen my\u00f6hemmin.<\/p>\n<p>Meid\u00e4n on kuitenkin <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-03-new-registry-function-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">lis\u00e4tt\u00e4v\u00e4 funktio<\/a> \u2013 vaikka se olisikin v\u00e4liaikainen \u2013 jotta voimme lis\u00e4t\u00e4 luokkia, jotka eiv\u00e4t ole eksplisiittisi\u00e4 tapahtuman tilaajia:<\/p>\n<pre><code>&lt;?php\n\/**\n * @return array all of the the objects that aren't subscribers registered with WordPress\n *\/\npublic function getRegisteredObjects()\n{\n    $objects = [];\n    foreach ($this-&gt;registry as $object) {\n        if (!$object instanceof AbstractSubscriber) {\n            $objects[] = $object;\n        }\n    }\n\n    return array_filter($objects);\n}<\/code><\/pre>\n<p>T\u00e4t\u00e4 muokataan my\u00f6hemmin, koska muutamme ydinluokat tilaajiksi my\u00f6hemmin.<\/p>\n<h3>3 Tarkista Bootstrap<\/h3>\n<p>Ennen kuin jatkat, mielest\u00e4ni on t\u00e4rke\u00e4\u00e4 tarkistaa bootstrap. Vaikka otsikkosi ja dokumentaatiosi voivat vaihdella, on t\u00e4rke\u00e4\u00e4 huomata, ett\u00e4 teemme seuraavat asiat:<\/p>\n<ul>\n<li>bootstrapin nimiv\u00e4li,<\/li>\n<li>est\u00e4\u00e4 p\u00e4\u00e4syn tiedostoon,<\/li>\n<li>automaattilataajalle soittaminen,<\/li>\n<li>rekisterin perustaminen,<\/li>\n<li>ja k\u00e4ynnist\u00e4\u00e4 plugin.<\/li>\n<\/ul>\n<p>Se kuulostaa paljon, mutta <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-02-the-current-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">koodi on melko lyhyt<\/a> :<\/p>\n<pre><code>&lt;?php\n\/**\n * WordPress Widget Boilerplate\n *\n * The WordPress Widget Boilerplate is an organized, maintainable boilerplate for building\n * widgets using WordPress best practices.\n *\n * @package   WordPressWidgetBoilerplate\n * @author    Your Name &lt;email@example.com&gt;\n * @license   GPL-3.0+\n * @link      http:\/\/example.com\n * @copyright 2018 - 2019 Your Name or Company Name\n *\n * @wordpress-plugin\n * Plugin Name:       WordPress Widget Boilerplate\n * Plugin URI:        https:\/\/github.com\/tommcfarlin\/wordpress-widget-boilerplate\n * Description:       An object-oriented foundation for building WordPress Widgets.\n * Version:           1.0.0\n * Author:            Tom McFarlin\n * Author URI:        https:\/\/tommcfarlin.com\n * Text Domain:       widget-name\n * License:           GPL-3.0+\n * License URI:       http:\/\/www.gnu.org\/licenses\/gpl-3.0.txt\n * Domain Path:       \/lang\n *\/\n\nnamespace WordPressWidgetBoilerplate;\n\nuse WordPressWidgetBoilerplateUtilitiesRegistry;\nuse WordPressWidgetBoilerplatePlugin;\n\n\/\/ Prevent this file from being called directly.\ndefined('WPINC') || die;\n\n\/\/ Include the autoloader.\nrequire_once __DIR__. '\/vendor\/autoload.php';\n\n\/\/ Setup a filter so we can retrieve the registry throughout the plugin.\n$registry = new Registry();\nadd_filter('wpwBoilerplateRegistry', function() use ($registry) {\n    return $registry;\n});\n\n\/\/ Start the machine.\n(new Plugin($registry))-&gt;start();\n<\/code><\/pre>\n<p>T\u00e4ss\u00e4 vaiheessa on kuitenkin aika tarkastella, millaista on jakaa aliluokka tavallisesta <a href=\"https:\/\/codex.wordpress.org\/Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Widgets API<\/a> :sta johonkin, joka sopii k\u00e4ytett\u00e4v\u00e4\u00e4n koodimalliin.<\/p>\n<h2>Lapsiluokan jakaminen<\/h2>\n<p>T\u00e4m\u00e4 osa kattaa todenn\u00e4k\u00f6isesti muutaman postauksen, koska ty\u00f6t\u00e4 on v\u00e4h\u00e4n, mutta aloitamme luomalla oman widget-luokkamme, joka perii peruswidget-luokan.<\/p>\n<p>Tee ensin <strong>API<\/strong> -hakemisto <strong>src<\/strong> &#8211; hakemistoon ja lis\u00e4\u00e4 tiedosto nimelt\u00e4 <strong>Widget.php<\/strong>. T\u00e4ss\u00e4 ovat widgetin perusteet. K\u00e4sittelemme hallinnollisia ja julkisia tyylisivuja ja JavaScript-tiedostoja seuraavassa viestiss\u00e4.<\/p>\n<p>T\u00e4ss\u00e4 vaiheessa tiedoston perusasioiden pit\u00e4isi <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-04-widget-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">n\u00e4ytt\u00e4\u00e4 t\u00e4lt\u00e4<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateAPI;\n\nuse WP_Widget;\n\nclass Widget extends WP_Widget\n{\n    \/**\n     * @var string unique identifier for your widget\n     *\/\n    protected $widgetSlug;\n\n    \/**\n     * Initializes the plugin by setting its properties and calling the parent class with the description.\n     *\n     * @param mixed $widgetSlug\n     *\/\n    public function __construct($widgetSlug)\n    {\n        $this-&gt;widgetSlug = $widgetSlug;\n\n        \/\/ TODO: update description\n        parent::__construct(\n            $this-&gt;getWidgetSlug(),\n            __('Widget Name', $this-&gt;getWidgetSlug()),\n            [\n                'classname' =&gt; $this-&gt;getWidgetSlug().'-class',\n                'description' =&gt; __('Short description of the widget goes here.', $this-&gt;getWidgetSlug()),\n            ]\n        );\n    }\n\n    \/**\n     * Return the widget slug.\n     *\n     * @return string slug variable\n     *\/\n    public function getWidgetSlug()\n    {\n        return $this-&gt;widgetSlug;\n    }\n\n    \/**\n     * TODO: This is a temporary message to show that the Boilerplate has loaded.\n     *\/\n    public function load()\n    {\n        $html = '&lt;p style=\"text-align:center; background: #fff; padding: 1em; border: 1px dotted gray; margin: 2em 2em 2em 14em;\"&gt;';\n        $html .= 'The Widget Boilerplate is loaded.';\n        $html .= '&lt;\/p&gt;';\n        echo $html;\n    }\n}\n<\/code><\/pre>\n<p>Huomaa, ett\u00e4 se vaatii yhden argumentin. Olen k\u00e4ytt\u00e4nyt widgetin nimi, mutta voit k\u00e4ytt\u00e4\u00e4 mit\u00e4 tahansa, kunhan se edustaa widgetti\u00e4si.<\/p>\n<p>T\u00e4m\u00e4 osoittaa, ett\u00e4 luokkaa instantoidaan ja ladataan oikein, kun laajennus aktivoidaan. Jos et n\u00e4e t\u00e4t\u00e4, jokin on vialla (jotka tarkistamme hetken).<\/p>\n<p>Seuraavaksi on t\u00e4rke\u00e4\u00e4 varmistaa, ett\u00e4 t\u00e4m\u00e4 luokka on lis\u00e4tty rekisteriin. Joten lis\u00e4\u00e4 seuraavat koodirivit <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-05-add-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">bootstrapiin:<\/a><\/p>\n<pre><code>&lt;?php\n\n\/\/ Add the Widget base class to the Registry.\n$registry-&gt;add('widget', new Widget('widget-name'));<\/code><\/pre>\n<p>Ja nyt, kun aktivoit laajennuksen, sinun pit\u00e4isi n\u00e4hd\u00e4 seuraava:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160983-61e7189c9c671.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160983-61e7189c9c671.png\" alt=\"WordPress-widgetit: Refaktorointi, osa 7\"><\/a><\/p>\n<p>Jos ei, tarkista koodi <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">kehityshaarassa<\/a> varmistaaksesi, ett\u00e4 sinulla on kaikki t\u00e4ss\u00e4 viestiss\u00e4 kuvattu.<\/p>\n<h2>Toteuttavat tilaajat<\/h2>\n<p>Tulevissa viesteiss\u00e4 aiomme tarkastella, kuinka voimme ottaa tilaajat k\u00e4ytt\u00f6\u00f6n sivuston julkiselle puolelle (eli miss\u00e4 widgetin sis\u00e4lt\u00f6 n\u00e4ytet\u00e4\u00e4n). Ja teemme samoin sivuston hallintoalueella.<\/p>\n<p>Lopuksi k\u00e4\u00e4nn\u00e4mme huomiomme koodiin, joka vastaa tietojen suojaamisesta ja sarjoittamisesta (lue: widgetin p\u00e4ivitt\u00e4misest\u00e4), ja sitten katsomme, milt\u00e4 p\u00e4ivitetyn kattilalevyn lopullinen versio n\u00e4ytt\u00e4\u00e4.<\/p>\n<p>T\u00e4ss\u00e4 viestiss\u00e4 k\u00e4ytt\u00e4m\u00e4mme ensisijainen strategia on kuitenkin aliluokan jakaminen, jotta sit\u00e4 voidaan edelleen k\u00e4ytt\u00e4\u00e4 muiden luokkien kanssa k\u00e4ytt\u00e4m\u00e4ll\u00e4 rajapintoja ja perusluokkia, jotka on jo m\u00e4\u00e4ritetty koodikannassa.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ongelma WP_Widgetin kanssa on, ett\u00e4 se on paljon ty\u00f6t\u00e4 yhdell\u00e4 luokalla. Joten aloitamme sen muokkaamisen nyt.<\/p>\n","protected":false},"author":1,"featured_media":236064,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[719],"tags":[1166],"class_list":["post-231352","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kehittaejae","tag-affiai-fi"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/231352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/comments?post=231352"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/231352\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media\/236064"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media?parent=231352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/categories?post=231352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/tags?post=231352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}