Leaderboard
Popular Content
Showing content with the highest reputation on 07/12/2019 in all areas
-
I've been in Minnesota all week for a family reunion and only a few minutes at the computer every day, so I don't have a core update or anything worthwhile to write about this week. But now I'm headed back home so will be back to a regular schedule next week. Hope that you have a great weekend!7 points
-
I'm close to releasing my new module called RockMarkup which will be similar to @kongondo's and @kixe's markup modules. The module is already on github and ready to play with: https://github.com/BernhardBaumrock/RockMarkup Unfortunately I have a bug that I can't seem to find. When a field is placed in a template and visibility is set to "closed + AJAX load" the field does not work at all: Would be great to get some help with this one! URL for installation of the module: https://github.com/BernhardBaumrock/RockMarkup/archive/master.zip3 points
-
Just submitted a pull-request. I figured out that if the output is wrapped into a div it‘s getting loaded properly. Please don‘t ask why ? /edit: Thanks for sharing your module!3 points
-
Use wire('all') Example from our production code: $factory = $modules->get('TemplateEngineFactory'); echo $factory->render('chunks/bodyCta.tpl', array_merge( (array) wire('all'), (array) [ "title" => $title, "text" => $text, "href" => $href ] ));3 points
-
Hey @horst, @3fingers, I'm very sorry for the late response. I finally found some time to look into this. - @horst at the beginning, you mentioned a 401 error. I think this could be caused by a wrong audience id. But seems like this was no problem later? - Regarding 404: you get a 404 for every new user, because the "getStatus" method simply can't find a status for that user. This is absolutely correct behaviour and the check itself is suggested by the API documentation. I guess it is not a good idea to log this as a warning, as it is part of the normal process. I removed that. - @3fingers do you have double opt-in enabled or disabled? there was an extra 'if' on line 55 that has caused problems with resubscription when double opt-in was disabled. This should be fixed in 0.0.5. Thanks to jliebermann for posting this issue on github. (Note, that after a 'resubscribe', the user has to confirm his email adress again and will disappear in your "contacts" list until he does that!) - @3fingers your solution with updating line 54 can not really work, because the $status you are checking is not the HTTP_STATUS. It is supposed to be the subscription status, and it will be false, when you (correctly) get a 404 during the API call. So there should never be a 404 in $status ?. Besides that, I changed the wording in the readme and comments from 'list' to 'audience', since this is the new wording by Mailchimp. Version 0.0.5 is live in a minute. Appreciate your feedback. Thanks a lot for posting your issues and for your patience! Trying to answer you faster next time. Let me know if you still have problems.3 points
-
Hi @neonwired, guest and superuser are default roles. Documentation says: "The guest role is automatically given to all anonymous site users. You should not give this role any access other than page-view permission." You can find further details here. If you wish to assign specific permissions you can easily create custom roles. Just as an example for a blog website, you may create visitor, author, editor roles and assign them their specific permissions.2 points
-
Hi @Torsten Baldes, you could try the following: wire('user')->setTrackChanges(Wire::trackChangesOn | Wire::trackChangesValues); wire()->addHookAfter('Pages::save', function($event) { // >>> ON PAGE SAVE $page = $event->arguments(0); if($page->template->name === 'user') { // >>> APPLY ONLY TO USER TEMPLATE $changes = user()->getChanges(true); // output changes as log entry wire('log')->save('testchangelog', print_r($changes, true) ); $m = new WireMail(); $m->from('Your email From'); $m->to('Your email To'); $m->subject('Your email subject'); $m->body('Your email text'); $m->send(); } }); Note: made a couple of corrections and changed to WireMail as per @horst suggestion. Still testing if changes are recorded...2 points
-
@bernhard if you are using ProcessWire 3 and if useFunctionsApi enabled you can call all api functions in rendered files directly.2 points
-
TLDR: Buy ProFields I don't understand why that brief list of fields is a "mess and a nightmare". I know the general advice given is to reuse fields where possible but I think people sometimes take this suggestion a bit too seriously. Create the fields you need and forget stressing about whether you have perfectly optimised the reuse of fields. If you have less than, say, 100 fields in your site you really have nothing to worry about. I think I saw a post recently where Lost Kobrakai was talking about a site of his with over 800 fields. But ProFields... You mention client editing experience, so I take that to mean you (like me) earn an income from developing websites. With that in mind here are some things to consider when making your decision whether or not to purchase ProFields... Have you thought about how lucky we developers are that we can earn an income with virtually no overhead costs? With so much fantastic open-source software made available to us at no cost we are in a very fortunate position. We could design and develop websites entirely with free software if we so choose. Hell, if we wanted we could go to the landfill and probably pick up a free old computer that would be perfectly adequate to develop a website on. Now think about the carpenters and dentists and all those other professions that must purchase real physical tools (that wear out) in order to earn a living. £100 doesn't go very far if you need to buy a table saw. On the topic of open-source, think about what Mr Ryan Cramer has provided us with in ProcessWire. People with his level of skill do not need to be contributing their time for free to open-source projects - they are in very high demand for all kinds of lucrative work. Purchasing a Pro module from Ryan is a way to show appreciation for the generous work he puts into PW. PW is not just great free software, it is great software full-stop. You mention previously having worked with Drupal and Craft CMS. Time is money, so think of all the money you have saved by the quick development workflow that PW allows vs Drupal. And Craft CMS costs USD$299 per website and is still not as powerful as the PW core. Ryan's Pro modules are insanely good value for money. The price that you can purchase a dev license that allows you unlimited use of the modules is more than reasonable. For comparison, here is one of the most popular addons for Concrete5: http://www.concrete5.org/marketplace/addons/block-designer-pro There is no unlimited license, and a license for 5 installations costs USD$276.25. And it requires "Block Designer" so that's another USD$120 for 5 installations, bringing the cost to USD$396.25. I haven't used it but it looks like it is basically the equivalent of Repeater Matrix. But probably not as elegant. And with ProFields you get another four modules bundled in. For unlimited use. For USD$129. Hope this has helped make the decision a little easier.2 points
-
@Jim Bailie You'll find plenty of examples in the dedicated pro forum threads, once you buy it. And people are happy to share their own code-snippets / advices in those forums. "site sample": not sure if you think of it as a special installable site-profile. If so, then I would guess no.1 point
-
I guess I would try option 3, but of course some more information about these "tasks" and "tools" would be needed. Maybe I'd use JSON storage only for settings. This module would perhaps be useful.1 point
-
Hi, I enabled hsts in the new .htaccess file in latest version of PW (as described here https://processwire.com/blog/posts/pw-3.0.135/#step-4-decide-whether-to-to-enable-hsts-section-9f) Everything seemed okay but realised my subdomains had gone offline ('This site can’t be reached') and now both our main business website has gone offline and our emails (done through Google Apps) have stopped working). Could hsts be responsible for all this? I removed the new .htaccess and now have the old one, I also tried resetting Chrome to remove the hsts domains but nothing works. Funnily I can't access our hosting now (Digital Ocean) because I have no access to my email. Please can any help shine a light on this? Can hsts be this dangerous?!1 point
-
@alexcapes It might turn out to be instructional if you could let us know what went wrong with the transfer and how you (eventually) get it sorted out. Regardless, I do hope this is fixed for you soon.1 point
-
Ok so I think my panic on hsts was a little misguided. What seems to be the issue was transferring DNS records over to a new hosting company which has not happened seamlessly. ?1 point
-
Short answer: RockFinder + RockGrid are exactly built for such tasks and RockTabulator is currently under development. You can PM me if you want to talk about possible collaboration/sponsoring/consulting.1 point
-
@OllieMackJames Just yesterday I was reviewing the amember.com website, I see it's a hosting solution to install on my server. Anyway this would be for the administration of accesses, permissions and payments (which is very interesting and I will try it for sure) but my problem now is how to save all the information of the tools (which is a lot) for each user to use internally in PW for calculations, analysis, etc. Thank you very much for your answer1 point
-
Hi @Edison, if this shows the old and the new values inlog and mail, this is really good! (Will test this later when back in buero). Only thing that should be changed is the use of (PHP) @mail function. Instead you should use wireMail(). :)1 point
-
require './vendor/autoload.php'; this did the trick, when I desperately changed the folder name. Thanks for you help!1 point
-
Is the favicon referenced in your HTML like <link rel="shortcut icon" href="/path/to/favicon.png" type="image/png"> or is it the last thing the browser does by looking in its default place?1 point
-
Hi @Torsten Baldes, I am also not really a pro, but maybe it can help nevertheless. Did you already try to hook after Pages::saved and filter to only run for user template? This way the hook runs only if the user page is saved and you can get all changed fields.1 point
-
Hi @adrian, thank you very much for your fast reply and fix. It works. I just tested it with few entries. You are a life saver!1 point
-
You don't need to include_once() if the vendor folder is in the ProcessWire installation root, it has loaded the libraries already, if i remember correctly the index.php of PW takes care of this. I am also almost sure you also have to have the use statement like @Edison points in the examples.1 point
-
Hi @iipa , I think so... ? Here is an example taken from PhpSpreadsheet documentation: <?php require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', 'Hello World !'); $writer = new Xlsx($spreadsheet); $writer->save('hello world.xlsx'); Php "use" directive provide you an alias for the namespace, so thanks to that in the above example you can simply instantiate this class's library as: $spreadsheet = new Spreadsheet(); Alternatively you could call the class with the fully qualified class name which includes both namespace and class: $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); Of course if you have several calls... the "use" directive avoids to keep repeating the fully qualified name each time. ? Without informing PHP about the namespace of your class or function, it will search for it inside Processwire namespace where not finding it will return an error. ?1 point
-
Could be a simple issue with the paths. When site/config.php is loaded, the working directory should be site root, so you may be going way below the level you actually intended. You could try __DIR__ . '/../../libraries/vendor/autoload.php' instead, or just './libraries/vendor/autoload.php' (in case your libraries directory is in your site root – or ../ if it's below it).1 point
-
When a blog post article receives many comments ? your start to consider to apply pagination to comments. Looking around this forum, I found some useful hints, but I couldn't find how to take full advantage of PW built-in pagination. In particular the ukBlogPosts() function in Uikit 3 Site/Blog Profile renders a list of paginated posts. ukBlogPosts() is calling a ukPagination() function which permits to navigate the posts. ? After some unsuccessful attempts to use it with CommentArray … ? I decided to insist. ? And here is the result. The ukPagination() function in _uikit.php expects an argument $items of type PageArray. Of course a CommentArray ... is not a PageArray ... ? so we have to remove this blocking point. Going deeper inside the function you will notice that pagination is achieved through a call to a render() method of MarkupPagerNav. Let's look at its declaration: public function ___render(WirePaginatable $items, $options = array()) Interesting ? here $items are declared of type WirePaginatable. What's that? ? a class? No! It's an interface! ? Looking around further I discovered that WirePaginatable interface is used by PageArray, PaginatedArray, and CommentArray.. bingo! ?? We got what to do first, modify ukPagination() function in _uikit.php changing $items argument type from PageArray to WirePaginatable: //function ukPagination(PageArray $items, $options = array()) { function ukPagination(WirePaginatable $items, $options = array()) { //>>>>> REPLACE WITH THIS LINE Now the function accepts our CommentArray as argument, but to make it work we need to set its Limit, Start, and Total attributes as PW does automatically when dealing with pages. In order to do that we will use the WirePaginatable methods setLimit(), setStart(), setTotal(). In this process our Start attribute will have to be calculated dynamically to consider the page number when navigating the comments. To do that we will largely ? modify the function ukComments() in _uikit.php: function ukComments(CommentArray $comments, $options = array()) { if(!$comments->count) { //>>>>>NEW-start if(input()->pageNum > 1) { // redirect to first pagination if accessed at an out-of-bounds pagination session()->redirect(page()->url); } return ''; } //>>>>>NEW-end $defaults = array( 'id' => 'comments', 'paginate' => false, //>>>>>NEW 'limit' => 3, //>>>>>NEW ); //if(!count($comments)) return ''; $options = _ukMergeOptions($defaults, $options); $language = user()->language->id; //>>>>>NEW $comments = $comments->find("language=$language"); //>>>>>NEW if($options['paginate']) { //>>>>>NEW-start $limit = $options['limit']; $start = (wire()->input->pageNum - 1) * $limit; $total = $comments->count(); $comments = $comments->slice($start, $limit); $comments->setLimit($limit); $comments->setStart($start); $comments->setTotal($total); } //>>>>>NEW-end $out = "<ul id='$options[id]' class='uk-comment-list'>"; foreach($comments as $comment) { $out .= "<li class='uk-margin'>" . ukComment($comment) . "</li>"; } $out .= "</ul>"; if($options['paginate'] && $comments->getTotal() > $comments->count()) { //>>>>>NEW-start $out .= ukPagination($comments); } //>>>>>NEW-end return $out; } As you will notice we have added two options to the function [paginate => false] and [limit => 3]. In such a way the ukComments() function will operate as before. If you wish to use pagination you will have to pass [paginate => true] as argument of the function. Of course you can freely choose the limit value or by pre-setting it in the function or by passing it as an argument to the function. Please note that the modification implements the necessary changes (2 lines) to make comments language-aware as described in the tutorial: We are now just to steps away to see our paginated comments. ? First you will need to enable pagination in the templates where you want comments to be paginated. Login to PW Admin and select your template. In the tab URLs enable the "Allow Page Numbers?" option. Second you will need to modify the associated php template, in our example blog-post.php, to change the call to ukComments() as follows (sorting is not necessary, depends on your preferences): //echo ukComments($comments); echo ukComments($comments->find("sort=-created"), ['paginate' => true]); //>>>>> REPLACE WITH THIS LINE And here we are! Below a snapshot our paginated comments! ??? As you can see on the bottom of the comments you have the standard PW pagination navigator, without being forced to rewrite a new one for the purpose! ? I hope you can find something useful with this tutorial.1 point
-
@iipa You need to use the correct namespace by either aliasing the class with the use statement, or by using a fully qualified class name. As others have said though, it's much easier to use Composer with it's autoloader, since you only need to include it once and all classes will be autoloaded. It's also better for performance, as only the classes you actually use get loaded for each request. If you need help setting up Composer and the autoloader, check out my tutorial on Composer + ProcessWire ?1 point
-
Processwire API and minimalism is so much lean that it feels like you are still writing PHP compared to other CMS which are overly complex, I think Processwire is easy to use Project with so many things taken care of, especially the fields, It's so much easier to build applications for client easily than other frameworks/cms because Processwire provides so many features that are vital.1 point
-
With ProcessWire you don't generally want to perform your own SQL queries. It's possible, but generally I'd consider that a bad practice. If your content is stored as ProcessWire objects (basically Pages), you should always use the Selector engine for that sort of stuff. Not only does this provide the benefits of a great API (such as $pages->find('template=mailbox, owner=[some_user_field=whatever_value]') or $pages->get('parent=some-parent, name=page-name')->setAndSave('field', 'value')), there's also zero chance of accidentally running into nasty SQL injection vulnerabilities. Of course you can always create custom database tables and perform queries on them using the $database API variable (which is essentially a wrapper for PHP's own PDO class), but in such cases the content won't be editable within ProcessWire's admin, so you're missing a pretty important benefit there. Another alternative would be using RockFinder, which kind of provides the best of both worlds: easy to use syntax for queries combined with the performance of raw SQL and lightweight PHP arrays/objects. So, long story short: if you want a nice GUI and an easy-to-use API for managing your content, ProcessWire is a great choice. If you ultimately just want to use your custom database tables, write a few SQL clauses to update a few rows here and there, and there's no need for a web based interface for managing said items – then perhaps you should just build it from scratch (or use something like Laravel instead).1 point
-
Hi Guys, In short: I would like to base the template and parent of the imported pages to be based on values in the csv Great work on the module Ryan, it's a very useful extension to Processwire indeed! ? I was wondering if it would be possible to set multiple templates for the pages that are created, maybe based on a .csv field value? I'm using Padloper for variation products which ends up looking like this: - Parent Product Page ( needs productprarent template ) - Variation child page ( needs variation template ) - Variation child page - Variation child page so In my cvs file I guess I would use something like this? Type template title color price image Parent productparent T-Shirt 5 Child variation T-Shirt Blue templates/img/blue.jpg Child variation T-Shirt Red templates/img/red.jpg Child variation T-Shirt Green templates/img/green.jpg This way I could create a parent of all sets of children, if values aren't filled there the system uses the price of the parent. I was thinking of something in de lines of: if($CsvLine->type == "Child") { $page->parent = $parent($CsvLine->title); } if takes makes any sense :') Do you think something like this could be done? Thanks in advance! ? Bram1 point
-
protected function defineOptions() { return array( array( 'name' => 'csv_upload', 'label' => 'CSV upload', 'description' => 'Upload a CSV file.', 'type' => 'file', 'extensions' => 'csv txt', 'overwrite' => true, 'maxFiles' => 1, 'required' => true, ) ); } protected function executeAction($options) { // If there was a file uploaded (Pagefiles object) if(count($options['csv_upload'])) { // Get the file (Pagefile object) $file = $options['csv_upload']->first(); // Parse the CSV data $handle = fopen($file->filename, 'r'); $count = 0; while(($row = fgetcsv($handle)) !== false) { $count++; // Process each $row // ... } fclose($handle); // Delete the uploaded CSV file (or else you will get an error next time you upload) unlink($file->filename); $this->successMessage = "$count CSV rows were processed."; return true; } else { $this->failureMessage = 'Please upload a CSV file'; return false; } }1 point
-
Getting just the folder means $file is actually not a file (Pagefile), but a Pagefiles object. File fields are internally always handled as list of files, so you might need to use the following or alike: $file = $upload->file->first();1 point
-
Do you do design websites as well as develop them? If you do then my experience has been that there is plenty of work available from businesses and organisations who care about and understand the benefits of high-quality bespoke design and development. Yes, there are many out there who think that a $40 Wordpress theme is good enough and don't want to pay above the minimum - if job satisfaction is important to you, you don't want those people as clients. You'll hate the client, hate the finished website, and end up hating your job. You say you also work in the charity sector - I think that is a good sector to target as a specialisation and maybe you can make use of your contacts there to get started. Most of my clients are not-for-profits, mainly environmental organisations. I have found them to be excellent organisations to work with - friendly, sensible people, happy to take advice and willing to let you get on and do your work without a lot of interference. Another benefit is that these organisations often fund their projects from grants. This makes them less price-sensitive. To be clear, I'm not talking about gouging them on price - just that you can quote a fair price and they base their funding application on that and there's no grizzling and bargaining over cost like you can get in the for-profit sector. I live/work in the middle-of-nowhere rural New Zealand, I have never advertised or done any kind of promotion, and have been fortunate enough to always have a steady stream of work. And believe it or not, in the ten years I have been doing web work I have never had a client request a Wordpress site. I think positive word-of-mouth is key, and the great thing about it is that good people tend to know other good people so you generally avoid those Clients From Hell. To get good word of mouth you need to exceed expectations - set yourself high standards, have meticulous attention to detail, and deliver that bit extra. Best of luck with your career!1 point
-
I just needed to fiddle around some more to find my answer. $image_fields = $fields->find("type=FieldtypeImage"); Looking at the data for a field I guess you can also find fields by id, flags, name and label. Nice!1 point