Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/14/2018 in all areas

  1. Hi, I just want to thank to flydev and everyone else who has contributed to this wonderful module. For me, Duplicator It has worked flawlesly to make backups and bring those backups to my local machine to test new functionality. Sincerely a fellow Processwire developer.
    3 points
  2. I built ProcessWirePageLists a long time ago - it works with Migrator and lets you install the fields and templates (and in some cases pages) for getting started quickly. https://github.com/adrianbj/ProcessWirePageLists The `person.json` file is probably the most relevant to the question you are asking. You could easily build one-click installs of templates/files all sorts of things, like a blog, hotel booking field/templates, news articles, image gallery, ecommerce - whatever really. Maybe I should commit some more myself, but my original plan was to get user contributions to that repo. This is how you "install" them. They are pulled in at runtime directly from Github, so new ones are always available. This is what the JSON looks like for "person": { "templates":[ { "template":"person", "data":{ "useRoles":0, "childrenTemplatesID":0, "sortfield":"", "noChildren":"", "noParents":"", "childTemplates":[ ], "parentTemplates":[ ], "allowPageNum":0, "allowChangeUser":0, "redirectLogin":0, "urlSegments":0, "https":0, "slashUrls":1, "altFilename":"", "guestSearchable":0, "pageClass":"", "pageLabelField":"", "noGlobal":0, "noMove":0, "noTrash":0, "noSettings":0, "noChangeTemplate":0, "noShortcut":0, "noUnpublish":0, "nameContentTab":0, "noCacheGetVars":"", "noCachePostVars":"", "useCacheForUsers":0, "cacheExpire":0, "cacheExpirePages":[ ], "label":"", "tags":"" } } ], "fields":[ { "name":"title", "label":"Title", "description":null, "template":"person", "flags":13, "type":"FieldtypePageTitle", "data":{ "required":1, "textformatters":[ null ], "size":0, "maxlength":255 } }, { "name":"first_name", "label":"First Name", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":50, "size":0, "maxlength":2048 } }, { "name":"last_name", "label":"Last Name", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":50, "size":0, "maxlength":2048 } }, { "name":"portrait", "label":"Portrait", "description":null, "template":"person", "flags":0, "type":"FieldtypeImage", "data":{ "extensions":"gif jpg jpeg png", "maxFiles":1, "inputfieldClass":"InputfieldImage", "descriptionRows":1, "adminThumbs":1, "defaultGrid":0, "fileSchema":2 } }, { "name":"position", "label":"Position", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":50, "size":0, "maxlength":2048 } }, { "name":"department", "label":"Department", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":50, "size":0, "maxlength":2048 } }, { "name":"email", "label":"E-Mail Address", "description":null, "template":"person", "flags":9, "type":"FieldtypeEmail", "data":{ "size":70, "maxlength":255, "columnWidth":50 } }, { "name":"website", "label":"Web site", "description":null, "template":"person", "flags":0, "type":"FieldtypeURL", "data":{ "noRelative":0, "addRoot":0, "columnWidth":50, "size":0, "maxlength":1024 } }, { "name":"phone", "label":"Phone", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":33, "size":0, "maxlength":2048 } }, { "name":"mobile", "label":"Mobile Phone", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":34, "size":0, "maxlength":2048 } }, { "name":"fax", "label":"Fax", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":33, "size":0, "maxlength":2048 } }, { "name":"po_box", "label":"PO Box", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":50, "size":0, "maxlength":2048 } }, { "name":"address_1", "label":"Address", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":50, "size":0, "maxlength":2048 } }, { "name":"address_2", "label":"Address", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "size":0, "maxlength":2048 } }, { "name":"city", "label":"City", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":33, "size":0, "maxlength":2048 } }, { "name":"state", "label":"State", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":34, "size":0, "maxlength":2048 } }, { "name":"country", "label":"Country", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":33, "size":0, "maxlength":2048 } }, { "name":"skype", "label":"Skype", "description":null, "template":"person", "flags":0, "type":"FieldtypeText", "data":{ "columnWidth":33, "size":0, "maxlength":2048 } }, { "name":"twitter", "label":"Twitter", "description":null, "template":"person", "flags":0, "type":"FieldtypeURL", "data":{ "noRelative":0, "addRoot":0, "columnWidth":34, "size":0, "maxlength":1024 } }, { "name":"facebook", "label":"Facebook", "description":null, "template":"person", "flags":0, "type":"FieldtypeURL", "data":{ "noRelative":0, "addRoot":0, "columnWidth":33, "size":0, "maxlength":1024 } } ] }
    3 points
  3. That's an amazing list of 2017's features. Seeing them in a single place makes you appreciate how lucky we and our clients are. Thanks for another incredible year of updates. I imagine everyone's wish list is different. This is what I'd like to see natively in PW. I know some of these are already available as Modules so no offence if you're reading this and have already put tons of work into creating something similar. Processwire Multi-Admin A Processwire dashboard which allows me to monitor multiple installs across different servers. This dashboard would list my installs, version number, and display available upgrades (Module and Core) and allow me to update above from central place. It might show me logged in user(s), uptime etc. Media Manager A built in MM which acts as a single place to manage all uploads. Using the MM you can find, list and edit any uploaded file/image. and its versions. Add tags, crop, delete, rename, copy, bulk upload etc Furthermore the MM should work with user permissions so a MM for me might list different assets than an editor etc Importantly, the look of the MM would be consistent with what's already in place and the new UI Kit theme. SEO A native SEO Module that is maintained and updated as modern SEO evolves. Image Cropping Pre-set image crops and a way to define and manage them. That's it :-/
    2 points
  4. I have a site for an orchestra. I would like to keep track of the players participating each concert. The players are kept as users in processwire. Each player has a default instrument as a user-field, violin, bass, flute etc. But some players play multiple instruments. Each concert has a page in PW. The players for a concert would be selected from a list of users. The list would then be used for sending email to the players of that concert and keep track of the players salaries etc. This would be easy to accomplish with Page references and ASMselect to the users-pages. BUT because the user might have an other instrument from his/her default instrument in one particular concert, I have to keep track of both the user and the instrument in that concert he plays. How would you do this? Make a repeater for the players of the concert and change the instrument for the player in the repeater? PageTable? Some other fieldtype that I don't know or remember? How to make a nice interface for selecting the players and attaching them to correct instruments?
    1 point
  5. If you're not comfortable doing this manually, take a look at this action in the AdminActions module: Copy Content to Other Field This action copies the content from one field to another field on all pages that use the selected template. This can be useful if you decide you need to split one field into two to allow different settings on different templates. It also makes it easy to move content from one field type to another one that is incompatible.
    1 point
  6. Hi @Juergen - it's all about output formatting. It is off by default when bootstrapping. So just do this: $p = $pages->get(n); $p->of(true); $p->fieldname->formattedNumber // OR $p->fieldname Remember that calling $p->fieldname will actually return a formatted version by default - you don't need to explicitly specify ->formattedNumber If you don't want to turn on output formatting for the entire response, you can also use PW's getFormatted like this: $p->getFormatted('fieldname');
    1 point
  7. For each field that you want to change to CKEditor, add a new CKEditor field to the template. Then use the API to set the formatted value of the textarea field to the CKEditor field. When you have done the API operations and checked that everything is okay you can delete the old textarea field. See here:
    1 point
  8. Filling the bounding box is the standard behaviour for the size() method. $image->size(300, 200); For fit, I think it's a not a good idea to add background colour to the canvas. Better to use maxSize(), or size() with cropping set to false, and then center the image within the bounding box with CSS. But if you want to add a background colour you can do this with the canvas() method of Page Image Manipulator.
    1 point
  9. You will need to use a repeating field type "Players" for the players. For me, the order of preference in terms of UI would be: 1. ProFields Table 2. Repeater 3. PageTable Within each item of Players you have two Page Reference fields - one for Player and one for Instrument. The safest thing would be to specify the instrument for every player in the Players field. But if the default instrument of a player is something that is fixed once selected (i.e. a player never changes their default instrument) then you could consider including the default instrument within the "Custom page label format" of the Player field. Then the instrument field could be named "Instrument override" and you only set it if the player is performing with something other than their default instrument. This would make it a quicker process to add players to a concert.
    1 point
  10. FYI... There is also a discussion around focal point image cropping https://github.com/processwire/processwire-requests/issues/150 if anyone is interested.
    1 point
  11. Hi @Antonio Iorio, Regarding where to place your ads, is dependant on the ad itself. For example, a creative with wide dimensions doesn't fit in a sidebar. When I wrote the ad manager plugin fo wp many years ago, I referenced the IAB Standards for ad sizes. In your screenshot you will notice a Leaderboard 728x90 type ad. This ad is designed to display in one of three locations (I used the term zone in my plugin). This banner should be placed in the header and or footer of your page, or even between two separate sections of body content. The <script> section of your screenshot is apparently how altervista wants you to include the ads. You would simply edit your PW templates and include that script at the location you want the ad to appear. You repeat that process for all the ads you want to present. One note of caution. While ads can be a good means to generate a small income, you should use them sparingly. No user wants to weed through a bunch of ads in order to continue reading your content. So I would keep with the old axiom, less is more. I hope this helps. Let us know if you have any further questions.
    1 point
  12. > I'd really like to build these out if we can get some community contributions. Gotcha. I look forward to exploring that space over the coming weeks. This is for a volunteer project that has nothing to do w/ my day job, hence my wanting some prefabs if possible. I like the component-based approach you're describing. To be continued...
    1 point
  13. Yeah, Site Profiles are nice, but what I like about my poorly named "Page Lists" is that they can be applied one-by-one as components as needed and also added to a site after initial PW install. I'd really like to build these out if we can get some community contributions.
    1 point
  14. HI @lickny2001 Try to use "insertAfter" method https://processwire.com/api/ref/wire-array/insert-after/
    1 point
  15. To give a status: I got it working I need to do some clean up and then I can provide it. @BrendonKoz Should I make a pull request to your code or to the original one?
    1 point
  16. You will end up with a PHP function (written by @mindplay.dk) ,two templates and pages which will define your menu. I will write the tutorial a bit later in the afternoon.
    1 point
  17. It sounds like one of the factors that determines which roadmap items get attention first is the level of interest within the community (makes sense). But it would be good to have a more accurate and transparent gauge of the interest in each roadmap item. A simple solution would be to have an official Roadmap sub-forum with a topic for each roadmap item (separate from the Wishlist sub-forum). The community could then indicate their interest in each item by "liking" it, and give feedback or ideas about implementation in topic replies. My vote for most desirable roadmap item: Add support for custom properties in file/image fields.
    1 point
  18. The page export process should sort by the number of segments in the path to each page so that when you import they will be created in the correct order. At least that is how I handle it in Migrator: https://github.com/adrianbj/ProcessMigrator/blob/eaf8255aded36033bcd468c59b235b9a0eb6b785/ProcessMigrator.module#L379-L387 This sounds like a bug to report on Github.
    1 point
  19. $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if(!$page->id) return; // Page ID is 0 when page is first created // Your code here });
    1 point
  20. You mean JSON? Or Serialized array? Here are a couple of posts (not all may be directly relevant in your case, though).
    1 point
  21. this should work : $field = $fields->get('comments'); $comments = $field->type->find($field, "sort=-created");
    1 point
  22. Thanks for the info on this thread, it's appreciated greatly. I'm moving forward on this now, the composition example makes sense to me. I'm at this stage: <?php namespace ProcessWire; class FormChecker { // 3rd party validator object private $validator; public function __construct($validator) { $this->validator = $validator; } public function checkForm() { return $this->validator->validate(); } public function checkField($name) { return $this->validator->errors($name); } } // require Valitron class require_once("./vendor/vlucas/valitron/src/Valitron/Validator.php"); // get sanitized POST values $name = $sanitizer->text($input->post->name); $email = $sanitizer->email($input->post->email); $message = $sanitizer->textarea($input->post->message); // create new valitron $v = new \Valitron\Validator(array( "name" => $name, "email" => $email, "message" => $message ) ); // create valitron rules $v->rule("required", ["name", "email", "message"]); $v->rule("email", "email"); // save as property on new $checker object $checker = new FormChecker($v); // has form been submitted? $isSubmitted = $input->post->sendMe; // does form validate after submission $formValidates = $checker->checkForm(); $result = ($isSubmitted && $formValidates) ? "SUCCESS" : "FAIL"; echo "Form validation was a: " . $result; ?> <div id="form-top" class="mb-5"></div> <h2>Send me a message</h2> <form id="contact-form" method="post" action="#form-top"> <div class="row"> <div class="form-group col-sm-12 col-lg-6 py-2 <?= $checker->checkField('name') ? 'has-danger' : ''?>"> <label for="name">Name (required)</label> <input class="form-control" name="name" id="name" type="text" value="<?php if ($name) echo $name; ?>"> </div> <div class="form-group col-sm-12 col-lg-6 py-2 <?= $checker->checkField('email') ? 'has-danger' : ''?>"> <label for="email">Email (required)</label> <input class="form-control" name="email" id="email" type="text" value="<?php if ($email) echo $email; ?>"> </div> </div> <div class="form-group py-2 <?= $checker->checkField('message') ? 'has-danger' : ''?>"> <label for="message">Message (required)</label> <textarea class="form-control" name="message" id="message" rows="8"><?php if ($message) echo $message; ?></textarea> </div> <div> <label for="recaptcha">Recaptcha (required)</label> <!-- Google Recaptcha code START --> <?php // echo $captcha->render(); ?> <!-- Google Recaptcha code END --> </div> <div class="form-group"> <button type="submit" class="btn btn-primary" name="sendMe" value="1">Message me!</button> </div> </form> And behold, so far so good! Excitement levels rising now, I like where this is heading. Gonna get my feedback messages in there now.
    1 point
  23. Welcome to the forums @Schwab Have a read here about WireArrays. A multi page field returns a PageArray (which is derived from a WireArray). http://processwire.com/api/ref/page-array/ http://processwire.com/api/ref/page-array/add/ http://processwire.com/api/ref/wire-array/ http://processwire.com/api/ref/wire-array/add/ Examples // examples $someOtherPage = $pages->get(1234); $page->your_page_field = $someOtherPage;// @note: not sure it works in all contexts $page->your_page_field->add($someOtherPage); $page->your_page_field->add(1234); // Add multiple pages $page->your_page_field->add($pages->find("template=basic-page"));
    1 point
  24. You're both right, I'm gonna try a class, my code is just getting ridiculous now lol, seems miles worse than my original one. <?php namespace ProcessWire; function generateFlashMessage($isValidated, $recaptchaResponse, $session, $feedback, $feedbackEmptyArr) { $str = ""; if (!$isValidated) { array_push($feedbackEmptyArr, $feedback["errorValidation"]); } if (!$recaptchaResponse) { array_push($feedbackEmptyArr, $feedback["errorRecaptcha"]); } if ($isValidated && $recaptchaResponse) { if (!$session->sent) { array_push($feedbackEmptyArr, $feedback["errorSend"]); } else { array_push($feedbackEmptyArr, $feedback["success"]); } } if (count($feedbackEmptyArr)) { $str = '<ul class="mb-0">'; foreach ($feedbackEmptyArr as $value) { $str .= '<li>' . $value . '</li>'; } $str .= '<ul>'; } return $str; } function createMessage($name, $email, $message) { $msg = " <html> <body> <p><b>Name:</b> {$name}</p> <p><b>Email:</b> {$email}</p> <p><b>Message:</b></p> <p>{$message}</p> </body> </html> "; return $msg; } function sendMail($contactFormRecipient, $name, $email, $message) { $mail = wireMail(); $mail->to($contactFormRecipient) ->from($email, $name) ->subject('Email from website...') ->bodyHTML($message); return $mail->send(); } function checkField($name, $v, $isSubmitted) { if($isSubmitted) { return $v->errors($name); } } wireIncludeFile("./vendor/vlucas/valitron/src/Valitron/Validator.php"); $captcha = $modules->get("MarkupGoogleRecaptcha"); $contactFormRecipient = "EMAIL_RECIPIENT"; $isSubmitted = $input->post->sendMe; $feedbackEmptyArr = []; $session->flashMessage = $feedbackEmptyArr; $feedback = [ "errorSend" => "Sorry, an error occured. Please try again.", "errorValidation" => "Please fill out the fields correctly.", "errorRecaptcha" => "Recaptcha must be complete.", "success" => "Thanks for your message!" ]; $name = $sanitizer->text($input->post->name); $email = $sanitizer->email($input->post->email); $message = $sanitizer->textarea($input->post->message); $v = new \Valitron\Validator(array( "name" => $name, "email" => $email, "message" => $message ) ); $v->rule("required", ["name", "email", "message"]); $v->rule("email", "email"); // validate form - true/false $isValidated = $v->validate(); // verify recaptcha - true/false $recaptchaResponse = $captcha->verifyResponse(); // if form is submitted if($isSubmitted) { if ($isValidated && $recaptchaResponse) { $msg = createMessage($name, $email, $message); sendMail($contactFormRecipient, $name, $email, $msg); $session->sent = true; } } ?> <div id="form-top" class="mb-5"></div> <h2>Send me a message</h2> <?php if($isSubmitted):?> <div class="alert <?php echo $session->sent ? 'alert-success' : 'alert-danger'?>" role="alert"> <?= generateFlashMessage($isValidated, $recaptchaResponse, $session, $feedback, $feedbackEmptyArr); ?> </div> <?php endif;?> <form id="contact-form" method="post" action="#form-top"> <div class="row"> <div class="form-group col-sm-12 col-lg-6 py-2 <?= checkField('name', $v, $isSubmitted) ? 'has-danger' : ''?>"> <label for="name">Name (required)</label> <input class="form-control" name="name" id="name" type="text" value="<?php if ($name) echo $name; ?>"> </div> <div class="form-group col-sm-12 col-lg-6 py-2 <?= checkField('email', $v, $isSubmitted) ? 'has-danger' : ''?>"> <label for="email">Email (required)</label> <input class="form-control" name="email" id="email" type="text" value="<?php if ($email) echo $email; ?>"> </div> </div> <div class="form-group py-2 <?= checkField('message', $v, $isSubmitted) ? 'has-danger' : ''?>"> <label for="message">Message (required)</label> <textarea class="form-control" name="message" id="message" rows="8"><?php if ($message) echo $message; ?></textarea> </div> <div> <label for="recaptcha">Recaptcha (required)</label> <!-- Google Recaptcha code START --> <?php echo $captcha->render(); ?> <!-- Google Recaptcha code END --> </div> <div class="form-group"> <button type="submit" class="btn btn-primary" name="sendMe" value="1">Submit suggestion</button> </div> </form> <?php $session->remove("flashMessage"); $session->sent = false; echo $captcha->getScript(); ?> It's one of those time where I learn best... by seeing how not to do something! I still got some ways to go here methinks. Terrible code, great learning experience. This will for sure be one of those posts that I look back on and laugh. On a plus note, it works (and I'm actually writing code and thinking about structure now which is awesome)
    1 point
  25. I fixed the problem now after checking all modules. The website was intended to be multilingual, so i prepared all the fields to be multilingual (text, textarea, url). After the launch of the site the multilingual feature wasn't needed anymore, so i deleted the second language but forgot to reset all the fields to be not multingual. In 3.0.84 i had no problems, in 3.0.85 i get errors. But it now runs as it should on 3.0.88
    1 point
  26. PwCron is not required anymore, you can set your job calling directly site/modules/Duplicator/cron.php https://github.com/flydev-fr/Duplicator#system-cron
    1 point
  27. I have used Repeater Matrix for this purpose, to create a type of page builder, each repeater type being a possible section, though you still have to have a predefined set of repeater types, most of this types have a checkbox or two for customization of behaviour (even repeaters inside, works wonderful)
    1 point
  28. This is something that I've been trying to figure out for quite awhile. At the moment I do this: 1) Create template banner-index 2) Create template banner-entry 3) Create page 'Banners' using banner-index template 4) Create child page of whatever the banner will be, let's say 'Sounds good'. So you now have: ... and the template for 'Sounds good': (link to page is a Page type which enables me to pick ANY page on the site with a PageListSelect+ as input field type and 'Home' set as parent) So I create a file which is going to output the actual banner: // includes/_banner.php <?php namespace ProcessWire; // get the banner page determined by the id passed to this template // from wireIncludeFile additional array, see next snippet $banner = $pages->get($Id); ?> <div class="jumbotron jumbotron-fluid py-6 text-center bg-repeat"> <div class="container"> <h2 class="display-4"><?= $banner->headingMain; ?></h2> <p class="lead"><?= $banner->headingSubtitle; ?></p> <a href='<?= $banner->linkToInternalPage->url; ?>' class='btn btn-primary'>Go to <?= $banner->linkToInternalPage->title; ?></a> </div> </div> ...then I grab this file using 'wireIncludeFile' so I can pass an additional value into this template which is the id of the page: // views/about.php <?php wireIncludeFile('./includes/_banner', array('Id' => 1212)); ?> So the page id of 'Sounds good' is '1212'. I pass this manually at the moment. So now, when /about/ is viewed, it displays '_banner.php' wherever I want, where you can see the PHP is populated with values from the 'Sounds good' page: So, what about making this a bit more dynamic instead of manual IDs in a template. Create a new field 'bannerToDisplay' as a 'Page' field type: ...then select it to return just a single page: ...and choose the parent of selectable pages to be the 'Banners' page you made earlier using the 'banners-index' template with an input field type of 'Select': ...go add this bad boy to a template! ...then go edit your page: ...choose a banner, save it. Go edit the code which renders '_banners.php' and get rid of that manual ID: // views/about.php <?php // if something has been selected from the 'Choose a banner' dropdown if ($page->bannerToDisplay) { // get the ID of the selected page $bannerPageId = $page->bannerToDisplay->id; // pass this ID to the _banner.php template wireIncludeFile('./includes/_banner', array('Id' => $bannerPageId)); } ?> ...create another banner and then change the dropdown and refresh the page! This is obviously just an example which enables adding of a single block but once you get the idea of the Page field type and how you could use it, your options will increase a fair bit. The thing I found with repeaters is that you still can't add a content block above, say , a body field, then another one below it. Your template would literally just have to have the repeater on it and you add item after item. Of course, with a repeater, every item will be the same (defined once, then just repeated with alternative content in the same field types). I'm going to try the pro fields repeater matrix next for something similar. I'd love to be able to make entire pages simply from blocks and to be able to drag them around. It takes a fair bit of forethought though. Just experiment, have fun! NOTE: This still means you have to define WHERE the banner will go on the page via a template, but you can change WHICH banner to display on the page edit inside admin it doesn't solve your problem but hopefully helps a bit and gets you on your way. Good luck!
    1 point
  29. Has anyone here a recommendation on a simple fulltext search library in javascript? I've ~30 FAQ item that should be searchable, but somehow all the libraries I've tried are missing even fullword hits at times. Either they are to fancy and miss those basic hits or they are to simple and have a hard time with fuzzy search terms. Tried out libs: lunr.js fuzzy.js elasticlunr.js fuze.js fuzzyset.js
    1 point
×
×
  • Create New...