{"id":194,"date":"2023-02-28T07:00:00","date_gmt":"2023-02-28T15:00:00","guid":{"rendered":"https:\/\/dejal.com\/blog\/?p=194"},"modified":"2023-02-27T13:56:40","modified_gmt":"2023-02-27T21:56:40","slug":"a-simon-filters-case-study","status":"publish","type":"post","link":"https:\/\/dejal.com\/blog\/a-simon-filters-case-study\/","title":{"rendered":"A Simon filters case study"},"content":{"rendered":"<body><p><\/p>\n<p>Before I moved <a href=\"https:\/\/dejal.com\/blog\/\">the Dejal blog<\/a> to WordPress, I had a test that was bundled with Simon called \u201cDejal posts\u201d (you may still have this if you\u2019re a long-time customer). This was a great example of using multiple filters to narrow down the output of a <strong>Web Page<\/strong> service. While the URL it monitored is no longer valid, it remains a useful example for you to learn more about creating your own filters.<\/p>\n<p>The general idea of this test was to look at a \u201cRecent Posts\u201d page of the Dejal site, which listed all recent blog, forum, FAQ etc posts and their comments, and output some tidy text describing the most recent one, along with a changed state when a new post or comment is added.<\/p>\n<p>Firstly, here\u2019s the <strong>Service<\/strong> page; nothing remarkable here (the cookies are automatically recorded, and unimportant for this test):<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Service\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/service.png?resize=758%2C246&#038;ssl=1\" alt=\"Service\" width=\"758\" height=\"246\" border=\"0\" loading=\"lazy\"><\/p>\n<p>The most interesting page is the <strong>Filters<\/strong> one:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Filters\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/filters-1.png?resize=757%2C814&#038;ssl=1\" alt=\"Filters\" width=\"757\" height=\"814\" border=\"0\" loading=\"lazy\"><\/p>\n<p>When you check the test and look in the <strong>Activity<\/strong> log, you can see the output from each of those filters (from bottom to top):<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Activity\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/activity.png?resize=1200%2C166&#038;ssl=1\" alt=\"Activity\" width=\"1200\" height=\"166\" border=\"0\" loading=\"lazy\"><\/p>\n<p>Another way to view the output is via the <strong>Preview<\/strong> pane, which includes not only the service response and headers, but also the full output of each filter, to help you diagnose each step.<\/p>\n<p>Here\u2019s the output of the service; the full HTML of the web page:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Preview0\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/preview0.png?resize=673%2C252&#038;ssl=1\" alt=\"Preview0\" width=\"673\" height=\"252\" border=\"0\" loading=\"lazy\"><\/p>\n<p>Let\u2019s break down each of the filters, via the <strong>Preview<\/strong> filter output.<\/p>\n<p>The first filter, a <strong>Block<\/strong> one, takes the service response as its <strong>Input<\/strong>, and has <strong>Start<\/strong> text of <code>&lt;tbody&gt;<\/code> and <strong>End<\/strong> text of <code>&lt;td class=\"replies\"&gt;<\/code>. This finds the first occurrence of each of those bits of HTML in the service response, which corresponds with the most recent post information:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Filter1\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/filter1.png?resize=657%2C98&#038;ssl=1\" alt=\"Filter1\" width=\"657\" height=\"98\" border=\"0\" loading=\"lazy\"><\/p>\n<p>This filter outputs that:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Preview1\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/preview1.png?resize=670%2C242&#038;ssl=1\" alt=\"Preview1\" width=\"670\" height=\"242\" border=\"0\" loading=\"lazy\"><\/p>\n<p>The second filter is another <strong>Block<\/strong> one. It takes the output of the first filter as its input, and narrows it down further to just the title of the post. Notice that it also uses options disclosed on the right-hand-side of the filter configuration: it looks for the second occurrence of the <strong>Start<\/strong> text, searching from the beginning of the input:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Filter2\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/filter2.png?resize=657%2C98&#038;ssl=1\" alt=\"Filter2\" width=\"657\" height=\"98\" border=\"0\" loading=\"lazy\"><\/p>\n<p>The output of this filter is the post title:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Preview2\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/preview2.png?resize=686%2C244&#038;ssl=1\" alt=\"Preview2\" width=\"686\" height=\"244\" border=\"0\" loading=\"lazy\"><\/p>\n<p>The third filter is yet another <strong>Block<\/strong> (it is one of the most useful filters), but the input is different: this time it uses the output of the first filter, instead of the previous one (as is the default). It also has an option to look for the third occurrence:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Filter3\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/filter3.png?resize=647%2C92&#038;ssl=1\" alt=\"Filter3\" width=\"647\" height=\"92\" border=\"0\" loading=\"lazy\"><\/p>\n<p>It extracts the author information:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Preview3\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/preview3.png?resize=692%2C242&#038;ssl=1\" alt=\"Preview3\" width=\"692\" height=\"242\" border=\"0\" loading=\"lazy\"><\/p>\n<p>Filter number four is different. It uses an <strong>Ignore Links<\/strong> filter to extract out just the author name from the previous filter output. The previous filter doesn\u2019t do this as when you were not logged in on the Dejal site, only the name is included (in which case this filter has no effect):<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Filter4\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/filter4.png?resize=647%2C92&#038;ssl=1\" alt=\"Filter4\" width=\"647\" height=\"92\" border=\"0\" loading=\"lazy\"><\/p>\n<p>The output is just the non-HTML part of the input:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Preview4\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/preview4.png?resize=692%2C244&#038;ssl=1\" alt=\"Preview4\" width=\"692\" height=\"244\" border=\"0\" loading=\"lazy\"><\/p>\n<p>Next we\u2019re back to a <strong>Block<\/strong> filter again, but this time looking at the original service response text to extract the number of replies to the post:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Filter5\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/filter5.png?resize=647%2C92&#038;ssl=1\" alt=\"Filter5\" width=\"647\" height=\"92\" border=\"0\" loading=\"lazy\"><\/p>\n<p>This should always output a number:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Preview5\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/preview5.png?resize=688%2C242&#038;ssl=1\" alt=\"Preview5\" width=\"688\" height=\"242\" border=\"0\" loading=\"lazy\"><\/p>\n<p>We then use a <strong>Singular or Plural<\/strong> filter, to take the number found in the previous filter and output \u201c<code>reply<\/code>\u201d if it is one, or \u201c<code>replies<\/code>\u201d for any other number:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Filter6\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/filter6.png?resize=648%2C96&#038;ssl=1\" alt=\"Filter6\" width=\"648\" height=\"96\" border=\"0\" loading=\"lazy\"><\/p>\n<p>As seen in the preview:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Preview6\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/preview6.png?resize=687%2C244&#038;ssl=1\" alt=\"Preview6\" width=\"687\" height=\"244\" border=\"0\" loading=\"lazy\"><\/p>\n<p>The last filter puts it all together: an <strong>Override Custom<\/strong> filter uses variables to combine the output of several filters in a nice readable way. In this case all the variables are variations of the filter output, but other variables are available too. Something that isn\u2019t immediately obvious is that you can insert numbers to reference specific filters (otherwise it refers to the previous one):<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Filter7\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/filter7.png?resize=648%2C96&#038;ssl=1\" alt=\"Filter7\" width=\"648\" height=\"96\" border=\"0\" loading=\"lazy\"><\/p>\n<p>Which results in:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Preview7\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/preview7.png?resize=687%2C246&#038;ssl=1\" alt=\"Preview7\" width=\"687\" height=\"246\" border=\"0\" loading=\"lazy\"><\/p>\n<p>So now that we\u2019ve got some nice output text, what do we do with it? Of course, you can just see it in the <strong>Tests<\/strong> list, if you have the last change and failure displayed:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Tests\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/tests.png?resize=708%2C292&#038;ssl=1\" alt=\"Tests\" width=\"708\" height=\"292\" border=\"0\" loading=\"lazy\"><\/p>\n<p>But you\u2019ll probably want to get a notification:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" title=\"Notifiers\" src=\"https:\/\/i0.wp.com\/dejal.com\/blog\/wp-content\/uploads\/2023\/02\/notifiers.png?resize=753%2C200&#038;ssl=1\" alt=\"Notifiers\" width=\"753\" height=\"200\" border=\"0\" loading=\"lazy\"><\/p>\n<p>I hope this case study is helpful. Most tests don\u2019t need a series of filters like this, and there are other ways to achieve similar effects (like writing all the logic in a script), but it can be very useful when you want it. You can use similar techniques in your own tests.<\/p>\n<p><\/p>\n<\/body>","protected":false},"excerpt":{"rendered":"<p>Before I moved the Dejal blog to WordPress, I had a test that was bundled with Simon called \u201cDejal posts\u201d (you may still have this if you\u2019re a long-time customer). This was a great example of using multiple filters to narrow down the output of a Web Page service. While the URL it monitored is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[16,4],"tags":[],"class_list":["post-194","post","type-post","status-publish","format-standard","hentry","category-faq","category-simon"],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/posts\/194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/comments?post=194"}],"version-history":[{"count":2,"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/posts\/194\/revisions"}],"predecessor-version":[{"id":196,"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/posts\/194\/revisions\/196"}],"wp:attachment":[{"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/media?parent=194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/categories?post=194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dejal.com\/blog\/wp-json\/wp\/v2\/tags?post=194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}