-
Posts
1,331 -
Joined
-
Last visited
-
Days Won
61
Everything posted by BitPoet
-
The EEC just explained what has been the law in Europe long before the GDPR. The German publisher Heise for example has released a jquery plugin with data protection conforming social buttons in 2011 for this reason (link to fork with English docs). The buttons there act as placeholders and only load resources from the respective sites when clicked once. It would apply to embedded content from any non-EU site, but especially to all the big players who are known to practice data harvesting and aggregation.
-
$count_arr = []; foreach($page->my_repeater as $rep) { $name_normalized = ucwords(strtolower($rep->lastname . " " . $rep->firstname)); $count_arr[$name_normalized]++; } arsort($count_arr, \SORT_NUMERIC); $leaders = array_slice($count_arr, 0, 5); The caveats are names with prefixes, like Scottish McSomething, which will end up being Mcsomething, and that there's no sorting among names with equal vote count.
-
If there aren't any 40x errors, look into the returned content for JqueryUI.js and its friends. The web server might be inserting error or warning messages that break the parsing.
-
Do you see any errors in the browser's developer console, or any not loaded scripts in its network tab?
-
I'd use ?: instead of ??. At least if you can trust the truthy-ness of the field's value if set (which should be okay for keywords and description). And... though not necessarily better, I sometimes add a generic method to the Page class to abstract away logic from the template. // in site/ready.php: wire()->addHook("Page::getWithDefault", null, function(HookEvent $event) use($pages) { $page = $event->object; $property = $event->arguments(0); return $page->get($property) ?: $pages->get(1)->get($property); }); Then your template code boils down to <?= $page->getWithDefault("meta_description") ?>
-
You can use WireArray's explode method to get the required property(s) from your repeater. "socials" => $m->socials->explode(['title', 'url']) Pass it a function instead of a property name or names to add fancier processing: "socials" => $m->socials->explode(function($item, $key) { return [ "name" => $item->title, "link" => $item->url ]; })
-
I already submitted it, and it's pending approval, so it should become visible in the next few days. The latest version on GitHub also lets you add custom CSS classes to the links.
-
Here's a little text formatter module that redirects all external links found in a textarea (e.g. for hit counting) to a given URL. TextformatterExternalRedirect GitHub repo As TextFormatters do, this module modifies the contents of the textarea (HTML) at rendering time. It prepends the given URL to the link address for external links (http and https), optionally makes sure that the link is opened in a new window and allows you to add css classes to such links. All options can be configured in the module's configuration settings. Usage: Download the zip archive and extract it to site/modules, the rename the top folder to TextformatterExternalRedirect Go to the backend and select "Modules" -> "Refresh", then click "Install" for "External Link Redirect" Click "Settings" and configure the module Go into the field configuration for the field(s) you want this formatter to apply to and add it from the dropdown Done, now any external links in the configured fields will have the configured settings applied Feel free to leave feedback and post and questions you have here.
-
- 8
-
-
I have updated the code to add an option for that. The module is now available at GitHub. Check "Open in new window" in the module configuration to add a target="_blank" attribute (or replace an existing target attribute's value with "_blank").
-
This is probably a perfect case for a custom textformatter. Those are invoked when the content of a textarea is rendered. Here's an example module that prepends a custom URL to all external links. You need to enter /my-redirect-link/?link= in the module's configuration after installation and configure the field in question to use TextformatterExternalRedirect. <?php namespace ProcessWire; /** * ProcessWire External Link Redirector Textformatter * * Prefixes the URL in each external link with a local URL that redirects to the * original URL after doing whatever it is that it needs to do. * * The URL to prepend is configured in this module's settings * (Backend: Modules -> Configure -> TextformatterExternalRedirect) * * It assumes that the prepended URL ends with a GET parameter and an equal sign, * so it urlencode()s the original URL. * * Example: * Link is <a href='https://processwire.com'> * Prepend URL: /myredirector/?link= * Textformatter generates: <a href='/myredirector/?link=https%3A%2F%2Fprocessire.com'> * */ class TextformatterExternalRedirect extends Textformatter implements ConfigurableModule { public static function getModuleInfo() { return array( 'title' => 'External Link Redirect', 'version' => '0.0.4', 'summary' => "Parses links in textareas and prepends a local redirector URL", ); } public function __construct() { parent::__construct(); $this->set("prependUrl", ""); } public function format(&$str) { $str = trim($str); if(!strlen($str)) return; if(!$this->prependUrl) return; $that = $this; $str = preg_replace_callback( '/(<a[^>]+href=)(["\'])([^"\']*)(\\2)/i', function($match) use($that) { // If link is not external, we return the original link if(!$that->isExternalLink($match[3])) return $match[0]; return $match[1] . $match[2] . $that->prependUrl . urlencode($match[3]) . $match[2]; }, $str ); } public function isExternalLink($url) { foreach($this->config->httpHosts as $hostname) { // If the target host is one of our own hostnames, // this link is not external. if(preg_match("~^https?://{$hostname}~i", $url))) return false; } // Otherwise, all http(s) links are definitely external // and get redirected. if(preg_match('~^https?://~i', $url))) return true; // No match, then we have a relative url (internal) or some other // scheme (e.g. mailto) that we don't redirect. return false; } public static function getModuleConfigInputfields($data) { $inputfields = new InputfieldWrapper(); $f = wire('modules')->get("InputfieldText"); $f->attr('id+name', 'prependUrl'); $f->label = __("URL to prepend", __FILE__); $f->description = __("This URL is prepended. It is assumed that it ends with a GET parameter to which the URL-encoded original link will be passed.", __FILE__); if(isset($data["prependUrl"])) $f->attr('value', $data["prependUrl"]); $inputfields->append($f); return $inputfields; } }
-
Are these page names or page ids? For $p->tags->add to work, anything numeric must be a valid page id. And, duh, I have to say sorry. I just took a look into PageArray.php and saw that you can actually pass an array of pages to PageArray::add and it will call itself recursively, thought the same rules apply then. If it looks numeric, it needs to be a page id.
- 9 replies
-
- api
- page reference
-
(and 1 more)
Tagged with:
-
Yes, loop over $tags and call $page->tags->add() for each like in the snippet you posted. Of course, you can just call $sanitizer->text for every $tag inside the loop in your third code snippet and go without the array_map. array_map is just a function that calls the passed function for every entry in the array given to it and returns a new array with the results.
- 9 replies
-
- 1
-
-
- api
- page reference
-
(and 1 more)
Tagged with:
-
My guess is that this might be the culprit. If you submit multiple tags, that likely returns something like "array-2". You might need to do something like this: $rawTags = $input->post->tags; $tags = array_map( function($tag) use($sanitizer) { return $sanitizer->text($tag); }, is_array($rawTags) ? $rawTags : [$rawTags] );
- 9 replies
-
- api
- page reference
-
(and 1 more)
Tagged with:
-
What does the web server error log have to say? You should see a more verbose error description there (or perhaps even in Chrome developer console on the network tab).
-
Thanks a lot for that! I‘m away for the weekend and can‘t test it thoroughly, but it looks fine so I merged it to the dev tree. Will give it a closer look and push to master Sunday evening.
-
Haven't done it, but since Office 365 uses Azure with SAML as authentication protocol, the SamlAuth module might work. Maybe @Adam can chime in whether he has used his module with Azure yet?
-
I've still got that on the back burner, but it'll likely be the next quarter until I find enough time for it. It's going to need some deep digging, unfortunately.
-
Date field output formatting with strftime() not outputting AM/PM
BitPoet replied to elabx's topic in General Support
You'll have to use lowercase "%p" and/or a workaround. The uppercase %P is missing in many platforms' native strftime implementation, and PHP just uses what the platform (i.e. the operating system) offers. So if you're e.g. on windows, a number of format characters listed in the strftime manual will throw an error or fail silently. -
And, if you want a nice CK'ish dropdown instead of having the user type, @Robin S' Hanna Code Dialog might also be an option.
-
AdminDevModeColors: different colors for development backends
BitPoet replied to BitPoet's topic in Module/Plugin Development
Implemented in dev but not tested yet ? -
Nothing. Escaping single quotes as HTML entities is perfectly valid and just an optical thing, the behavior stays the same as if there were literal single quotes.
-
Thanks for sharing this, a wonderful and funny read that also brings up some sentimental points. And, coincidentally, I also read his article about quitting at YouTube which ends with My request to take six months off next year to go backpacking (thru-hiking) on the Pacific Crest Trail was approved a week ago. Didn't think it might be this valuable in my CV?
-
Need help installing Mollie module with composer vendor files
BitPoet replied to bramwolf's topic in General Support
Any change if you use the version from the PW3 branch in the github repo for PaymentModule (which is basically the same with the namespace added)? -
Need help installing Mollie module with composer vendor files
BitPoet replied to bramwolf's topic in General Support
It might be a dumb question, but since the dependency check that gives the message is a core function reliably used by many modules, are you sure PaymentModule is really installed (i.e. showing up in "Modules" -> "Site" in the backend)?