Leaderboard
Popular Content
Showing content with the highest reputation on 10/27/2016 in all areas
-
v091 brings useful updates to the AdminDataTable filters like counter, invert search using "!" and some badass CSS styling, plus many improvements under the hood. The new submodule ListerTweaks is also included, which now respects the Lister bookmarks too. There was an important fix to ctrl+s feature of Hotkeys - if the Source dialog of a CKEditor is opened then ctrl+s won't save the underlying page but trigger the OK button in the dialog.4 points
-
You would need to set script path by $script.path(), e.g $script.path('/site/templates/js/') https://github.com/ded/script.js/#scriptpath3 points
-
Hey guys, Just launched a new project called Fabricius: fabriciusstrasse31.de Fabricius is a new building thats being built in Hamburg (Germany), that offers modern living comfort in a green environment. I developed the whole brand strategy and visual identity for the website and some printing materials. The logo mark is derived from the silhouette of the building, which is surrounded by trees (circular shapes) and green areas. More details here The website is build with PW 3.0 and uses Modules like Map Marker, Pages2PDF (to generate the apartment exposes) and MarkupSrcSet. Thanks for the awesome support here and the development of PW and the modules!!3 points
-
For everyone interested: CodeKit 3 is out now. I know, that everything CodeKit does, can be achieved using an IDE, Grunt, Gulp, CLIs and so on. But CodeKit provides a good starting point for beginners, in my opinion. Regards, Andreas2 points
-
@szabesz ah, good point! Yes I did indeed add a new custom rewrite rule recently. It took me a while to figure out but that was indeed the issue. Thanks for pointing me in the right direction!2 points
-
If you avoid using find()/get() in loops you're quite save against n+1 queries. If you don't, then there's not much ProcessWire can do against it besides caching already retrieved items.2 points
-
Looks like I have made the following patch locally: - if ($page->isChanged('status') && $page->is(Page::statusUnpublished) && $page->publish_from) { + if (!$page->isNew() && $page->isChanged('status') && $page->is(Page::statusUnpublished) && $page->publish_from) { Possibly related2 points
-
The two sql_mode settings incompatible with ProcessWire should be ONLY_FULL_GROUP_BY and STRICT_TRANS_TABLES. The dev version (>= 3.0.37) removes those by default for MySQL versions >= 5.7.0. It might make sense to file a request to run that logic for all MySQL versions that support these settings. Also, for *= and ~= to work, the search string needs to be 4 characters or longer. See the selector operator documentation (especially the two paragraphs before the "Negative Operators" heading) for details.2 points
-
2 points
-
@Michael van Laar, you could use a hook to set the value of the Page field after a new article page is added. In /site/ready.php: $this->pages->addHookAfter('added', function($event) { $page = $event->arguments('page'); if($page->template->name != 'article') return; // your logic here to find the right author ID $page->setAndSave('author', $my_author_id); });2 points
-
Hello @mstroeck and welcome to the forums! What sort of server setup are you using? Any chance that you have custom rewrite rules? Any more detail that can shed more light on the issue?2 points
-
Hi, Trust this message finds you hale and hearty. Need your help, if you'd be so kind. I just can't seem to get the file paths correct for a template I'm converting to Processwire. Js folder is inside the site -> templates folder: In this folder are calls to js files, in my _head.inc and _foot.inc files: In the _head.inc file: jquery.js jquery-migrate-1.2.1.js device.min.js In the _foot.inc file: script.js Here's the code I use to call these files: _head.inc <script src="<?php echo $config->urls->templates; ?>js/jquery.js"></script> <script src="<?php echo $config->urls->templates; ?>js/jquery-migrate-1.2.1.js"></script> <script src='<?php echo $config->urls->templates; ?>js/device.min.js'></script> _foot.inc <script src="<?php echo $config->urls->templates?>js/script.js"></script> Inside the script.js file, there are a bunch of includes, like the following: include('js/jquery.cookie.js'); I'm on Chrome, and the console shows a bunch of 404 errors. The main files don't find the files referenced in script.js. Here's an example: http://localhost/surfinn.rocks/js/jquery.cookie.js http://localhost/surfinn.rocks/js/jquery.cookie.js That shows an error. The HTML demo of the site I installed on my Wamp works fine. No errors. Not the case when loaded in Processwire. Any idea what I'm missing? Thanks so much for your time.1 point
-
Another alternative would be using what you (probably) already have: it's more than likely that you've got logging enabled for Apache, and the Apache log file will no doubt include the URL of each viewed page. See where I'm going with this? The benefit of this approach would be that you reap all the benefits of ProCache: the bulk of the requests are served static files, and PHP or MySQL (or Redis or whatever) won't need to be triggered at all. The obvious downside is that parsing the logs requires a bit more work than simply fetching the data from a table.1 point
-
@teppo thanks a lot !!!!!!!! - that fixed the problem! @formmailer Can this feature be included in the module maybe? (easier to maintain)1 point
-
Wow, thanks @Robin S. That’s exactly what I was searching for. I haven’t learned much about hooks yet, simply because there was no need by now. I thought I have to write a module to achieve this. But putting this in the ready.php works like a charm and is super easy to set up.1 point
-
@FrancisChung you have $stats->save; instead of $stats->save(); in your code.1 point
-
Yes, that's it. This is a fully functional code example: //pageviews.php receives a ajax get passing $page->name as querystring //Ex: example.com/pageviews.php?path=/videos/title-of-video/ //First, check if there is a querystring and find the page with it if(($path = (string) $input->get->path)) { $path = $sanitizer->selectorValue($path); $p = $pages->getByPath($path); if($p->id && $p->fields->has('page_views')) { // page was found and it has a 'page_views' field $key = "pageview" . $p->id; if(!$session->$key) { // pageview not yet recorded for this page for this user session $p->setOutputFormatting(false); $p->page_views++; $p->save('page_views'); $log->save("pageviews", $p->id); //optional, just if you want see it in the logs on Admin $session->$key = "pageview" . $p->id; //register in session so a reload will not trigger a pageview for the same user } } } else { //no querystring on url, so lets avoid any problems throw new Wire404Exception(); }1 point
-
"To master git, one has to live many lives" – Confucius Is indeed very hard to understand it beyond the basics. I sure don't. One good resource that I can recommend is this course by Jeffrey Way on his Laracasts: https://laracasts.com/series/git-me-some-version-control He is an excellent teacher, I can't recommend him enough. Take a look at all courses there, you won't regret.1 point
-
On GitHub: https://github.com/rolandtoth/PageimageRemoveVariations On Modules directory: http://modules.processwire.com/modules/pageimage-remove-variations/1 point
-
Hi SamC, Processwire does not create a CSS cache. This is done by your browser and/or the server (in this case, Dropbox). The technique you used to see the new file, by appending a query string in the filename, in this case "?a=1", is one of the things that trigger an instruction in the browser to make it download the file again. You can read more about this in this post https://css-tricks.com/strategies-for-cache-busting-css/ And regarding keeping the site copies in sync between your computers, although Dropbox works, it's not a good practice because you can't track changes on the files and risk losing some of the work done in eventually sync error. It is recommended that you use a version control system for this. Best, Sergio1 point
-
Your "controllers" aka regular ProcessWire templates are always in "site/templates", you can't customize this path. However, with this setting, you tell the module where your twig templates are, e.g. "views" in your case. Since you use twig, check out the template inheritance support from Twig, where you define a "global" template and other children-templates inherit stuff from it. If you enable this setting, you always have the same twig template behind the $view API variable. You either need to write this in an autoload module or attach the hook in your site/ready.php file. Learn more about hooks here: http://processwire.com/api/hooks/ Cheers1 point
-
Those who don't have Lister Pro (like myself) will probably dig this feature - option to specify extra columns for the lister (Find & Users). As you probably know when you close the browser tab with a Lister then your custom columns are gone. This tweak let you specify the defaults. I've needed such feature for a long time and today when I tried to use the filter I realized how useful this would be. There are a few things to iron out and a module config UI is need to be figured out but I already love it Ps. adrian will surely like the screenshot1 point
-
@pwired and all forum members I decided to put together my own bash script because I did not find what I was after. I am not a bash pro nor a linux/unix guru, so there might be better solutions using standard system tools, but I like the result so I thought I share it with you. You might also find it useful. Here is a short demo: https://youtu.be/V6eF4NBNDbc Please read the instructions (located in the script itself) if you happen try it out! Any constructive criticism is welcome. pwdiff.sh 0.0.8, (2016-10-25), initial public release:1 point
-
Sorry if this a bit of a rant. I'm in the last steps of getting our intranet "reborn" on PW, and one still unanswered question is what search backend to use. As with most intranets it holds quite a big number of office and pdf files. I've already tried a few of the major open source search engines like ElasticSearch, Solr, Sphinx and OpenSearchServer, and I found all of them lacking in two regards - for one, the documentation is all over the place so you never know if the piece you're reading even applies to the version you're using, and the implementations of their APIs are just horribly awkward and extremely picky in regards to the slightest deviations from their "standard" (which isn't really concisely documented) syntax. None of them comes with a basic permission system, which is an absolute must have. I can probably work around that with facets or the like, but still... you'd think everybody all over the world but me only indexes public webpages. Design decisions like using JSON objects that have multiple identically named properties make me doubt the sanity of those maintaining the software. Looking at all these points, I'm now also considering rolling my own on top of an InnoDB fulltext index, just re-using the text extractors I've already running in the old system (up to now only feeding the extracted plaintext into a MySQL table and doing literal searches), adding a fulltext index, setting up a lean API module for the few search variants I need and be done with it. That, of course, still leaves the topic of extracting relevant snippets open - should I write my own UDF for that, or are there (functional and maintained) third party extensions available to do just that? A question that warrants some more digging for an educated decision. I'm still a bit torn, but there's also the time factor to consider. If any of you has experiences with searches (especially with implementing visibility of search content using a group-based permission concept) and could throw in a few pointers or experiences, I'd be glad.1 point
-
It doesn't have a shopping cart--at least not that I'm aware of. Most of the reservation page is custom forms / code and such. We have been expanding and tweaking the reservation form for over 6 years and it is available in English, Spanish, and Portuguese. Also, Ryan gets a ton of email so he doesn't always respond. To get his attention I usually have to send him text messages. Not sure about padlooper...I've never heard that word. I'm happy to answer other questions. Jan CTO Tripsite.com1 point
-
Hey guys, I am working on a Visual Studio Code Extension which contains snippets for the Processwire API. You can see my WIP in my repository: https://github.com/jleifeld/Processwire-API-Snippets-for-Visual-Studio-Code It is much work to do everything by hand. Is there a database for the api which contain the same documentation as in the PW cheatsheet? This would make the work easier and faster for me. Thanks, Jannis1 point
-
I needed to calculate recurrent dates for a project and at that time discovered that there is a PHP DatePeriod class for such type of calculations. It was not so easy for me to get my head around this but I finally came up with a function that is calculating recurrences from start date, end date and an interval. Not the same as your scenario, but maybe it can help to get you started. // DatePeriod calculation taken from http://php.net/manual/de/class.dateperiod.php#109846 function getRecurrences($startTime,$endTime,$interval) { $format = 'Y-m-d H:i'; $start = new DateTime(); $end = new DateTime(); $start->setTimestamp($startTime); // if interval 0 we calculate weekdays and set start = end; $end = ($interval == 0) ? $end->setTimestamp($startTime) : $end->setTimestamp($endTime); // if start and end time are the same, we calculate for weekdays and set endtime to 3 month from starttime $end = ($start == $end) ? $end->modify('+90 days') : $end->modify( '+1 minute' ); // set duration to move on in 1 day steps, if we are calculating timestamps for weekdays $duration = ($interval != 0) ? 'PT' . $interval . 'M' : "P1D"; $interval = new DateInterval($duration); $daterange = new DatePeriod($start, $interval ,$end); return $daterange; } EDIT: After reading carefully through your post again, I am wondering about your interval. You say you let the user define an interval as timestamp. But a timestamp typically is one point in time. So I am wondering how your timestamp looks like for describing a time range? Can you give an example? If you are using something like "+1 day", "+1 week" as an interval, you could use strtotime for your calculations, like $new_timestamp = strtotime('+1 week', time()); // + 1 week from today1 point
-
They are pages. Look for them under "Repeaters" inside the admin page in the tree. Repeater pages are under a page with the name "for-page-1234" (1234 is the ID of the page that holds the repeater field) under a page named "for-field-123" (being 123 the id of the repeater field. You can see it o the URL when editing the field). This means that you can easily get all pages from a repeater field in a page by using the selector: $pages->find("parent=/processwire/repeaters/for-field-123/for-page-1234") Or even construct that selector dynamically when needed: $pages->find("parent=/processwire/repeaters/for-field-130/for-page-{$page->id}")1 point
-
If you're on a Mac, CodeKit is a hassle-free (as in open it and you're pretty much ready to go) alternative: https://incident57.com/codekit/ Bonus: Overview of version 2 on CSS Tricks: https://css-tricks.com/codekit-2-0/1 point
-
Hi @gebeer Ye, I must outline some of the features of the generator - it can definitely improve workflow! It's a little opinionated - it generates projects using our SCSS framework, our KSS Styleguide Boilerplate, an extensive Gruntfile for much awesome automation, and of course the MVC Boilerplate, all of which are fundamental to our ProcessWire projects. As a quick overview, you can expect the following structure from a newly generated project : ├── database // location for automated db dumps ├── src // PW install location ├── styleguide // KSS Boilerplate, and SCSS (style.css built to templates) ├── .bowerrc // tell Bower where to install libraries ├── .editorconfig // normalise line endings, tabs, etc for all team members ├── .gitattributes // have git normalise line endings cross platforms ├── .gitignore // default ignores ├── Gruntfile.coffee // automated deliciousness ├── package.json // Grunt dependencies ├── private.json // .gitignored - put sensitive data here (SSH keys, db creds etc) └── private-sample.json // a template private.json for other devs to add non-committed sensitive data I'd like to put together a post covering some finer details in the next 2 weeks or so - things are a bit crazy here at the moment! I'll update here to let everyone know!1 point
-
@OrganizedFellow MVC's not too bad, really. I was always intimidated by it, but all it really is is this: Models -> object definitions, and communication with the database (not really applicable in PW because the API speaks with the DB). Models are an interface between the database, and controllers Views -> Logicless (mostly) templates which are responsible for markup, and display of data. Views communicate only with controllers Controllers -> functional and logical aspects regarding instances of an object (in our case, instances of page templates). Controllers are an interface between Models, and Views As a side note, we have a yeoman generator which will quickly help getting an entire PW project set up: https://github.com/fixate/generator-fixate-pw I'll eventually cover this in a separate post.1 point
-
When you get into sending POST data, ProcessWire has an http class that you can use rather than something like CURL. The benefit of using PW's WireHttp class is that it will fallback to sockets if it has to, ensuring the class works just about everywhere. Here's an example of the same web service we outlined above, except that this one posts to it: $data = array( 'username' => 'ryan', 'pass' => 'mypass', 'email' => 'info@grab.pw' ); $http = new WireHttp(); $result = $http->post('http://www.domain.com/path/to/service/', $data); if($result) { $result = json_decode($result, true); if($result['status'] == 'success') echo "Success! $result[message]"; else echo "Error! $result[message]"; } else { echo "error posting data"; } As a side note, this service is using the same password for the user to add, and the web service password. In reality, you'd probably want those to be different things.1 point
-
The PW API is always the same regardless of context. One of strengths of PW is in it's flexibility when it comes to sending or receiving web service data, and this is one of the things I use it for quite a lot. But you do have to tell it what to do, rather than it telling you what to do. At the simplest level, you could validate against an IP and/or password for authenticating the request. That may or may not be adequate, depending on who/what you are dealing with. In either case, use POST rather than GET. Here is a simple web service that adds a new user (written in the browser / not tested). This would simply be code written into a template file. Ideally you'd split this up a bit more, but just trying to keep it self contained for example purposes. $message = ''; $success = false; if($input->post->pass === 'mypass' && $_SERVER['REMOTE_ADDR'] === '123.123.123.123') { $name = $sanitizer->pageName($inpust->post->username); $pass = $input->post->pass; $email = $sanitizer->email($input->post->email); if($name && $pass && $email) { $u = $users->add($name); if($u->id) { $u->pass = $pass; $u->email = $email; $u->addRole($roles->get('some-role')); $u->save(); $success = true; $message = "Added new user: $u->name"; } else { $message = "username '$name' is already taken"; } } else { $message = "missing required fields"; } } else { $message = "you aren't authenticated"; } $result = array( 'status' => ($success ? "success" : "error"), 'message' => $message ); echo json_encode($result);1 point
-
You might want to check out the blog profile, which uses "next/prev" for comments pagination: http://processwire.com/blogtest/comments/ Also, the current version of ProcessWire does include the ability to paginate comments, though it's not particularly automated yet. See the FieldtypeComments::findComments function. While not the prettiest bit of API code, you can use it like this: $limit = 10; // comments to display per page $start = ($input->pageNum-1) * $limit; $selector = "page=$page, sort=-created, start=$start, limit=" . ($limit+1); // find the comments. replace "comments" with the name of your comments field $comments = FieldtypeComments::findComments("comments", $selector); // output the comments echo $comments->render(); // output the pagination links if($input->pageNum > 1) echo "<a href='./page" . ($input->pageNum-1) . "'>Back</a> "; if(count($comments) > $limit) echo "<a href='./page" . ($input->pageNum+1) . "'>Next</a>";1 point