Jump to content

psy

Members
  • Posts

    654
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by psy

  1. Hi @dragan Thanks for the feedback. I believe PushAlert only accepts the root domain. I will ask PushAlert support for clarification. The icon is always visible. After you've subscribed, it changes to an unsubscribe button. Not sure but may be related to the date issue? No timezones are hardcoded. It is a standard PW Date Time picker inputfield. It gets converted to a timestamp for submission to PushAlert and saved in the field json data. It gets reconverted to a string when the page edit is redisplayed by the date field. The URL submitted to PushAlert should be the frontend URL (always has been in my testing?), called in the code with $page->httpUrl. Are you using ProCache and stripping optional tags? The script needs the closing </head> tag. I'll work on an alternative way to manually call the script in the template. When you use only the PushAlert code, you miss the custom onSuccess callback function. This function posts back to PW to save the subscriber ID and logged-in user ID in the database. <script> function callbackOnSuccess(result) { let topw = {}; topw.subscriber_id = result.subscriber_id; topw.alreadySubscribed = result.alreadySubscribed; var json = JSON.stringify(topw); return fetch("https://mywebsite.com/pushalert-endpoint/", { method: "POST", headers: { "Content-Type": "application/json", }, body: json }); } </script> The only time, very early on in the development cycle, I got double notifications was when I had both sw.js and the PWABuilder service worker installed and they clashed horribly. The existing service worker called the page as did PW for faster load times and so the notification went twice. Are you using multi-language? Maybe that's having an effect?
  2. This module enables you to send push notifications and receive information about sent notifications on your HTTPS ProcessWire website. It enables you to: Create a field of type FieldtypePushAlert that you can add to a page template. This is a multi-input field widget that enables you to send notifications from your page in the admin Page Edit and monitor statistics - Attempted, Delivered, Clicked, etc Send notifications from a page template directly using the API, eg to PW users who have a specific role and have subscribed to notifications Capture subscriptions on your website front end All kudos to the great support team at PushAlert and to all the ProcessWire developers who've helped me with this project. Download from the Modules directory at: https://modules.processwire.com/modules/push-alert/ or from GitHub at: https://github.com/clipmagic/PushAlert Full instructions for use are in the module README.md file. Enjoy!
  3. Hi @Steve_Stifler and welcome to ProcessWire Forget the WP model of themes etc that force you into their on-screen boxes. With ProcessWire you have complete control over what goes where & how on the frontend. You design your frontend layout and retrieve the data you need to populate the page in the templates
  4. Quick update Please (whatever deity you choose), I'm close to publishing an alpha version. The PushAlert API is easy. It's the PW integration that challenged me. If you only ever want to capture subscriptions to PushAlert and send notifications carte-blanche via a PW template without capturing stats, and/or sending advanced options, eg to a specific user instead of everybody, the instructions in the PushAlert docs will get you going. This module is more than just a wrapper... more soon including the readme.md (why does that always come last?) Anyone interested in being a guinea pig tester?
  5. Usual way is something like this in your module (adjust to suit your needs): /** * @return array */ static public function getDefaultConfig() { return array( "my-module-config-1" => "", "my-module-config-2" => "", "my-module-config-3" => "my default setting for this config field", ); } /** * Populate default configuration (will be overwritten after constructor with user's own configuration) * */ public function ___construct() { foreach(self::getDefaultConfig() as $key => $value) { $this->$key = $value; } } /** * @param array $data * @return InputfieldWrapper */ public function getModuleConfigInputfields(array $data) { $inputfields = new InputfieldWrapper(); $defaults = self::getDefaultConfig(); $data = array_merge($defaults, $data); $f = $this->modules->get('InputfieldText'); $f->name = 'my-module-config-1'; $f->label = __('MyModule key 1'); $f->value = $data['my-module-config-1']; $f->collapsed = 5 ; // collapsedPopulated $inputfields->add($f); $f = $this->modules->get('InputfieldText'); $f->name = 'my-module-config-2'; $f->label = __('MyModule Config key 2'); $f->collapsed = 5 ; // collapsedPopulated $f->value = $data['my-module-config-2']; $inputfields->add($f); $f = $this->modules->get('InputfieldText'); $f->name = 'my-module-config-3'; $f->label = __('MyModule config key 3'); $f->collapsed = 5 ; // collapsedPopulated $f->value = $data['my-module-config-3']; $inputfields->add($f); return $inputfields; } Then you can call it in your template like: <?php $myModule = $modules->get('MyModule'); ?> <p><?=$myModule->my-module-config-1?></p> Best way to learn is to look into other popular PW custom modules ?
  6. Thanks for the suggestions. I ended up putting the conditional further down the food chain for now. It works and with page caching, shouldn't affect the front end page render speed. Maybe in a later release I'll fine tune it a bit more ?
  7. More... $page->template == 'admin' Works BUT it interferes with the receipt of the WireHttp call to get the json result. It always comes back as null. Works fine when I remove this conditional from the hook, but then the front end falls over. I supposed I could put a conditional further down to see if the http result is valid but am concerned that will dramatically slow down front end page load. The test could only be done after the GET call and a bunch of database hokey pokey. Would be much more efficient to have it at the start of the hook - if it's the front end, return now; if it's admin, process the GET call etc
  8. @matjazp Thanks, tried both and they didn't work. ? $page->template == 'admin' meant it affected the page list $page->process is 'Process Template' for both front and back end, including page list - maybe due to hook method Page::loaded
  9. I'm well into developing a module that has both front and admin features so don't want to flag the module as 'admin only'. One hook has very specific requirements: ONLY applicable in admin ONLY applicable if in page edit on a page that will have front end output (not a custom admin page) ONLY applicable if the page has a particular Fieldtype which is a custom field type specific to this module suite I've got 2 & 3 down but am stuck trying to figure out 1 despite trying lots of things. When viewing the page on the front end, the hook activates and crashes the page. public function ready() { $this->addHookAfter('Page::loaded', $this, 'hookResultJson'); } public function hookResultJson (HookEvent $event) { $page = $event->object; // Only applicable in admin area in page edit mode // STUCK ON THIS ONE ????? // Confirm the page has a FieldtypeMyCustom field $fields = $this->wire('fields'); $paFields = $fields->find('type=FieldtypeMyCustom'); if (!$paFields->count) return; $widgetFld = ''; foreach ($paFields as $item) { if ($page->hasField($item->name)) { $widgetFld = $fields->get("name=".$item->name); break; } } // No field of FieldtypeMyCustom on the page/template if (empty($widgetFld)) { return; }; // We are now in admin edit of a page that has a field of type FieldtypeMyCustom // ... } Any suggestions for the 'admin only page edit' conditional statement? TIA psy
  10. Agree with @wbmnfktr Have always used subdomains on my development host and never encountered this issue
  11. @adrian and @thetuningspoon thanks! ? Needed some tweakage as FieldsetPage, although based on Repeater, only has one page, not a number of child pages under the repeater page, in admin. Got it working with: /** * Creates a fieldsetpage field with associated fieldgroup, template, and page * * @param string $repeaterName The name of your fieldsetpage field * @param string $repeaterFields List of field names to add to the fieldsetpage, separated by spaces * @param string $repeaterLabel The label for your fieldsetpage * @param string $repeaterTags Tags for the fieldsetpage field * @return Returns the new FeildsetPage field * */ public function createFieldsetPage($repeaterName,$repeaterFields,$repeaterLabel,$repeaterTags) { $fieldsArray = explode(' ',$repeaterFields); $f = new Field(); $f->type = $this->modules->get("FieldtypeFieldsetPage"); $f->name = $repeaterName; $f->label = $repeaterLabel; $f->tags = $repeaterTags; $f->save(); //Create fieldgroup $repeaterFg = new Fieldgroup(); $repeaterFg->name = "repeater_$repeaterName"; //Add fields to fieldgroup foreach($fieldsArray as $field) { $repeaterFg->append($this->fields->get($field)); } $repeaterFg->save(); //Create template $repeaterT = new Template(); $repeaterT->name = "repeater_$repeaterName"; $repeaterT->flags = 8; $repeaterT->noChildren = 1; $repeaterT->noParents = 1; $repeaterT->noGlobal = 1; $repeaterT->slashUrls = 1; $repeaterT->fieldgroup = $repeaterFg; $repeaterT->save(); // Create the admin/repeaters page (different to standard repeaters) // add more options to the page if you prefer $repeaterPage = new Page(); $repeaterPage->of(false); $repeaterPage->template = 'admin'; $repeaterPage->name = "for-field-" . $f->id; $repeaterPage->title = $f->name; $repeaterPage->parent_id = $this->pages->get("path=/admin/repeaters/"); $this->pages->save($repeaterPage); // Associate the FieldsetPage field with the new admin/repeater page $f->parent_id = $this->pages->get("name=$repeaterPage")->id; $f->template_id = $repeaterT->id; //Now, add the fields directly to the FieldsetPage field foreach($fieldsArray as $field) { $f->repeaterFields = $this->fields->get($field); } $f->save(); return $f; } and example usage: $fsPageName = "fspage_widget"; $fsPageFields = "widget_title"; $fsPageLabel = _("My Widget"); $fsPageTags = "widget"; $f = $this->createFieldsetPage($fsPageName,$fsPageFields,$fsPageLabel,$fsPageTags);
  12. In my code, I create all the fields I want included in the FieldsetPage - all good. I then create my FieldsetPage field and it appears in the Admin->Fields list - seems all good. $fields = wire('fields'); if(!$fields->get("name=widget_title")) { $field = new Field; $field->type = $modules->get("FieldtypeText"); $field->name = "widget_title"; $field->label = $this->_("Message Title"); $field->description = $this->_("Max length 64 characters."); $field->maxlength = 64; $field->stripTags = true; $field->tags = "widget"; $field->set('showCount', InputfieldText::showCountChars); $field->save(); } // Fieldset page (requires PW v3.0.74 or later) if(!$fields->get("name=fspage_widget")) { $widget = new Field; $widget->type = $modules->get("FieldtypeFieldsetPage"); $widget->name = "fspage_widget"; $widget->label = $this->_('My Widget'); $widget->tags = "widget"; $fields->save($widget); } Problem arises when I try to add fields to the FieldsetPage. While the field is created, the template and field group are not. When I try to add via code, eg $widget = $fields->get("name=fspage_widget"); $templateName = FieldtypeRepeater::templateNamePrefix . $widget->name; // Correct name but no template yet assigned to FSPage field $template = $templates->get($templateName); // results in NULL $fg = $template->fieldgroup; // Ditto due to above $titleFld = $fields->get("name=widget_title"); $fg->add($titleFld); $fg->save(); // No fieldgroup so no save it falls over with NULL template and NULL fieldgroup. I can manually add fields to the FieldsetPage via the admin field edit screen, at which point the appropriate template & fieldgroup get generated. If I try to force the creation of the template in my code when I create the field, I end up with 2 templates - repeater_fspage_widget and repeater_fspage_widget1. That leads to all kinds of madness and no fields appear in the admin edit screen for 'fspage_widget' even though the field(s) I add show they're attached to a template. It's all clearly visible in the database. I've read everything I can find including the actual code and this forum article: In this scenario, the fieldsetPage fields with their templates & fieldgroups already exist and are being migrated. Even @ryan says a the end: So, question is, after adding a new FieldsetPage field via code, how do I programmatically add its template, fieldgroup & fields?
  13. Did you update the site/config.php file $config->httpHosts array to include the new domain name? And/or change the root dir in your .htaccess file? Had similar issue today where dev site on same server with same db was moved to new domain name and different site path, eg From: http://999.99.99.99/~myclient dir/ to http://www.myclientsite.com 1/ Make changes to the /site/config.php httpHosts whitelist to add the new domain name: /** * Installer: HTTP Hosts Whitelist * */ $config->httpHosts = array( 'www.mysite.com', 'mysite.com', '999.99.99.99' ); 2/ Make a change to the .htaccess file to update it from the old site root to the new site root: # ----------------------------------------------------------------------------------------------- # 11. OPTIONAL: Set a rewrite base if rewrites aren't working properly on your server. # And if your site directory starts with a "~" you will most likely have to use this. # ----------------------------------------------------------------------------------------------- # RewriteBase / # RewriteBase /pw/ # RewriteBase /~user/ # RewriteBase /~myclient/
  14. Module starting to come together. Will of course give credit to other devs whose module code I've studied and in some cases, unashamedly copied, including @elabx draft OnSignal and nico's MarkupSEO. Ready now to jump
  15. PushAlert4PW WIP.... Some more on the PushAlert REST API. Every sent alert requires a URL and it appears in the notification. Silly me thought that was 'just life'. Didn't realise until I chatted with Alex from PushAlert, that it is in fact the URL to which notification responses are sent. It does not have to be the page, eg an admin page, that sent the push notification. So cool! The URL also appears in the notifications so thinking about hooking into the front end home page URL to capture the json responses and save the data to a different page that connects the sending page with the message id. Onward & upward
  16. Yes, absolutely - same as sending email campaigns directly from the website vs going with an email-sending provider such as CampaignMonitor or MailChimp. This is a key decider for going with a notification-sending provider
  17. Thank you @dragan @PWaddict and @elabx for your detailed and considered opinions. Much appreciated. I investigated all your suggestions and all of you asked why I chose PushAlert. Simple really, it was the first I found some time last year. I searched for others but none of the solutions you presented came up. PushAlert seemed to have the best plans and I've found their tech support to be responsive and helpful. OneSignal appears to be the biggest and has the most fully documented solutions. However, like @elabx, I was uncomfortable with the fact that you had to pay for GDPR security??? The leap from free to US$99/mo for what should be a right not a privilege didn't sit well with me. I guess they make their money from selling the marketing data rather from their sender clients? Ended up going back to PushAlerts and they have a published GDPR Compliance page covering all plans, including free. https://pushalert.co/gdpr On the flip side, you don't get the detailed reporting but then I doubt 99.9% of clients would want it. They want to know how many notifications were sent, how many were successfully received, how many CTA's clicked and how many unsubscribed. All this info is provided by PushAlert while still protecting subscriber confidentiality. Works for me! @elabx would you consider sharing your code with me? Why reinvent the wheel and your ideas are exactly what I'm looking for to adapt to PushAlert. Thanks again
  18. Background I'm creating a module to integrate https://pushalert.co/ into ProcessWire. You actually don't even need a module. You could just use the "Other Websites" javascript provided by PushAlert for basic functionality, ie send a broadcast notification to all subscribers. This is essentially what all the other integrations, including WordPress, do. The WP integration installs a widget with a form enabling the admin to enter details such as title, message, etc from a blog post. It does not: collect any statistics within the CMS about the notification enable audience fine tuning to eg a particular subscriber or subscriber segment within WP. The admin needs to use the PA dashboard for that functionality PushAlert has a javascript and REST API. It's intended that this module will use both. https://pushalert.co/documentation What my module does so far: associate a subscription with a user. FE user clicks a button on the website front end to subscribe and/or agrees to the browser popup to accept notifications from this site send broadcast push alerts from a page within admin It doesn't have a 'widget' but easy enough to create a fieldsetpage with the relevant fields and add that fs page to any appropriate templates, then with a hook, send the notification. Need to be careful that once published/sent, the notification is not automatically re-sent on subsequent page edits. Looking for help/collaboration on how best: to send a notification, eg from a blog post, then track the statistics. Dilemma is that the push notification must come from the admin page. Responses go to the sending page which, as it's an admin page, is restricted and will not accept the https response. This is where the other CMS integrations stop. The only json response from PushAlert is the status, eg 'success', and the notification id. There is no opportunity at this point to capture the sending page id. handle, 'once sent on page publish', do not automatically resend on future page edits Am thinking along the lines that FS Page will have a @kongondo runtime markup field https://modules.processwire.com/modules/fieldtype-runtime-markup/ to pull the stats from PushAlert. Every time an admin visits the page, the stats will update. Once an admin checks the 'Send notification on page publish' checkbox, a hook creates new front end page that records the 'sender page', sends the notification request to PA, which then uses that newly created frontend page, as the response endpoint. Another rook re-associates the front end page with the admin page (eg blog post), to update the stats. Potential use cases: Notify individual and/or users with a particular role of an event, eg "New work opportunity" for job seekers; new blog post published; entries now open, etc... Looking for help/ideas/collaboration on this module. Please let me know if you're interested and as I do, believe this would be a great addition to ProcessWire
  19. @teppo totally agree. It's definitely not the answer to accessibility for the visually impaired. All sites should be readable by screen-readers. It's just another tool in toolbox and a nice addition ?
  20. Found this today: Wild, weird and out there, it's a big bonus to making PW sites more accessible... https://websitevoice.com/ Talk to me ProcessWire ?
  21. @MoritzLost Great tutorial I often use Repeater Matrix field with an added Fieldset Page containing the styling options for that section. FS page means it's easy to add a single field to different templates. Like you, I only give the client what options they need rather than the complete set. In the example below, the HTML theme is Canvas which is based on Bootstrap.
  22. @kongondo, thank you! New day here and taking another look. I noticed in the code that even though I'm only calling FormBuilder to get the entries, all the FB scripts & css are loading into the <head>. Digging deeper to see if this is causing a conflict. Grateful for your offer to look around the code if I can't resolve it. Will keep you posted. More: Yep, FormBuilder files seem to be the problem. Now to figure out how to use FB in admin area to get the entries without the scripts loading. SOLVED: One of the things my custom function 'formsMultiple' did was render the form and add the output to the final returned array. Works great on the front end but not needed here. Made the form rendering optional in the 'formsMultiple' function and in the RTM code, said don't do it. End result is RTM field and rest of the admin page display as expected. Thanks for the help & pointing me in the right direction.
  23. @kongondo thanks for chipping in ? My function is in a custom module and the code in the RTM field is: $custom = $this->wire('modules')->get('CustomFunctionsTBR'); return $custom->getJobSeekerData ($page); The function in CustomFunctionsTBR is: function getJobSeekerData ($page) { $skills = $this->formMultiple('jobseeker_skills', $page->user_id); $out = ""; $out .= "<h3 class='uk-h3'>Skills</h3>"; foreach ($skills['entries'] as $entry){ $out .= "<div class='uk-width-3-4'>" . $entry['skill_name'] . "</div><div class='uk-width-1-4'>" . $entry['skill_level']. "%</div>"; } return $out; } Where $this->formMultiple function queries the FormBuilder entries for records based on a user id saved (but not displayed) on the page. There are no errors in the dev console. Output from var_dump just prior to returning $out in the CustomFunctionsTBR FormBuilder entry: string(355) "<h3 class='uk-h3'>Skills</h3><div class='uk-width-3-4'>some other skill</div><div class='uk-width-1-4'>65%</div><div class='uk-width-3-4'>talking under water</div><div class='uk-width-1-4'>80%</div><div class='uk-width-3-4'>Yawning</div><div class='uk-width-1-4'>100%</div><div class='uk-width-3-4'>Balloon animals</div><div class='uk-width-1-4'>80%</div>" string(355) "<h3 class='uk-h3'>Skills</h3><div class='uk-width-3-4'>some other skill</div><div class='uk-width-1-4'>65%</div><div class='uk-width-3-4'>talking under water</div><div class='uk-width-1-4'>80%</div><div class='uk-width-3-4'>Yawning</div><div class='uk-width-1-4'>100%</div><div class='uk-width-3-4'>Balloon animals</div><div class='uk-width-1-4'>80%</div>" Seems to be rendering the output twice - have heard of this anomaly happening before, eg in certain repeater matrix situations...??? Or maybe it's late and I'm tired. Any/all suggestions to fix are welcome.
  24. @Chris Bennett thanks, a step in the right direction. Now can output direct HTML and it works fine but still problems when I try to construct the string from my function
×
×
  • Create New...