Leaderboard
Popular Content
Showing content with the highest reputation on 01/20/2016 in all areas
-
I am also one of those weirdos without a Facebook or Twitter account - I'd much rather read the PW forum or Github activity. That said I am often accused of staring at my wife's computer when she is looking at friend's photos on FB, so I guess I am a social media voyeur rather than exhibitionist.6 points
-
Hi, Here is our web site done in ProcessWire: http://gsbelarus.com/pw/en/ Background image will change with every page reload, so use Refresh to view all gallery.5 points
-
Hey mr. Ivan! Nice to hear from you. There can be some different usecases. Normally you want to use a Queue for decoupling time intensive tasks from the websites responses so that the users doesn't have to wait long times. For example, if someone booked / collected something on a site, there will finally an email sent to him / her. If the script would wait until it could connect to the smtp server and has sent the email, it could be that the smtp server is busy and delays the sending. With a Queue, you simply drop in this job and give fast response to the users screen: "Thanks for your booking! We will response by email soon.". Another script will pickup the job and proceed it. So, decoupling time intensive tasks and optionally split up the work to multiple workers if usefull / necessary. Another example would be sending a newsletter to 5k recipients. It seems better to me to have those temporary data seperated from the main Database in regard of Backups / Restores. With WireQueue you can create and controll Queues visually in the backend. This wouldn't be necessary but I found it usefull and comfortable. Currently there is only a very simple StorageModule available with plaintext files. The next one uses SQlite Databasefiles what is much more comfortable as it opens the WireQueue to not only put and get jobs into it but also can be used to store the current state of each job. Or if the collected data should be exported to other systems for further processing, etc. You can use whatever storage type you like. You only needs to create your own storage module upon the abstract class that comes with the module. Currently there are only comments in the code itself and the WireQueueTextfile module for detecting how it should be done. But it isn't complicated. You can setup one that uses a MYSQL table in another DB than that from your PW installation. etc. etc. More and better information will come later in next step. Does that help?4 points
-
Jumplinks is suitable for this task. You could make use of Mapping Collections or Destination Selectors. Browse through the documentation to see if it will work for you. As always, you're more than welcome to ask for help if you need it, either in this thread, or the support thread.4 points
-
In some cases it doesn't matter, and in some cases it does It depends on the scope and class context as to whether $this->user->name will work or not, but seems to have been common practice in various modules. With PW 3.x ramping up I would suggest reading this: https://processwire.com/blog/posts/processwire-2.6.21-upgrades-comments-more-on-pw-3.x/#more-updates-on-processwire-3.0 - scroll down a little to the "Multi-instance with 3rd party modules and PW 3.x" section where it explains what works where. Actually this is a good reminder for me to update my modules to use $this->wire()4 points
-
Server IP/~user RewriteBase may need to be set in htaccess. Are you running apache2.4+ (See comments in htaccess regarding versions).3 points
-
Example for a use case with importing things. This is a raw draft with a bit pseudo code: // you have created a queue in PW, the ID of the page is 2000 for example // here is some skeleton code for an importer that uses this queue // get and validate the queue handle if(! ($queue = $pages->get('id=2000')->wireQueue())) exit(); // we could not get the Queue page // now start to scan / read data for your imports, wrap each record into an array and put it into the queue foreach($pages->find(YOURSELECTOR) as $p) { $data = array($p->field1, $p->field2); $queue->addItem($data); } // now start to process your items by pulling one after the other from the Queue while($timer < $maxtime) { $data = $queue->getItem(); // process the $data ... } $session->redirect('./');2 points
-
2 points
-
Glad it's sorted and runnin'! Here's to your first forum post being the most difficult during your ProcessWire career!2 points
-
Thanks for your responses. Respective issue was created: https://github.com/ryancramerdesign/ProcessWire/issues/1622 . Variable $homepage was used only for illustrative purposes. LostKobrakai's definition as $pages->get("/") would fit just right.2 points
-
Bitnami XAMPP has ProcessWire available as all-in-one add-on on top of XAMPP. https://bitnami.com/stack/xampp#processwire https://www.apachefriends.org/add-ons.html2 points
-
can you try moving the page up to the top, in the admin page branch? sure, i can try, and the plan is to eventually make a module... but in the meantime i'll try and make a tutorial, because until the module is made, it's just a lot of fields, templates and pages in the admin; then 1 dashboard.php, and 3 css files2 points
-
http://code.tutsplus.com/articles/4-reasons-to-choose-processwire-as-your-next-cms--cms-25062 and http://webdesign.tutsplus.com/tutorials/how-to-install-and-setup-processwire-cms--cms-25509 Copied from tuts topic. Great day for pw exposure. Please share these on Twitter, Facebook etc!2 points
-
Hello @ all I want to share my code of a module which copies values from a parent page to a child page by using the add button of a pagetable field. If you find it useful you can copy the code or you can improve the code and post your ideas of improvement here. The intention for me was that I have pages with events and I dont want to write all the data for an event manually. Especially if only the date of the event is different. I use a pagetable field for the events and I want to click the add button of this field and a new childpage will be created with all the data of the event (title, description, summary,...) so I have only to fill in the start and end date for the event. So far so good, but it was a little bit tricky to get this to work with the add button of the pagetable field. So I decided to write a module which does the work for me. Here is the piece of code: <?php class CopyPageTableAdd extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Pagetable copy values', 'summary' => 'Copy Pagetable content by pressing the add button', 'href' => '', 'version' => 001, 'autoload' => true, 'singular' => true ); } public function ready() { $this->pages->addHookBefore('ProcessPageAdd::execute', $this, 'copyaddpage'); } public function copyaddpage() { //configuration $parenttemplatename = "events"; //the template name of the parent template $childtemplatename = "single-event"; //the template name of the newly created child template $page = new Page(); $page->parent = $this->input->get->parent_id; if ($page->parent->template == $parenttemplatename) {//check if it is the right parent template $page->template = $childtemplatename; //set the template for the created child page //copy all fields field values from the parent template (start) //enter all fields which you want to copy into the child page $page->title = $page->parent->title; $page->eventstatus = $page->parent->eventstatus; $page->eventtype = $page->parent->eventtype; $page->summary = $page->parent->summary; $page->headline = $page->parent->headline; $page->importanteventstext = $page->parent->importanteventstext; $page->importanteventstext = $page->parent->importanteventstext; $page->notifiable = $page->parent->notifiable; $page->reservationtype = $page->parent->reservationtype; $page->participantlimit = $page->parent->participantlimit; $page->participantmaxnumber = $page->parent->participantmaxnumber; $page->eventmaxstatus = $page->parent->eventmaxstatus; $page->eventcosttype = $page->parent->eventcosttype; $page->eventprice = $page->parent->eventprice; $page->eventpriceadd = $page->parent->eventpriceadd; $page->eventlocationname = $page->parent->eventlocationname; $page->street = $page->parent->street; $page->postalcode = $page->parent->postalcode; $page->eventlocationname = $page->parent->eventlocationname; $page->place = $page->parent->place; $page->region = $page->parent->region; $page->country = $page->parent->country; $page->googlemap = $page->parent->googlemap; //copy all fields field values from the parent template (end) $page->addStatus(Page::statusUnpublished); //this foreach loop is only if you have a multilanguage site to get the path names in each language //if your site is only single language you can use $page->name=$page->parent->name (but not tested) foreach ($this->languages as $lang) { $lname = $lang->id; $pageName = $page->title->getLanguageValue($lang); $page->set("name$lang", $pageName); if ($lang->isDefault()) continue; $page->set("status$lang", 1);//activate the multilanguage checkbox } $page->save(); $this->session->redirect("../edit/?id=$page"); } } } The configuration part: //configuration $parenttemplatename = "events"; //the template name of the parent template $childtemplatename = "single-event"; //the template name of the newly created child template This is the part where you have to define the templates. The name of the parent template is responsible that the module only run on that template (in my case the template with the name "events). The name of the child template ist the template which should be created after pressing the add button (in my case the template with the name "single-event"). You have to fill in your template names. The module runs only if the parent template has the specific name and creates only child pages with the child pages template name. Copy all field values par: //copy all fields field values from the parent template (start) //enter all fields which you want to copy into the child page $page->title = $page->parent->title; $page->eventstatus = $page->parent->eventstatus; $page->eventtype = $page->parent->eventtype; $page->summary = $page->parent->summary; $page->headline = $page->parent->headline; $page->importanteventstext = $page->parent->importanteventstext; $page->importanteventstext = $page->parent->importanteventstext; $page->notifiable = $page->parent->notifiable; $page->reservationtype = $page->parent->reservationtype; $page->participantlimit = $page->parent->participantlimit; $page->participantmaxnumber = $page->parent->participantmaxnumber; $page->eventmaxstatus = $page->parent->eventmaxstatus; $page->eventcosttype = $page->parent->eventcosttype; $page->eventprice = $page->parent->eventprice; $page->eventpriceadd = $page->parent->eventpriceadd; $page->eventlocationname = $page->parent->eventlocationname; $page->street = $page->parent->street; $page->postalcode = $page->parent->postalcode; $page->eventlocationname = $page->parent->eventlocationname; $page->place = $page->parent->place; $page->region = $page->parent->region; $page->country = $page->parent->country; $page->googlemap = $page->parent->googlemap; //copy all fields field values from the parent template (end) This ist the part where you can fill in all fields which you want to copy the values. It copies the values from the parent page to the child page. You can do this also with a foreach loop, but I dont want to copy all field values so I write it manually for each field. The multilanguage part: foreach ($this->languages as $lang) { $lname = $lang->id; $pageName = $page->title->getLanguageValue($lang); $page->set("name$lang", $pageName); if ($lang->isDefault()) continue; $page->set("status$lang", 1);//activate the multilanguage checkbox } The multilanguage part is necessary if you have a multilanguage site, because it creates the path names for each language in the right language. After that the multilanguage checkbox for the non default language should be checked to activate the page in this language. Here are some screenshots: 1) Press the add button of the pagetable field 2) A new child page will be created with prefilled values of the parent page 3) Path names are in the right language and multilanguage checkbox is activated So this might be useful for others Best regards1 point
-
i really liked the "save + new" and "save + close" button back in my joomla days here is the first version of a module to bring this functionality to processwire. i know there's the save actions module, but that's not exactly what i wanted... module is alpha state https://github.com/BernhardBaumrock/SaveButtonEnhanced i have one problem where i need your help: i want to submit the #ProcessPageEdit form via a jquery click() event: https://github.com/BernhardBaumrock/SaveButtonEnhanced/blob/master/SaveButtonEnhanced.module#L126 but unfortunately that does not submit the form reliably. sometimes it works, sometimes it doesn't. most of the time i need a second click. also i was not able to trigger the click like this: $('body').on('click', '.sbe_action', function() { console.log('clicked a sbe item'); }); it just did nothing does anyone know what is the problem here? would really appreciate it.1 point
-
------------------------------------------------------------------------------ This is officially released now with some fixes and a second storage handler based on SQLite3. ------------------------------------------------------------------------------ WireQueue WireQueue is a module that allows easy creation and usage of Queues in ProcessWire. It is based upon a basic (parent) module that can or should have one or multiple StorageHandler modules. This alpha pre release contains a basic plain text storage module, WireQueueTextfile. The base module creates the needed: FIELDS (wire_queue_type, wire_queue_state, wire_queue_storage_options) TEMPLATES (wire-queue-container, wire-queue-storage, wire-queue-tools) PAGES (wire-queues = container for all Queuepages, wire-queue-storages = container for StoragetypePages) ROLE (wire-queue-admin) Each storage module creates one page under wire-queue-storages. New Queues can be created in the backend by adding a new page under "Wire Queues". After creation one have to select a Storage type from availables list and publish the page. After that, there are some buttons available to start / pause / and close the queue. Putting and getting data to and from the queue is done via API calls. First you have to get the page that holds the queue object. // get and validate the queue handle if($queue = $pages->get(SELECTOR_TO_DESIRED_PAGE)->WireQueue()) { // wrap your data into an array and pass it into the queue $success = $queue->addItem($data); ... } // get and validate the queue handle if($queue = $pages->get(SELECTOR_TO_DESIRED_PAGE)->WireQueue()) { $data = $queue->getItem(); ... } Thats basically all what you want from a queue. Following are a few conveniences: $queue->getPage()->title gives you the title of the queue, ($queue->getPage() returns the page object) $queue->className() shows the StorageType of the queue $queue->getState() and $queue->getStateStr() returns the current state of a queue: 1 = new / empty 2 = enabled / running 3 = paused 4 = closed / archived $queue->itemCount() gives the total number of all pending items in the queue Here is code that gives an overview of all Queues in the system: $container = $pages->get('template=wire-queue-container'); $bodyContent = "<h1>$container->title</h1>"; $bodyContent .= "<p>There are currently {$container->numChildren} Queues defined:</p>"; $bodyContent .= "<ul>"; foreach($container->children() as $p) { if(! ($queue = $p->wireQueue())) continue; $bodyContent .= "<li>{$queue->getPage()->title}<ul>"; if(!$queue->ready2use()) { $bodyContent .= "<li>{$queue->className}</li>"; $bodyContent .= "<li>This Storagetype is not ready to use! The System seems not to provide all requirements.</li>"; $bodyContent .= "</ul></li>"; continue; } $bodyContent .= "<li>{$queue->className}</li>"; $bodyContent .= "<li>{$queue->getStateStr()} ({$queue->getState()})</li>"; $bodyContent .= "<li>Currently are {$queue->itemCount()} items pending!</li>"; $bodyContent .= "</ul></li>"; } $bodyContent .= "</ul>"; Following are a screenshots of the backend The module is on Github: https://github.com/horst-n/WireQueue Would be nice if someone has time and can test it a bit and report back.1 point
-
I fixed the image upload issue and think I shouldn't post it here... I take a closer look... Nothing in the caddy error log, access.log shows me the 500 error code. Look into the PW error log... Error: Call to undefined function ProcessWire\mb_strtolower() (line 378 of /home/caddy/public_html/wire/core/WireUpload.php) Then ... no, it was more like Solution (CentOS): yum install php-mbstring Upload works fine. It's NOT a PW or Caddy bug! Just a missing PHP package Done some more testing (add / edit fields, edit content, upload images, insert images, ... works fine But frontend edit doesn't work. Nothing happend during click the "Save" button. Also no log entry (access, error or PW).1 point
-
1 point
-
InputfieldSelect is a form inputfield like any others, so if you submit a form with the inputfield in it, the selector will be sent. You can then use this selector in the module to select the pages. There's no such thing as a prebuild ajax solution to update without an pagerefresh.1 point
-
Thanks Rick! Your solution worked, I had to add the rewrite rule. Tried that before, but did it wrong, doh! Cheers1 point
-
the latest screenshot i use pages for the shortcut widgets as follows; this is a basic setup and will be expanded upon gradually: the widgets are pages this is the template for making shortcuts; the shortcuts are configured first, and then added to the widget; this way shortcuts can be used in any widget this is the page for configuring a shortcut widget this is the shortcut page showing the page select for the shortcuts there is one template file dashboard.php which controls the contents of the dashboard. the shortcut widgets are generated automatically based on being setup in the admin; the lister widgets are currently hardcoded but the plan is to make them configurable using a selector field1 point
-
@Gideon So and @regesh, I am pretty sure this is a bit of an abandoned experiment - it was never officially released in the modules directory, so I don't think it will see anymore updates. Also @kongondo has a new module that will do all this and lots more: https://processwire.com/talk/topic/11224-media-manager/1 point
-
Thank you Adrian. Seems that the blog post came 3 months too early for me. I read it but didn't remember. Now it makes sense1 point
-
Usually it works if you just set the "$entryPage->titel" to the value, but think it only works with the ID. Depends if you use the "ID" or the additional "value" options (id=value|title) If using value: foreach ($options as $option) { $field->addOption($option->value, $option->title); } foreach ($entryPage->titel as $value) { $valArray[] = $value->value; // array of values selected, not key=>title } $field->attr("value", $valArray); Using ID foreach ($options as $option) { $field->addOption($option->id, $option->title); } $field->attr("value", $entryPage->titel); // just passing the field (only when outputformatting off) If that doesn't work just make an array using id. foreach ($entryPage->titel as $value) { $valArray[] = $value->id; }1 point
-
Your array look like have auto index. Try to set array key as $value->id if there is a id or something like it. on here: $field->addOption($option->value, $option->title); you used $option->value like a key but on here : $valArray[] .= $value->title; you don't have a key ? and when you set an array don't use .= this will be enought $valArray[] = $value->title; or $valArray[$value->value] = $value->title; For asmSelect you can clone core asmSelect module and rename it modify module as your needs or if there hook available you can make hook or you can use asmSelect directly.1 point
-
Compare the entries from $options with the entries from $entryPage->titel. $options->value must match $value->titel. Maybe you have to change titel to value: $valArray[] = $value->value;1 point
-
Update: So I've been using Pete's dashboard module instead of the technique described above; it's quicker to setup, and easier to clone to other installs, and no need to have code in various places like the themes folder and in ready.php The hope/plan is to turn it into a full widget enabled dashboard module that i can install on various installations a) without having to do any hardcoding b) enable control over which widgets are shown on the dashboard (by user/role/permission) c) allow for easy configuration of colors, icons, columns, etc. To achieve this I setup some templates for different widget types, one is a shortcuts widget, another is a page lister widget; these each have pages and fields to configure them; i can set them to appear by user/role. in the future i can add different types of widgets as needed and then include them in the needed user's dashboard. This is using a combination of a free (MIT licensed) admin theme for bootstrap, but instead of using bootstrap as the css layout, it uses a tiny grid called rwdgrid which i s 2KB; it uses the box, and other widget classes from the admin theme.1 point
-
I would like to include my thanks too, LostKobraKai, Kongondo, Adrian, Ryan and all the others i can't name now. This forum's great for newbies like me. It can be really overwhelming and irritating to code sometime, but in the end you always get there with the help of the generous staff-members. Thanks again! All the best Jakob1 point
-
This kind of error is usually because your code is overwriting the PW $user object. Try making your own user and password variable something like $u and $p, then there is no chance of that happening.1 point
-
I have to hop in on this and portray my thanks to LostKobraKai and everyone else on this forum! Everyone is so helpful and (and luckily for me) ignores my dumb/simple questions to help me out. As someone still learning php and processwire, it can be overwhelming trying to achieve what is in my head with the limited knowledge that I have thus far.1 point
-
Unix timestamps do start in 1970. All times / dates before that can therefore not be translated to a timestamp and not be saved. I'm just not sure, why it's saving a date for 1902 correctly. Edit: Ah php does work with negative integers as well. The max size for an integer (32 bit) would be -2147483648 which translates to 1901/12/13 20:45:52. So maybe it's still an issue with not being able to translate to a timestamp.1 point
-
$tmpDir = new WireTempDir('someName'); // add files $fileBasename = 'basename.ext'; $filename = $tmpDir->get() . $fileBasename; file_put_contents($filename, base64_decode($b64Data)); $page->files->add($filename); // repeat for all files ... // optionally, at the end call $tmpDir->removeAll(); EDIT: Ah, you already know / found WireTempdir() EDIT2: If one use WireTempDir for very timeconsuming tasks, one optionally can define a maxAge for it, different than the default 120 seconds: $tmpDir = new WireTempDir('someName', array('maxAge' => 300));1 point
-
this in your /site/ready.php <?php $wire->addHookAfter("ProcessPageEdit::buildForm", function(HookEvent $event){ $process = $event->object; $form = $event->return; $page = $process->getPage(); // remove field when actual page has no children if($page->numChildren == 0) { $form->remove($form->getChildByName('your_field_name')); } });1 point
-
Conclusion, we are weird anti social people. Ok, jokes asides, it seems to be the trend with the type of developers Processwire attracts as diogo stated. I also think that also the very nature of Processwire makes it a bit "anti marketing buzz". We just won't be seeing: "10 MODULES YOU CAN'T LIVE WITHOUT" and I think that because this "markets" don't really exist in the PW related dev world. I wonder if we should take a look at what other frameworks more like Laravel are outputting to the social media. Ironically, I started using Twitter a lot more recently to basically get more involved with anyone out there who is using Processwire.1 point
-
This is just my personal opinion, but I hate social media. Actually, I find it annoying to be constantly interrupted with tweets, or other messages, while working. And when I'm not working (read playing golf) the last thing I'm concerned about at that time is an update. I also try to keep things centrally located so that I don't have to go lookin' at other places to get my news or information. As it is now, we search both the forum and github for information regarding a topic. I think it would become a maintenance issue to add more avenues. Don't get me wrong, I'm not against using these tools to better the publicity, I'm just sayin' I personally don't use them.1 point
-
I don't have an answer to this question, but I suspect it has to do with the very nature of PW that attracts people that are more focused on work and GTD and less worried about social media. At least I like to think that's the reason1 point
-
I do not know about others, but I have fallen in love with ProcessWire at first sight However, I hate social media and maybe it is not just me who does so.1 point
-
1 point
-
I double the thanks! I think LostKobraKai's posts around the forum are a damn awesome source of learning, short elegant code filled answers right in your face! But certainly can't stop thanking here, there is so much talented and experienced people giving away so much valuable advice, I had forgotten how important a community can be when learnimg new stuff. And no, I'm no that drunk yet! But already feeling sentimental lol1 point
-
My preferred approach is to create a high level "Slideshows" page. Then I will create a parent "Slideshow" page and add individual slides as child pages. On the page where a slideshow needs to be assigned, I create a Page field that allows for a single slideshow selection. Using repeater fields is a bit limited in that you have to completely delete the slide from the slideshow if you no longer want to use it. Some of my clients want to unpublish a slide and then use it again in the future. Using pages as individual slides provides them more flexibility, and using pages as slideshows allows them to create a variety of slideshows that can be swapped out. For example, a client may want to change Home page slideshows on a seasonal basis.1 point
-
Just wanted to throw in my two cents. If you come at it as a front-end developer that's a complete beginner to CMSs, then PW should be very easy to get going. It's built around working the same way that existing web technologies work… Pages map in the same way that URLs do… Template files are just plain HTML/PHP files… the API is largely the same as a front-end API (jQuery)… and so on. So if you know your basic web technologies outside of CMSs, then you won't find a simpler system than ProcessWire. The problem is most other CMSs don't work that way. So the line gets more blurry when you've become used to the terminology and approach of another CMS, because PW can be quite different. Sometimes you have to unlearn what you know from elsewhere in order to appreciate the simplicity of PW. People are always trying to find complexity that isn't there, especially those that grew up on other platforms. PW is a system that rewards you by being curious. We aim to show you how to fish so that you can catch the big fish. We're not here to catch the fish for you. You don't have to know anything about fishing, but you should know how to yell for help if you fall in the water. And you should be willing to learn by example. I learn best by example, so this is the way I tend to teach too (and I recognize not everyone learns the same way). PW is a CMS and CMF, not a website builder. If you are curious and willing to explore, you'll find it is very simple indeed. Certainly far simpler than even WordPress in creating a custom website. You do have to come from the point of view of "I want to create and have the system adapt to me" rather than "I will create something based on what the system provides." If you already know what you want to create and it's something unique, you won't find a simpler path to get there than PW. WordPress is a different beast, in that it's basically saying "YOU WILL CREATE A BLOG or modify this blog and call it something else." Some people like that underlying structure… "okay, we're starting with a blog, what can we do with it?" Others do not like that underlying structure. Our audience consists of those that want to have a system support their original creation rather than mash up an existing creation. There was a PDF posted earlier that I think hit upon some good points, and I appreciate the effort that went into putting it together. The fictional character being scripted in the dialog is not our target. I can go into specifics if anyone wants me to, but I was definitely left feeling at the end of it that we have to be careful about hand-feeding too much or else we'll start attracting people beyond our support resources. Folks that want the fish cooked and filleted rather than folks learning to fish. Perhaps in time we will want to attract more of the consumer-type audience, but currently I don't know how to support users looking to find all the answers in a sitemap file. Keep in mind that unbridled growth is not necessarily desirable. Most of us don't get paid for most of the work we do here and we do best if we grow in a more healthy manner, attracting more thoughtful designer/developers that are here to learn and also contribute. Obviously the author of the PDF is one of the thoughtful ones (and the PDF is a great contribution), even if his fictional character isn't necessarily, but we'll welcome him anyway. But we will definitely be going through the PDF in more detail to learn and improve from it where appropriate, while keeping our audience in mind. I think we're doing something right, because our audience is growing rapidly. I'm nearly full time on ProcessWire now, and it's still difficult to keep up with everyone. At present, I like that our audience is largely open-minded, curious and thoughtful designers and developers. Somehow we've attracted an incredible quality of people and that's what makes this place great. We could not ask for a better group of people here. I'm reluctant to lead PW towards a website builder direction because I think that's when the quality of the community could go down, as people come looking to eat fish rather than learn, catch some fish, and throw some back. The reality is that part of our long term goals include converting the rather large audience that has outgrown WordPress into ProcessWire users. I'm convinced that we do that by giving them more ProcessWire, and not more WordPress. But at the same time, we always have to keep an eye on WordPress and learn. They've been lucky no doubt, but they are also doing many things right. So we have been and always will be working to make the WP-side of users more comfortable in ProcessWire, while also trying to help them grow by distancing them from the limited WP mindset.1 point
-
<qoute>experience with running $pages->find("selector") api call on over 10,000 pages?</quote> I Don't think you will have any noticeable slowness with that amount of pages to be searched. You can't compare getResources with the ProcessWire way of finding pages. So far I understand Modx loads all the fields with getResources & the custom fields if needed in your results. ProcessWire wil only load the fields when you access them, so there's no field load with a page find. Result, searching 100.000 pages is not a problem. Searching 10.000 pages, just a blink of an eye.1 point
-
You actually can use the 'sort' property, but you'll want to perform the sort after you've assigned it to all your items, because PW will write them out in the order that they appear. For instance, here is how we might reverse the order: $cnt = count($page->images); foreach($page->images as $image) { $image->sort = $cnt; $cnt--; } // now tell it to sort by the field 'sort' $page->images->sort('sort'); // you may not need to do this, but putting it here just in case $page->trackChange('images'); $page->save(); Avoid calling $page->images->remove() just because that will queue an actual file to be removed when the page is saved. Another way you might accomplish reversing the order: $myImages = new Pageimages($page); foreach($page->images as $image) { $myImages->prepend($image); } $page->images = $myImages; $page->save();1 point
-
Almonk, Here's one way you could do it (below), using ProcessWire's WireUpload class: <?php $page->setOutputFormatting(false); // instantiate the class and give it the name of the HTML field $u = new WireUpload('userfile'); // tell it to only accept 1 file $u->setMaxFiles(1); // tell it to rename rather than overwrite existing files $u->setOverwrite(false); // have it put the files in their final destination. this should be okay since // the WireUpload class will only create PW compatible filenames $u->setDestinationPath($page->files->path); // tell it what extensions to expect $u->setValidExtensions('jpg', 'jpeg', 'gif', 'png'); // execute() returns an array, so we'll foreach() it even though only 1 file foreach($u->execute() as $filename) $page->files->add($filename); // save the page $page->save(); Another way to do it would be a more traditional PHP way: <?php $page->setOutputFormatting(false); // we run the $name through $sanitizer to make it PW compatible... // ...this prevents the possibility of it getting renamed on the add() call below $name = strtolower($sanitizer->name($_FILES['userfile']['name'])); // prepend underscores to filename until it's unique... // ...this is just one possible way to handle duplicate filenames while(is_file($page->files->path . $name)) $name = "_" . $name; // validate the file extension $pos = strrpos($name, "."); if(!$pos) throw new WireException("File is missing extension"); $ext = substr($name, $pos+1); if(!in_array($ext, array('jpg', 'jpeg', 'gif', 'png'))) throw new WireException("Invalid extension"); // determine the final destination and store it in $file $file = $page->files->path . $name; // move the file to it's destination using PHP's function if(move_uploaded_file($_FILES['userfile']['tmp_name'], $file)) { // add it to the page $page->files->add($file); /// save the page $page->save(); } Btw, no need to turn outputFormatting back on unless you are rendering parts of that page in the same request. Neither of these examples perform much error checking, which you may want to add. Though the WireUpload class will populate PW's "$notices" API var with any errors: <?php foreach($notices as $notice) { if($notice instanceof NoticeError) { echo "<p>Error: {$notice->text}</p>"; } } If you are using the PW's admin templates, then it already does something like the above snippet.1 point