Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/19/2018 in all areas

  1. Some time ago I created a site profile for creation of a REST API with ProcessWire. Since I kept struggeling with updating stuff between different projects which use this, I decided to convert it into a module. It is now ready for testing: https://github.com/thomasaull/RestApi Additionally I added a few small features: automatic creation of JWT Secret at module install routes can be flagged as auth: false, which makes them publicly accessible even though JWT Auth is activated in module settings To check things out, download and install the module and check the folder /site/api for examples. If you find any bugs or can think of improvements, please let me know!
    7 points
  2. Just turn on "Show system templates" in the template list. Edit the template level field settings as usual: If you have the great Custom Inputfield Dependencies module by @Robin S installed, you can easily implement any sort of custom visibility (even by using PHP and the PW API).
    4 points
  3. I got it to work like this! https://jsfiddle.net/elabx/vysjwp01/
    4 points
  4. On the to-do list for the next version, is localisation of the input and output country names in the country select list (again thanks to @matjazp). To do this, I plan to release a module that I wrote for a different project back in 2014, but never got around to publishing: LibLocalisation. (It needs a little tidy-up first, as PW has progressed a long way since I first wrote it.) This module allows simple localisation of country names, language names and currencies. The Street Address module will leverage this, if it happens to be installed, to display the select list of countries in the language being used by the user's browser - and to localise the destination country name into the language(s) used in the origin country as this is the language that postal workers in the source country will be used to. There will be extra config options to control this. Following that, I plan to work on @thlinna's request to make this work with FormBuilder. Update:
    3 points
  5. @adrian, thanks for your help. The examples given weren't really helping because the file name wasn't kept. For each time de file was replace it would add "-1", "-2" etc. to the file name. I managed to make it work and I am posting the code, in case someone needs something like this. foreach($files as $file) { if(substr($file, 0, 1) != '.' && $file != '.' && $file != '..') { // Get SKU $file_sku = substr($file, 0, 9); // Check for book $book = $pages->get('sku=' . $file_sku); if(!$book->id) { // Book doesn't exist } else { // Check if image already exists $replace = false; foreach($book->book_images as $image){ // Replace image if($file == $image) { $book->book_images->delete($image); $book->save(); $book->book_images->add($upload_directory . '/' . $file); $book->save(); // Place image in the right position: after previous or as first if(isset($previous_image)) { $old_item = $book->book_images->get($previous_image); $new_item = $book->book_images->last(); $book->book_images->insertAfter($new_item, $old_item); } else { $old_item = $book->book_images->first(); $new_item = $book->book_images->last(); $book->book_images->insertBefore($new_item, $old_item); } $replace = true; } $previous_image = $image; } // Add image to book if(!$replace) { $book->book_images->add($upload_directory . '/' . $file); } // Save book $book->save(); // Delete processed file unlink($upload_directory . '/' . $file); } } }
    2 points
  6. @pwired - I could reproduce with Firefox on MacOS and I have pushed a fix in the latest version. Please let me know how it goes at your end. New version also removes the keyboard shortcut text from the top of the Console panel and adds a new toggleable popup info table of all shortcuts:
    2 points
  7. Welcome to the forums. ? The structure of the page tree (Page List) always reflects the path to pages on the front-end. That fact is part of the ProcessWire philosophy that Ryan has talked about somewhere (can't remember where exactly). So you can't have the Home page appear anywhere other than at the root of the page tree. In terms of having a dashboard instead of Page List there are several forum topics that are relevant. A Google search will find them: https://www.google.com/search?q=site:processwire.com+dashboard And here is another approach you can try... 1. Install the AdminOnSteroids module, and use the "Add pages to navigation" feature to add your Internal DB and Newsletter pages as custom nav items. This will add those pages to the Pages menu so that if you click them you'll see only those sections in Page List. 2. Add a hook to /site/ready.php (add the file if it doesn't exist) so that your Internal DB and Newsletter pages do not appear in the main Page List, so they are not confusing to your users. $wire->addHookAfter('Page::listable', function(HookEvent $event) { // Only for non-superusers if($this->user->isSuperuser()) return; // The ID of the page that Page List is listing children of $id = $this->input->get->int('id'); $page = $event->object; // Don't list pages with certain templates under Home (adjust template names as needed) if($id === 1 && ($page->template == 'internal_db' || $page->template == 'newsletter')) { $event->return = false; }; });
    2 points
  8. Great! Oh no! That's because it is matching the > in the prefix value in the snippet. So, I should change this: "prefix": "pages->find(\"selector\")" to this: "prefix": "pagesfind(\"selector\")" Thanks for catching this, but hey, you shouldn't be typing HTML closing tags! ? VSC extensions should do that for you. See Auto Close Tag. It can do this: Have a look at Auto Rename Tag as well (it acts up sometimes though). Regarding ProcessWire variables, first check out intelephense (as per previous discussions earlier today). If it works for you, then no need for my snippets :-). I've gone back to my snippets atm since intelephense is not working for me ?
    2 points
  9. HI @STA - welcome! There is this module: The other option is to use Tracy's File Editor panel to edit the files directly on the server - the Test mode can make this a pretty decent option.
    2 points
  10. One more shortcut ? CTRL + SHFT + ENTER will toggle the Console in and out of fullscreen. Totally random, but a little tip about the Console panel - not only is it great for testing the PW API and PHP in general, it's also pretty nice for testing JS code out. Take this example of: calling an external API populating an element in the Console results pane with a property from the returned JSON logging the result to the browser dev console Why use this over the browser console, or CodePen, JSFiddle etc? Well, notice that the API call is grabbing a PW field from the current page: 'https://represent.opennorth.ca/postcodes/<?=$page->postcode?>/' Also, if you are a fan of the output of the Browser dev console, don't forget about Tracy's fl() option to dump objects direct to this. Anyway, hope there is something useful there if you hadn't thought about it before ?
    2 points
  11. Hi @Sorina. I have no experience with Foundation, however it doesn't look like you are loading the CSS or JS files. Also with a quick scan, you have 2 divs with the same id, and an id should be unique.
    2 points
  12. Did any one tried to integrate "WordPress New Editor" into ProcessWire ?? I did some searches and I found this Repo on Github: https://github.com/front/drupal-gutenberg Which allows Drupal Users to use Gutenberg. Any Thoughts ?
    1 point
  13. A very simply library that quickly allows localisation of country, language and currency names into various locales. It's based on the data from Umpirsky's country-list project. I started writing this back in 2014 but have finally got around to publishing it. I hope this is of use to some of you. Usage Examples... To create a localisation for a particular locale, first create a new instance and define the locale... $de_DE = wire('modules')->get('LibLocalisation')->setLocale('de_DE'); You can now use your locale to get information about countries, currencies and languages as they are used in that locale. For example, to output the names of various countries you use the country() method, passing in an ISO 3166-1 2alpha country code... echo $de_DE->country('CH'); // Outputs "Schweiz" - the German for Switzerland. echo $de_DE->country('AU'); // Outputs "Australien" - the German for Australia. echo $de_DE->country('US'); // Outputs "Vereinigte Staaten" - ditto for the United States of America. You can create as many instances of the module as you need and set them all up for the same, or different, locales. To access currency data, you call the currency() method, passing in the 3-letter currency code you are interested in. echo $de_DE->currency('GBP'); This returns an array of data about GBP - localised in German... [ digits => 2, number => "826", symbol => "£", name => "Britisches Pfund Sterling" ] Finally, you can output localised language names by calling the language() method and giving it a 2 letter language code. echo $de_DE->language('fr'); // Outputs "Französisch" - the German for French. Getting the Module... You can view the project on Github or in the module repository.
    1 point
  14. this question can be also asked on stackoverflow, but I think supporting the local forum is much better ? I discovered the following issue while using PHPunit tests to cover some module methods: If I declare an array in the init() method of a module it's not accessible in another method called from the testcase. If I move the same array initialization to the __construct() method it's working as expected. I am not sure if this is an issue with PHPunit, PW or just a misunderstanding by me. Is there anyone out there who has some more expert knowledge about this? Thanks!
    1 point
  15. Thanks @bernhard! The API does not really care if it's served over http or https, it's just HTTP(s)-Requests after all. If your server is configured to redirect all http requests to https, it'll do so with these as well. However, it's always a bit of a hazzle to test locally, so I left the examples as is and put a note that it's a good idea to use https ? JWT Auth (in this case) works like the following: The client sends a login-request with username + password (this definitely should go over HTTPS) The server checks the login credentials and if correct, creates a unique token with an added encrypted signature The client uses this token to authentiate every following request Since the client does not know the secret, he cannot modify the contents of the token without making it invalid That's basically how I understood it ?
    1 point
  16. 1 point
  17. LAPS, I am also using the LoginRegister module along with Kongondo Blog module, and wanted to add Favorite functionality for blog posts and users. This related thread gave me a good start: https://processwire.com/talk/topic/18618-best-way-to-handle-saving-an-item-as-a-favorite/ Guessing there will be more users than posts (and the pages may be sorted by favorite count in the future), I decided on using a page field "blog_favs" with input "templates : user" attached to my template "post". And I decided the Add/Remove functionality would be URL query based. Here is the code that I implemented in /site/Modules/MarkupBlog/MarkupBlog.module /** * Render favs * * Used by renderPostHead(). * * @access private * @param PageArray $blog_favs is field in blog_post template. * @return string $out Markup of favs * */ private function renderFavs($page, $small = false) { $options = $this->options; $out = ""; // if page field not available, break if ( !$page->blog_favs ) { return $out; } // if post display is summary snippet skip full UI // if user logged in, use full UI and functionality if ( $small != true && $this->wire('user')->isLoggedin() ) { $uid = $this->wire('user')->id; // uid is int $favExists = 0; // check query string for Add/Remove function $queryCheck = $this->wire('sanitizer')->entities($this->wire('input')->queryString); $queryAddFav = "add_fav={$page->id}"; $queryRemoveFav = "remove_fav={$page->id}"; $doSaveFav = 0; // on AddFav request, assume we are going to save fav $doRemoveFav = 0; // on RemoveFav request, assume we are going to remove fav if ( $queryCheck ) { if ( $queryCheck == $queryAddFav ) { $doSaveFav = 1; } if ( $queryCheck == $queryRemoveFav ) { $doRemoveFav = 1; } } // only loop through blog_favs if there are entries // only loop once if ( count($page->blog_favs) > 0 ) { foreach( $page->blog_favs as $fav ) { $fav_int = (int)(string)$fav; // convert saved object to string then to int (!) if ( $fav_int == $uid ) { if ( $doRemoveFav == 1 ) { $page->of(false); $page->blog_favs->remove($fav); $page->save('blog_favs'); $out .= "<div>" . $options['post_removed_fav_text'] . "</div>"; } else { $favExists = 1; } break; } } } // if AddFav, only if user not already faved this post if ( $doSaveFav == 1 && $favExists == 0 ) { $page->of(false); $page->blog_favs->add($uid); // $uid is int $page->save('blog_favs'); $favExists = 1; $out .= "<div>" . $options['post_added_fav_text'] . "</div>"; } // show Add or Remove links for user if ( $favExists == 0 ) { $out .= "<div><a href='{$page->url}?{$queryAddFav}'>" . $options['post_add_fav_text'] . "</a></div>"; } else { $out .= "<div><a href='{$page->url}?{$queryRemoveFav}'>" . $options['post_remove_fav_text'] . "</a></div>"; } } // always display basic UI Favorites Counter (this is at end to capture add/remove changes) $out .= "<span class='favs'>" . $options['post_favs_text'] . " " . count($page->blog_favs) . "</span>"; return $out; } I make no claims on performance or code elegance, but if any of this is helpful to you, enjoy!!!
    1 point
  18. https://github.com/processwire/processwire/blob/dev/wire/config.php#L275
    1 point
  19. @Beluga i found that if you run into a problem with upgrading this, it works to uninstall the old one, and then install the new one; you can take a screenshot to remember your settings from old version
    1 point
  20. Facepalm! ?. I was testing in a workspace where wire folder was not part of the workspace!!! Thanks guys. It works. After further testing, I think I'll stick with my snippets though due to the following reasons: Intelephense requires that I type the -> i.e.. First, I type pages, then I type ->, then I select the property/method I want. Meaning, to get $pages->find('selector'), I need to type 3 times! And it doesn't give me the "" around the string 'selector'. Using the snippets, I only need to type once; e.g., pagesfind, hit tab and bam, I get the whole thing, $pages->find("selector"); With the snippets, I get the closing semicolon at the end of the statement. Not with intelephense With the snippets, I can use normal variable syntax; I don't use the Functions API ? Aah. This is because I had Auto Close Tag before support was included in VSC 1.16. Also, one has to enable it on editor.quickSuggestions > strings:true :-).
    1 point
  21. Thanks for all your input guys. I'll check out those modules. At least one of them seems to do the trick. Yup, but this seems to be local machine that sits in their office. It makes absolutely no sense to use this kind of thing to host a website nowadays for way too many reasons. They say they had an SFTP at some time and eventually decided to close it because there was an attack. To me that suggests "use a decent provider that keeps an eye on things and is actively 1 step ahead", but hey. I could give them 5 providers from the top of my head that would charge them less than 5€ a month and take all the pain away from hosting -_- That was my immediate reaction. What happens when down the line an issue is detected, something needs updating, or you ask for a change? E-mailing zips around and crossing fingers hoping everything works? Well, I do like the GIT option. Maybe I'll suggest that if everything else fails. I'm not really hopeful, because that's work on the tech's side and the guy doesn't want to even have FTP, the lazy f***.
    1 point
  22. Seriously?! ? OK... no FTP is actually a good idea, but "everything locked down and doing updates via zip" does not sound good to me ^^ I'd also go via SSH (if you are using Windows I can recommend WinSCP) or you could also use GIT to host your files and do a git pull on the server once you pushed an update (or even do that automatically with a webhook). Using GIT you'd also have version control for your project. Oh, and welcome to the forum ?
    1 point
  23. Hi, I uninstalled the previous version 4.11.32 and installed the latest version 4.11.34 I can confirm: now it is working in FireFox, Thanks, all good.
    1 point
  24. @NorbertH Out of curiosity, how long does your script take if you don't actually save the page? <?php namespace ProcessWire; include "index.php"; // Include PW include "berufe.php"; // Simple array with about 25000 Job names /* $berufe = array( array('id_beruf' => '1','berufsbezeichnung' => 'Aalbrutzüchter/in','kldb2010' => '11412'), array('id_beruf' => '2','berufsbezeichnung' => 'Aalfischer/in','kldb2010' => '11422'), array('id_beruf' => '3','berufsbezeichnung' => 'Aalräucherer/-räucherin','kldb2010' => '29242'), ... */ foreach ($berufe as $beruf){ echo $i++. " " .$beruf['kldb2010']." ".$beruf['berufsbezeichnung']."\n"; $p = new Page(); $p->template = 'berufsbezeichnung'; $p->parent = '/einstellungen/berufi/'; $p->title = $beruf['berufsbezeichnung']; $p->schluessel = $beruf['kldb2010']; //$p->save(); } ...and... <?php namespace ProcessWire; include "index.php"; // Include PW include "berufe.php"; // Simple array with about 25000 Job names try { $database->beginTransaction(); foreach ($berufe as $beruf){ echo $i++. " " .$beruf['kldb2010']." ".$beruf['berufsbezeichnung']."\n"; $p = new Page(); $p->template = 'berufsbezeichnung'; $p->parent = '/einstellungen/berufi/'; $p->title = $beruf['berufsbezeichnung']; $p->schluessel = $beruf['kldb2010']; //$p->save(); } $database->commit(); } catch(\Exception $e) { $database->rollBack(); } ...? Should give us a handle on the overhead of creating 25000 pages and setting the data on your test system.
    1 point
  25. Dedicated server hosting always comes with SSH access.
    1 point
  26. Hmm ok , did some testing . Testserver is a synology disk station whith 8 G ram. The import ccript is pretty simple : <?php namespace ProcessWire; include "index.php"; // Include PW include "berufe.php"; // Simple array with about 25000 Job names /* $berufe = array( array('id_beruf' => '1','berufsbezeichnung' => 'Aalbrutzüchter/in','kldb2010' => '11412'), array('id_beruf' => '2','berufsbezeichnung' => 'Aalfischer/in','kldb2010' => '11422'), array('id_beruf' => '3','berufsbezeichnung' => 'Aalräucherer/-räucherin','kldb2010' => '29242'), ... */ foreach ($berufe as $beruf){ echo $i++. " " .$beruf['kldb2010']." ".$beruf['berufsbezeichnung']."\n"; $p = new Page(); $p->template = 'berufsbezeichnung'; $p->parent = '/einstellungen/berufi/'; $p->title = $beruf['berufsbezeichnung']; $p->schluessel = $beruf['kldb2010']; $p->save(); } It took about 60 minutes to import using a PW installation whith Inno DB It took about 40 minutes using an installation whith MyIsam Now i changed the script to use transactions: <?php namespace ProcessWire; include "index.php"; // Include PW include "berufe.php"; // Simple array with about 25000 Job names try { $database->beginTransaction(); foreach ($berufe as $beruf){ echo $i++. " " .$beruf['kldb2010']." ".$beruf['berufsbezeichnung']."\n"; $p = new Page(); $p->template = 'berufsbezeichnung'; $p->parent = '/einstellungen/berufi/'; $p->title = $beruf['berufsbezeichnung']; $p->schluessel = $beruf['kldb2010']; $p->save(); } $database->commit(); } catch(\Exception $e) { $database->rollBack(); } On InnoDB using transactions the script finished in about 10 Minutes. It seemed like the actual DB operation that happened after creating the transaction only took a few seconds, as the almost script imediately ended after the last echo. Possibly transactions are worth a closer look, if we do massive data handling.
    1 point
  27. Not full translation. I'm working on it https://github.com/Razoriks/PW-LanguagePack-ru-RU
    1 point
  28. Thank you for your feedback @kongondo and insight. I think at this stage the solution in the short-term is to only allow superusers to create/edit/remove roles and enable just the user-admin and user-admin-all permissions for sitemanagers to allow them to be able to assign the roles pre-defined by superusers. It will also keep the administration simple for future supersusers. Thanks again to both of you for your assistance.
    1 point
  29. This basically does the same as kongondo's script, but has a nice GUI if you prefer. This is one the actions in the AdmimActions module.
    1 point
  30. Good find @interrobang. Thanks for posting. I like how this narrows it down because before I would get every method of every API variable possible, which worked just fine, but this makes it even simpler. A couple of questions that I wasn't able to figure out from the linked page, and thought you might know: 1. How to make this apply to $this->wire() in the same way? (i.e. The wire() method from the Wire class). I tried to do it like this, duplicating the same properties, but no luck: \Wire::wire('') => [ all the same properties here ] 2. Also trying to figure out how to make it recognize a wire() or $this>wire() call with no arguments returns an instance of class ProcessWire. Any ideas? I'm not sure I fully follow what the '' == '@' means, the doc page is a little unclear, or maybe it's time to refill my coffee.
    1 point
  31. Hello fellow PW-ers! First post here, but I'm actually a relatively long time user. Today I finally came up with an issue that justifies asking for help. Does anyone know of a way to manage the templates directory from the admin interface? Something along the lines of the database backups module, that would allow me to upload a zip file and dump it over the files of the templates directory. I'm now facing a client that uses a dedicated server, has everything locked down, and has no FTP. They've setup PW for me, but now the only way for me to update the site is by sending them a zip that they then extract in the server. Imagine trying to fix problems and touching up markup like this. It's Hoover level of suck. Thanks for your time and help.
    0 points
×
×
  • Create New...