Leaderboard
Popular Content
Showing content with the highest reputation on 05/22/2017 in all areas
-
I started experimenting this morning. It's not all that difficult to get going. Proof-of-concept up and running already, so should have this functional on the core dev branch this week hopefully. (note: works for JPGs only)8 points
-
@ryan This might be a handy addition to the topic as well: https://gist.github.com/LostKobrakai/ddb11c64dcb0f1bf1c8eed4dd534a868 (prove-of-concept level) Chunked uploads would allow for file uploads beyond any php set limits even for files, which we obviously cannot shrink client side.3 points
-
3 points
-
These redirects can be made by uncommenting two portions of the PW .htaccess file: One Two If you're seeing this when trying to access the PW admin then it could be due to old browser cookies - try clearing the cookies for your domain.3 points
-
Introducing our newest [commercial] module: Recurme Processwire Recurring Dates Field & Custom Calendar Module. http://www.99lime.com/modules/recurme/ One Field to Recur them ALL… A Recurring Dates InputField for your Processwire templates. The InputField you’ve been waiting for. Complex RRule date repeating in a simple and fast user interface. Use the super simple, & powerful API to output them into your templates. example: <? // easy to get recurring events $events = $recurme->find(); // events for this day $events = $recurme->day(); // events for this week $events = $recurme->week(); // events for this month $events = $recurme->month(); ?> <? // Loop through your events foreach($events as $event){ echo $event->title; echo $event->start_date; echo $event->rrule; echo $event->original->url; ... } ?> Unlimited Custom Calendars. Imagine you could create any calendar you wanted on your website. Use recurring events with the Recurme field, or use your own Processwire pages and date fields to render calendars… it’s up to you. Fully customizable. Make as many calendars as you like. Get events from anywhere. Recurme does all the hard date work for you. Unlimited Custom Admin Calendars too. Hope you like it , Joshua & Eduardo from 99Lime. ## [1.0.1] - 2017-05-29 ### changed - Fixed $options[weekStartDay] offset in Calendar - Fixed ->renderCalendar() Blank Days - Fixed missing ->renderList() [renderMonth][xAfter] - Removed ->renderCalendar() <table> attributes border, border-spacing - Fixed ->renderCalendar() excluded dates - Fixed rrule-giu.js exclude dates - Fixed ->renderList missing space in attr ID (shout out to @Juergen for multiple suggestions & feedback).2 points
-
That's probably because MySQL strict mode is enabled. sortRebuild() uses a "shortcut" notation for multiple updates using an "INSERT ... ON DUPLICATE KEY UPDATE ..." statement that fails in strict mode. Both disabling strict mode globally or adding the following in site/config.php should help: $config->dbSqlModes = array( "5.5.0" => "remove:STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY" ) This is already the default for MySQL >= 5.7, but both features may be active in 5.5 and 5.6 installations as well. There's already an open issue for this here.2 points
-
IMO having comprehensive documentation is something that can only add value to the Pro modules, and takes nothing away from them. I get that many users will only interact with the modules via the admin interface and would have no desire to browse through all the methods - they can ignore that documentation entirely. But it's nice to have thorough documentation for those who do have a need for it. I'm not proposing that you necessarily spend a lot of time writing up documentation beyond what's already present in the source. The tools already exist to extract and format those phpdoc comments as online documentation as it powers the current API reference docs. And the API Explorer module can do this for modules already. The reason I prefer online docs to the API Explorer is that it's so useful to harness the power of Google to find what you're looking for. It's quicker and more powerful to open a new browser tab and do a search from the address bar (I have a keyword shortcut for "site:processwire.com/api/ref/+%s") than navigating through the API Explorer interface. And of course not everyone has API Explorer. Could the Pro modules be stored in private GitHub repos and indexed the same way as the API reference? Maybe this module from @justb3a could be useful for the authorisation?2 points
-
After using this module for a while, I have a couple of suggestions for future modifications. First, would it be possible to skip the dialogue window (or auto-close it) if the Hanna code being added does not have any attributes set? It could still have the on-click behaviour after being added (with the "This tag has no editable attributes" message), to future-proof the tag should the user add attributes in the future. Obviously, one could just type the Hanna code, but it is more convenient for clients to pick it from a list. Secondly, this isn't really a suggestion, but a custom modification I made to the code for my own purposes, which might be useful to others. When using selectable option fields (selects, radios, etc), the current method to set the different options is simply: attribute__options=Option A|Option B|Option C // The option string format is the same for dyanamically generated options. With this method, the option field input 'value' and 'text/label' are the same. However, I found that this was not very user-friendly when the options are somewhat cryptic. Eg, from a returned file list: file123-xyz.pdf abc-1978.pdf xyz-blah123.pdf really-long-title-2017-05-apple-blueberry-banana.pdf So, what I did was modify the foreach loop code in the file 'iframe_form.php' at line #63, to make it possible to have a separate input value and text. /* Original code at line #63 in iframe_form.php */ foreach ($select_options as $select_option) { $f->addOption($select_option); } /* My own modification * - Searches the option value for '@@' * - Uses it to split the string into two variables: $optionValue and $optionText * - Then adds the option to the select field. */ foreach ($select_options as $select_option) { if (strpos($select_option, "@@") !== false) { list($optionValue, $optionText) = explode("@@", $select_option); $f->addOption($optionValue, $optionText); } else { $f->addOption($select_option); } } Now, when setting the options, you specify them (either directly or dynamically) by separating each option's value and text/label with '@@' (chosen because it's unlikely to be part of an option value or text): attribute__options=file123-xyz.pdf@@Annual Accounts 2016|abc-1978.pdf@@Some Meaningiful Title|xyz-blah123.pdf@@Another Meaningful Title| really-long-title-2017-05-apple-blueberry-banana.pdf@@The Price of Fruit May 2017 // Note: in reality the above options would be generated dynamically. I would make a pull request (?) via GitHub for this, but I've never used it for such a thing and don't really know how.2 points
-
These are certainly nice projects, but I doubt a majority of users would need them, so they're probably a better fit for 3rd party modules than the core.1 point
-
@Christophe I had too many redirects at one time in the past which was due to the same thing you are trying to accomplish. With my registrar, the dns option to redirect using a wildcard, such as *.domain.tld (www.domain.tld) to domain.tld covers the initial redirect. Then you can leave the htaccess file to change http to https. This resolved the issue for me.1 point
-
1 point
-
Looks really amazing. One question: Is there the possibility to limit an event to a certain endtime or to a certain date? Fe event starts at 6am and ends at 9am or an event goes over midnight (multiple days event) From the images above it seems that it will always be a whole day event. Best regards and respect for this work.1 point
-
Yes. Any time you create or retrieve a page, whether it is a User type or any type of Page object, you should turn off output formatting before you save the data. For example: // new user, or any type of page object $u = new User(); $u->of(false); // turn off output formatting // assign data to fields $u->save(); // existing user, or any type of page ovbect. $u = $users->get("username"); // replace username with the name of a user $u->of(false); // turn off output formatting // assign data to fields $u->save(); ProcessWire will automatically turn output formatting on again after the save completes.1 point
-
Are you sure you are logged in? If you're not logged in it saves to the guest user. $u = $users->get("username"); username should be the name of the user you want to edit/save. If this are not the problem I don't know. If you test this on a server I could take a look, if you're ok with giving me access.1 point
-
Yeah, Ben C was referring to a post about four or five about his. This one to be precise:1 point
-
Okay, nice. I've bumped the version to 1.0.2. So you can get an "official" Release via GitHub/composer https://github.com/sunlix/ProcessAbbreviate https://packagist.org/packages/zenmotion/process-abbreviate1 point
-
hmmm can you look at the top of your referenced file if this line appears? if(!class_exists('Abbreviation', false)) require_once(__DIR__ .'/Abbreviation.php');1 point
-
You should activate those pages, check the checkboxes next to the page names (Settings tab at page edit).1 point
-
Hi I've been working on a site that needed a calendar. Specifically it needed a calendar with support for some rather iffy recurrence patterns. This is all still pretty rough but I have written two modules. Calendar : Implementes basic event recurrence expansion using four fields: calendar_start calendar_end calendar_rrule calendar_exdate these fields are created on install (but not removed!) and are added to the template: calendar-event which is created on install (but again not removed on uninstall!). the calendar-event template is intended to be expanded to represent the needed calendar event structure. The ProcessCalendarAdmin provides a calendar admin gui. the modules and a slightly more detailed readme can be found on github https://github.com/lindquist/processwire-calendar I'm not sure how much more time I can/will spend on this, so here it is in case anyone finds it useful1 point
-
Hi Joshua, Can you send screenshots of the existing site and new design to hello@buckhorn.marketing? Thanks, Steve Shaw1 point
-
1 point
-
or if you need to have inline icons (within the editor), you could use a hanna code to convert the hanna tag into an icon.1 point
-
Those ridiculous, downright stupid, pointless and idiotic EU Cookies taste like crap.1 point
-
My new blog post on setting up a Blank Proflie: http://szabesz.hu/blog/my-basic-setup-of-processwire/1 point
-
I've used the code on this tutorial for at least 4 or 5 sites, and it's rather easy to tweak for your needs. (You can pay for the full source code if you want to reward the developer for his work, but you don't have to: you can copy and paste the various parts needed).1 point
-
Most of our image/file features have been developed by the community rather than me, and I'm guessing this will follow a similar path. It doesn't seem to come up very often, but since you've mentioned it here maybe we'll have to bring more focus to it. I'll try to get a closer look this week to get a better idea of when we might be able to get more momentum going here. I do agree it would be a nice thing to have sooner rather than later. Also, since you quoted both 2016 and 2017 roadmap, it's important to note that this is a roadmap. It is a list of goals, it is not a contract of promises. We never expect to be able to accomplish all the goals, but feel it's important to have them nevertheless. Always good to aim for more rather than less. What doesn't get completed in one year still stays on the roadmap for the next year, unless it's determined it shouldn't be for some reason.1 point
-
Alternatively you can temporary upload your own personal index.html page with "site in maintenance"1 point
-
After this tutorial you'll have learned how to: Build a Process module Make an AJAX request to backend Serve JSON as response Let's say you want to display the latest orders in a dashboard that you can access from admin panel. And you want it to refresh its content with a button click. Most straightforward and proper way (that I know of) is to create a Process module, as they're built for this purpose. First, create a directory under /site/modules/, call it ProcessDashboard, and create a file named ProcessDashboard.module under that directory. Following is about the least amount of code you need to create a Process module. <?php namespace ProcessWire; class ProcessDashboard extends Process { public static function getModuleInfo() { return [ 'title' => 'Orders Dashboard', 'summary' => 'Shows latest orders', 'version' => '0.0.1', 'author' => 'abdus', 'autoload' => true, // to automatically create process page 'page' => [ 'name' => 'order-dashboard', 'title' => 'Orders', 'template' => 'admin' ] ]; } public function ___execute() { return 'hello'; } } Once you refresh module cache from Modules > Refresh, you'll see your module. Install it. It will create an admin page under admin (/processwire/) and will show up as a new item in top menu, and when you click on it, it will show the markup we've built in execute() function. All right, now let's make it do something useful. Let's add create a data list to display latest orders. We'll change execute() function to render a data table. public function ___execute() { /* @var $table MarkupAdminDataTable */ $table = $this->modules->MarkupAdminDataTable; $table->setID($this->className . 'Table'); // "#ProcessDashboardTable" $table->headerRow([ 'Product', 'Date', 'Total' ]); // fill the table foreach ($this->getLatest(10) as $order) { $table->row([ $order['title'], $order['date'], $order['total'] ]); } // to refresh items $refreshButton = $this->modules->InputfieldSubmit; $refreshButton->name = 'refresh'; $refreshButton->id = $this->className . 'Refresh'; // "#ProcessDashboardRefresh" $refreshButton->value = 'Refresh'; // label of the button return $table->render() . $refreshButton->render(); } where getLatest() function finds and returns the latest orders (with only title, date and total fields) protected function getLatest($limit = 5, $start = 0) { // find last $limit orders, starting from $start $orders = $this->pages->find("template=order, sort=-created, limit=$limit, start=$start"); // Only return what's necessary return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total ]; }); } When you refresh the page, you should see a table like this Now we'll make that Refresh button work. When the button is clicked, it will make an AJAX request to ./latest endpoint, which will return a JSON of latest orders. We need some JS to make AJAX request and render new values. Create a JS file ./assets/dashboard.js inside the module directory. window.addEventListener('DOMContentLoaded', function () { let refresh = document.querySelector('#ProcessDashboardRefresh'); let table = document.querySelector('#ProcessDashboardTable'); refresh.addEventListener('click', function (e) { // https://developer.mozilla.org/en/docs/Web/API/Event/preventDefault e.preventDefault(); // Send a GET request to ./latest // http://api.jquery.com/jquery.getjson/ $.getJSON('./latest', { limit: 10 }, function (data) { // check if data is how we want it // if (data.length) {} etc // it's good to go, update the table updateTable(data); }); }); function renderRow(row) { return `<tr> <td>${row.title}</td> <td>${row.date}</td> <td>${row.total}</td> </tr>`; } function updateTable(rows) { table.tBodies[0].innerHTML = rows.map(renderRow).join(''); } }); And we'll add this to list of JS that runs on backend inside init() function public function init() { $scriptUrl = $this->urls->$this . 'assets/dashboard.js'; $this->config->scripts->add($scriptUrl); } Requests to ./latest will be handled by ___executeLatest() function inside the module, just creating the function is enough, PW will do the routing. Here you should notice how we're getting query parameters that are sent with the request. // handles ./latest endpoint public function ___executeLatest() { // get limit from request, if not provided, default to 10 $limit = $this->sanitizer->int($this->input->get->limit) ?? 10; return json_encode($this->getRandom($limit)); } Here getRandom() returns random orders to make it look like there's new orders coming in. protected function getRandom($limit = 5) { $orders = $this->pages->find("template=order, sort=random, limit=$limit"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total ]; }); } And we're done. When refresh button is clicked, the table is refreshed with new data. Here it is in action: 2017-04-29_19-01-40.mp4 (227KB MP4, 0m4sec) Here's the source code: https://gist.github.com/abdusco/2bb649cd2fc181734a132b0e660f64a2 [Enhancement] Converting page titles to edit links If we checkout the source of MarkupAdminDataTable module, we can see we actually have several options on how columns are built. /** * Add a row to the table * * @param array $a Array of columns that will each be a `<td>`, where each element may be one of the following: * - `string`: converts to `<td>string</td>` * - `array('label' => 'url')`: converts to `<td><a href='url'>label</a></td>` * - `array('label', 'class')`: converts to `<td class='class'>label</td>` * @param array $options Optionally specify any one of the following: * - separator (bool): specify true to show a stronger visual separator above the column * - class (string): specify one or more class names to apply to the `<tr>` * - attrs (array): array of attr => value for attributes to add to the `<tr>` * @return $this * */ public function row(array $a, array $options = array()) {} This means, we can convert a column to link or add CSS classes to it. // (ProcessDashboard.module, inside ___execute() method) // fill the table foreach ($this->getLatest(10) as $order) { $table->row([ $order['title'] => $order['editUrl'], // associative -> becomes link $order['date'], // simple -> becomes text [$order['total'], 'some-class'] // array -> class is added ]); } Now, we need to get page edit urls. By changing getLatest() and getRandom() methods to return edit links in addition to previous fields protected function getLatest($limit = 5, $start = 0) { // find last $limit orders, starting from $offset $orders = $this->pages->find("template=order, sort=-created, limit=$limit, start=$start"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total, 'editUrl' => $order->editUrl ]; }); } protected function getRandom($limit = 5) { $orders = $this->pages->find("template=order, sort=random, limit=$limit"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total, 'editUrl' => $order->editUrl ]; }); } and tweaking JS file to render first column as links function renderRow(row) { return `<tr> <td><a href="${row.editUrl}">${row.title}</a></td> <td>${row.date}</td> <td>${row.total}</td> </tr>`; } we get a much more practical dashboard.1 point
-
Hi @zervis, you could try $pages->findMany("template=user"); or $pages->findMany("role=user"). I tested this with normal PW users and $pages->find(), but it should work with findMany, too. Another way could be: $pages->find("template=user", ["lazy" => true]) see here for options, but I didn't tested that.1 point
-
For Chinese characters, I just copied the characters I needed to use in a page name and appended them to my $config->pageNameWhitelist, like this: $config->pageNameCharset = 'UTF8'; $config->pageNameWhitelist = '-_.abcdefghijklmnopqrstuvwxyz0123456789' . 'æåäßöüđжхцчшщюяàáâèéëêěìíïîõòóôøùúûůñçčćďĺľńňŕřšťýžабвгдеёзийкл' . 'мнопрстуфыэęąśłżź健康長壽·繁榮昌盛'; You'll have to make sure that your /site/config.php file is UTF-8 encoded, which it should be by default. But depending on what editor you are using, it's always possible it's not.1 point