All Activity

This stream auto-updates   

  1. Today
  2. This topic has some useful links on building custom button/command
  3. How can this be done? I'd like to add some custom buttons instead of adding to the Styles dropdown. I'm asking because Processwire controls this for each editor field individually through the CKEditor settings for each textarea field.
  4. Hi, Similar discussion with some tips and pointers:
  5. Huh, turns out there's this method inside ProcessPageView class <?php // /wire/core/ProcessPageView.php /** * Hook called when the pageview failed to finish due to an exception. * * Sends a copy of the exception that occurred. * */ public function ___failed(\Exception $e) { $this->wire()->setStatus(ProcessWire::statusFailed); } which I should be able to hook and access the exception and message with <?php wire()->addHookBefore('ProcessPageView::failed', function(HookEvent $e) { $ex = $e->arguments(0); $message = $ex->getMessage(); }) But, it's not firing when hooked inside /site/ready.php. In fact it does not appear to be used anywhere inside the core at all.
  6. When I take a look in a PW database I see this: pages are stored in “pages", templates are stored in “templates", sessions are stored in “sessions", forms are stored in "forms” (form builder), ... I want to make a website with a large catalog (1.5 million products). I don’t want that the products are stored in “pages” table in the database, but in the “products” table. Is this possible in PW? End will I maintain the same options, then when I store all products in “pages”? Some advice would be helpful! Kind Regards, Peejay
  7. While coding some templates I need to throw some Wire404Exceptions, which, expectedly, sets correct headers and renders 404 page. Since all these exceptions are extending Exception class, I can call its constructor with a message like this <?php $demoName = sanitizer()->pageName(input()->urlSegment1); $demo = pages('template=demo, name=$sanitizedPagenameFrom'); if(!$demo->id) { throw new Wire404Exception("Demo named $demoName cannot be found, but check out its source page instead"); } // inside template 404.php // somehow get the error $message echo "<h1>Page does not exist</h1>" echo "<p>$message</p>" What I want to do is to somehow catch this exception, or get inside 404 template the message that I set earlier in some module or another function, so that I can notify the user with a better message than "Error 404: Page not found". There's some parts inside core that handles this sort of things but they're not utilized. <?php // inside /wire/core/ProcessPageView.php public function ___execute($internal = true) { // ... try { // try to render the page } catch(Wire404Exception $e) { return $this->pageNotFound($page, $this->requestURL, false, '404 thrown during render'); } // ... } protected function ___pageNotFound($page, $url, $triggerReady = false, $reason = '') { // reason is not used, or passed to 404 template } So, is there a way to manually catch the exception thrown? For instance, with Silex all exceptions can be intercepted using <?php $app = new Silex\Application(); $app->error(function (\Exception $e, $code) { exit('asd'); });
  8. My module ( mentioned above still works fine in PW 3 if that's helpful for you.
  9. You are correct that process modules should be restricted to back-end use. It was my mistake for using that example and applying it to front-end use. I am not writing any process modules, though. I believe I have enough to continue converting my olden-days code to use in ProcessWire. I understand your URL segment example, too. I'm sure I will make use of it soon. Thank you for your help.
  10. Process modules (ones that extend Process class) can have execute[Action] methods that are called with their respective urlSegments. In case of your example, the method comments portrait the exact conditions where ___executeFields is executed with /fields urlSegment, for instance. The problem with this approach is that you cannot (or should not) use them on frontend, as Process modules are intended for backend use (unless I'm mistaken). However, calling the method depending on urlSegment is quite simple with the snippet I posted earlier. You can use something similar to following to call execute[Action] methods <?php public function ready() { // accept only single urlSegment if($this->input->urlSegment2) throw new Wire404Error(); // always sanitize user input $method = $this->sanitizer->alpha($this->input->urlSegment1); if(!$method) return; // or perform more sophisticated checks // respond to execute[Action] methods // such as executeList() with /list urlSegment // or executeFields() for /fields urlSegment // create camelCase method name // /json urlSegment will be intercepted by executeJson() function $method = "execute" . ucfirst($method); if (method_exists($this, $method)) { $this->{$method}($param1, $param2); } else { // method does not exist throw new Wire404Exception(); } } public function executeJson() { echo json_encode(['a' => 1, 'b' => 2]); } Put this inside your init() or ready() method in your module to relay the request to specific functions.
  11. Hi @abdus, @horst Thanks for your replies. abdus, If I understand you correctly, ProcessWire has it's own set of "magic functions" relating to module classes similar to how it automatically handles template files, such as <code>init.php</code> and <code>ready.php</code>, where init() and ready() are automatically executed within a module if present. In Ryan's module, ImportPagesCSV, it appears that module functions are automatically executed based on URL segments (which are not defined in a template): Maybe I am making things far more complicated than they really are, which is highly likely, but this is the basis of my confusion. Information like what you both have posted needs to be documented somewhere so it's easy to find. Thank you both for your replies.
  12. @rick: In your code that handles the form input, you simply can call the module or public module method: //if(<condition for form was posted>) { $myModule = $modules->get("MyModulesName"); // get a module handle $myModule->passNewDataIn($input->post->someData); // call the public method for data input // rest is done in modules method, ... // if you are not in template scope, you can use $myModule = wire("modules")->get("MyModulesName"); //}
  13. I have found my better checkerbox background image again: in use as BG it looks like this:
  14. How are you using it? Is it like this one?
  15. this is wonderful news, thank you. here are the official docs
  16. You can use this hook to remove Settings tab from page edit pages <?php wire()->addHook('ProcessPageEdit::buildFormSettings', function (HookEvent $e) { // get the page currently being edited $page = $e->object->getPage(); // check its template if($page->template->name !== 'some-template') return; // remove settings tab $e->object->removeTab('ProcessPageEditSettings') })
  17. Ok, I got it working with the initial query: $result = $pages->find("template=recipes-inner, sort=-recipe_views_counter, limit=4"); The issue was caused by the fact that I selected the recipe_views_counter to be Integer, but in Numeric Input Type I had Text by default. Changing it to Number (HTML5) did the trick. One less thing to worry about
  18. Just added a new 'getembedurl', 'append' and 'prepend' filters to v4.4. With getembedurl you can retrieve the embed url to be used when embedding videos (currently for Youtube/Vimeo). Editors aren't really capable of copying the embed url so you can use this filter to allow them adding the url of the video to the admin. Filters append and prepend are convenience filters that you can use to quickly append/remove data. Data can be primitive or arrays. These filters are particularly useful when chaining filters so you don't have to split the current line just to modify the original data. The bodyclass filter now contains the name of the viewFile (if exists), prefixed with "v-", and directory separators converted to "-". Custom classes can be added using $page->body_class if needed.
  19. I am not sure you can access Process modules (pages with admin template) as a guest. If you need to know what page the request is sent to, and perform operations depending on the page, or need some functionality from other autoload modules, then you'd do your checks under ready() function. If you don't, then both init() and ready() is fine. To intercept the requests, you can create a new template called api in your install() function (and remove in uninstall() function), then set it to accept urlSegments (as many as you want), then create a page with that template under root page, then inside your module check if request is made to that page and to that specific urlSegment. Optionally return 404 for all other urlSegments you're not interested in like this <?php $method = $this->sanitizer->alpha($this->input->urlSegment1); if(!$method) return; if (method_exists($this, $method)) { $this->{$method}($param1, $param2); } else { // method does not exist throw new Wire404Exception(); } You can build such a module like this <form action="/api/sendmail"> ... </form> <?php namespace ProcessWire; class MyModule extends Wire implements Module { public static function getModuleInfo () { return [ // ... 'autoload' => true // ... ] } public function ready() { if ($this->wire()->input->requestMethod() === 'POST') { // perform other checks if($this->input->url !== '/api/sendmail') return; // this is the request we should be intercepting $data = $this->wire()->input->post; $name = $this->sanitizer->text($data->name); $email = $this->sanitizer->email($data->name); if($this->sendMail($name, $email)) { // email sent successfully } else { // email failed } } } public function sendMail($name, $email) { $mailer = $this->wire()->mail; // check if any mail is sent successfully return 0 < $mailer->send( '', // to address '', // from address 'Test post, please ignore', // subject 'Hey there, this is a test mail' ); } }
  20. Tried again this morning using get instead find: $result = $pages->get("/recipes/")->child("sort=recipe_views_counter, limit=4"); The result was 26 recipes instead of the 4 limitted and I am not aware where it got 26 from as it is not the number of all available ones and is not even the views number. What am I missing here? As far as I removed the sort it works just fine: $result = $pages->find("template=recipes-inner, sort=-modified, limit=4"); So it seems like I am unable to sort by the recipe_views_counter only. Could that be because of the field being an Integer?
  21. Hello all, I am confused about how a specific module method is invoked by a form rendered on the front-end and then submitted. My confusion, or rather ignorance, stems from not finding any references describing how I (or ProcessWire) determine whether an action is adding or editing a set of data. I've gotten myself surrounded by so many trees at the moment from reading blog articles and forum entries, and dissecting existing modules. I've seen <code>___execute</code> method based on url, <code>___action</code> used with suffixed name, and others with no discernible means. I can create and install a skeletal module, create and edit the module config, retrieve data from page(s), and render a form on the front-end, all without issues. But so far I am unable to get a submitted form to invoke a particular class method for saving a new data set, editing an existing data set, etc. What is the proper, ProcessWire efficient, way to have a submitted front-end form call the appropriate module method?
  22. Do any experts have experience with the level of stability and/or support for turning on $config->advanced? I ask because of the warning at the bottom of the System tab "Please note that all of these system settings are intended for ProcessWire system development (not site development). Use them at your own risk." It provides two facilities that are invaluable to me (maybe because I don't know how to do them any other way). 1) Disable Settings Tab on a per template basis 2) Page Class Name - this makes it tweak a page while relying on the underlying Page class for the majority of functions. Are others using this setting in production? Have you used it over an extended time and seen that it is not changed often or at all?
  23. I'm working in version 3 and can't remove the settings tab using your example. Maybe something new has changed? But $config->advanced = true; works perfectly and is a better solution as it's already per-template.
  24. Woohoo! Thanks. $config->advanced = true; does the trick!
  1. Load more activity