Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/11/2017 in all areas

  1. I like to showcase my new website acniti on the forum here. History Building and managing a website is a hobby, over the years, making websites got more complicated and more technologies, knowledge and wisdom are required. I started building my first website around 1997. It started out with a static site built with FrontPage, a WYSIWYG HTML editor. A few years later it was time for the first content management system, I looked at Joomla but settled for MediaWiki. I run those websites for 2 years on the MediaWiki platform and then moved on to WordPress. WordPress was good, it did a good job but over time, it became more complicated to make something out of the box, if it's not a blog, it becomes complicated and to have a feature rich website requires a lot of plugins. Little by little it became less fun and more and more hassle juggling the various plugins. In 2014 I became interested in learning PHP programming, I wanted to do this already for many years, but never had enough time to bite the bullet and work my way through the basics. At the end of the courses I though and now what have I learned, how to put this into action? To built modern website with PHP only is difficult, it also requires knowledge of html, MySQL, CSS, java-script etc. I started looking for a framework experimented a little with CakePHP and then came across Processwire via a CMS Critic blog post. Development setup I developed the acniti website on a Linux Ubuntu 16, with PHP 7 and MySQL as the development server. For the IDE I use PhpStorm, before using Storm I have used and tried some other IDE's such as Zend, Eclipse, Netbeans, Aptana but none of them I liked, some were feature poor, Zend and Eclipse were slow and use a lot of memory. PhpStorm not free but definitely worth the investment. I make use of the free tier Git repository of AWS called CodeCommit, I still use GIT Cola to commit the changes, I could also use PhpStorm for this but I never took the time to change my workflow. For project management I am a big fan of Redmine, Redmine is a web-based open-source project management and issue tracking tool. I use this also for my other work so it easily integrates with the website building flow as well. It's easy for maintaining lists of features you want to carry out per version, it supports a wiki which is easy for making notes and keeping a log of the activities. I use it everyday and it runs on Ruby. For images and graphics I switch back to Windows for some Photoshop. Processwire The acniti website runs on the latest stable Processwire version at the time of writing 3.0.62, the website has 4 languages including an Asian language. The Japanese language URL's are implemented with their 3 alphabets kanji, hiragana, katakana i.e. https://www.acniti.com/ja/インレットフィルタ. Some images on the site have text and image language tags help to select the correct language, the Processwire blog post from 30 June was helpful to get this running. The main site has a bootstrap theme, for the mobile version of the site the google AMP specification is implemented. This was really fun to do but challenging at times as the AMP specification is still a little limited. To visit the AMP pages type /amp/ behind any URL like https://www.acniti.com/amp/ for the homepage. The Google webmaster portal is really easy to troubleshoot and check for the correct AMP implementation. Finally structured data according to schema.org is added to the site via the JSON-LD markup. The commercial modules ProCache and Formbuilder are installed. The ProCache module is really amazing and makes the website lightning fast. Besides the commercial modules around eleven open-source modules are used, Database Backups, Tracy Debugger, Wire Mail SMTP, Protected Mode, Batcher, Upgrades, PublishAsHidden, URL (Multi-language), Twitter Feed Markup, Email Obfuscation (EMO), Login History, Selector test. During development the Processwire forum is really helpful and checked often. The forum is good for two reasons, most of the questions, I had during development of the site, are already on the site. Secondly the only 6 questions I posted over the last 2 years, are quickly and accurately answered. The downside I didn't become a very active member on the forum but see that as a compliment. An open issue on the acniti site is the AMP contact form with Formbuilder, the restricted usage of java-script for the AMP specification requires some more in-depth study. Hosting setup For the hosting services the acniti site uses Amazon EC2, I use AWS already many years to manage my cloud office so it was easy to decide to use it for the web hosting as well. The site is running on a micro instance of EC2 and with the ProCache module CloudFront is serving webpages worldwide fast. Updates from the development server are sent to CodeCommit and from there to the production server. From a site management point of view it would be nice to use AWS RDS to manage the MySQL databases, but from a cost perspective I decide not to do that for now. Via a cron I have set up automatic MySQL backups and these are via another cron job uploaded to AWS S3. To make sure the server is safe, a cron job runs daily snapshots of the server, this is getting initiated via AWS Lambda. Lambda also removes older snapshots because during creation a delete tag is attached for sevens days after their creation. It's important to make a separate MySQL backup as with snapshots the database often gets corrupted and its easier to restore a database backup than to fix a corrupted database. Another nice feature to use AWS Lambda for is a simple HTTP service health checker, which reports to you by email or sms when the website is down. Making use of all these Amazon services cost me probably somewhere between 10 - 15 $ a month, I have to estimate a little since I am running a lot more things on AWS than only the website. The site is running on a Comodo SSL certificate but next year I will change to the free LetsEncrypt, as it is easier to add and will automatically renew after 90 days. The Comodo certificate requires manually copy pasting and editing the certificates in place. Writing Content The content for the site I write in the Redmine wiki, most of the content I write requires research and it takes about two weeks before I publish the content to the Processwire site. For writing content I use the google spell checker with the grammar checker, After the Deadline. To ensure catchy headlines they are optimized with the Headline Analyzer from CoSchedule Social Media Now the site is running, it needs promotion. The robots.txt files shows the search engines the way as does the sitemap.xml both of these I have made in a template file. Most of the blog articles I promote are republished on social networks like, LinkedIn, Tumblr, Google+, Twitter, and some branch specific networks as the Waternetwork and Environmental XPRT. To check, the search engines index the site well, Google webmaster and Bing webmaster check for any problems with the site. For statics on the same server there is an instance installed of Piwik. Piwik is a leading open alternative to Google Analytics that gives full control over data. The Piwik setup works very well and gives a good overview of the site usage both on the desktop via the site or via a mobile app. As a part of a test I have installed the open-source SEO-panel on the same server to manage keywords and to further improve the scores in the search engine, a nice feature is that you can also track your competitors. I am still new to SEO panel and have to learn more how to use the tool effectively.
    13 points
  2. This week we added the new pages export/import feature to the core! In this post, we tell you how to install it and cover all of the new things added over the last week. https://processwire.com/blog/posts/processwire-3.0.71-adds-new-core-module/
    6 points
  3. Here are some starters: Hook into InputfieldFile::render method to add (modify $event->return and concatenate html string) an anchor link with its href set to a custom template/PHP file where you build your own zip file. (Preferentially, add a form with a download button and a hidden field for current page id etc and set its action attribute to the template file) Inside the template file, you'll get the page id from $input->post then build your zip file foreach($page->files_field as $name => $file) { $filePath = $file->path // ... } Use $files->zip() method to zip multiple files https://processwire.com/api/ref/files/zip/ or (from /wire/core/WireFileTools.php) // Create zip of all files in directory $dir to file $zip $dir = $config->paths->cache . "my-files/"; $zip = $config->paths->cache . "my-file.zip"; $result = $files->zip($zip, $dir); echo "<h3>These files were added to the ZIP:</h3>"; foreach($result['files'] as $file) { echo "<li>" $sanitizer->entities($file) . "</li>"; } if(count($result['errors'])) { echo "<h3>There were errors:</h3>"; foreach($result['errors'] as $error) { echo "<li>" . $sanitizer->entities($error) . "</li>"; } } and build your zip file Once the zip file is built force browser to download https://stackoverflow.com/a/1628281 If you have any questions, ask away
    3 points
  4. I think perhaps I am not understanding what you are looking for, but does this suit your needs? foreach($page->my_repeater as $item) { foreach($item->fields as $field) { echo $item->{$field->name}; } }
    2 points
  5. Under Edit field > Input > CKEditor Settings > CKEditor toolbar, you need to add the button: A11ychecker Save, then you should see the new button
    2 points
  6. Hi @homma, Someone posted a solution in github. I tested it and it works fine. The downside is that you have to modify the core of ProcessWire which mean you have to do it again every time you upgrade your core. https://github.com/processwire/processwire-requests/issues/56#issuecomment-263669255 Gideon
    2 points
  7. Have you tried serving file with PHP instead of just linking it? You can change the filename using HTTP headers this way https://stackoverflow.com/a/1628281
    2 points
  8. @Zeka - that's correct - it is only for one branch. To restrict to more than one is a more complex task. Here are a couple of gists that will get you going: https://gist.github.com/adrianbj/e391e2e343c5620d0720 https://gist.github.com/adrianbj/6fd1b770d9ce7a7252b6 Remember there are lots of things that AdminRestrictBranch takes cares of that you will need to consider like adjusting breadcrumbs, admin search results, the Pages > Tree menu, etc if you choose to start with one of these gists. The biggest issue with the "HideUneditablePages" gist module is if an editable page has an uneditable parent - how should that be handled? Anyway, hope one of them gets you going. This is the thread that led to those gist modules:
    2 points
  9. PHP writes its session data to a file by default, so does ProcessWire. So when ProcessWire starts executing a process the session starts and the session gets locked. After the process is completed the session unlocks and we are able to use ProcessWire again. For normal scripts this is oké. But when you have long running processes like importing big data or you want to create a responsive AJAX API, this can be a real bottleneck. You see this 'issue' for example with ImportPagesCSV where the admin 'freezes' while importing. 1 Dirty way to avoid session lock for big data import is to remove all sessions after you have started the import script. But this will log you out from the admin. An other way could be to use exec() and send the output to /dev/null. (Running the script in background) How do you guys deal with these session locks ?
    1 point
  10. One of PW 3.010's major novelty was the introduction of Horst's new image resizing engine that uses ImageMagick. Now I understand that ImageMagick can convert images to Webp, the image format that Google says can reduce image size up to 34% compared to JPEG. Mozilla is apparently adding support to Firefox, and even the Safari team is playing with it, so it looks like Webp is soon going to be available in most major browsers. If Horst's module can be extended to add Webp conversion, that would be a great addition to PW's already very powerful image manipulation arsenal. I'm currently using the free ImageEngine Lite to serve Webp images to supporting browsers, and the results are impressive. I routinely get images that are between 25 and 60% smaller compared to JPEG, with the same visual quality. I would love to eliminate the need to rely on a third-party service though.
    1 point
  11. OAuth2Login for ProcessWire A Module which give you ability to login an existing user using your favorite thrid-party OAuth2 provider (i.e. Facebook, GitHub, Google, LinkedIn, etc.).. You can login from the backend to the backend directly or render a form on the frontend and redirect the user to a choosen page. Built on top of ThePhpLeague OAuth2-Client lib. Registration is not handled by this module but planned. Howto Install Install the module following this procedure: - http://modules.processwire.com/modules/oauth2-login/ - https://github.com/flydev-fr/OAuth2Login Next step, in order to use a provider, you need to use Composer to install each provider ie: to install Google, open a terminal, go to your root directory of pw and type the following command-line: composer require league/oauth2-google Tested providers/packages : Google : league/oauth2-google Facebook: league/oauth2-facebook Github: league/oauth2-github LinkedIn: league/oauth2-linkedin More third-party providers are available there. You should be able to add a provider by simply adding it to the JSON config file. Howto Use It First (and for testing purpose), you should create a new user in ProcessWire that reflect your real OAuth2 account information. The important informations are, Last Name, First Name and Email. The module will compare existing users by firstname, lastname and email; If the user match the informations, then he is logged in. ie, if my Google fullname is John Wick, then in ProcessWire, I create a new user Wick-John with email johnwick@mydomain.com Next step, go to your favorite provider and create an app in order to get the ClientId and ClientSecret keys. Ask on the forum if you have difficulties getting there. Once you got the keys for a provider, just paste it into the module settings and save it. One or more button should appear bellow the standard login form. The final step is to make your JSON configuration file. In this sample, the JSON config include all tested providers, you can of course edit it to suit your needs : { "providers": { "google": { "className": "Google", "packageName": "league/oauth2-google", "helpUrl": "https://console.developers.google.com/apis/credentials" }, "facebook": { "className": "Facebook", "packageName": "league/oauth2-facebook", "helpUrl": "https://developers.facebook.com/apps/", "options": { "graphApiVersion": "v2.10", "scope": "email" } }, "github": { "className": "Github", "packageName": "league/oauth2-github", "helpUrl": "https://github.com/settings/developers", "options": { "scope": "user:email" } }, "linkedin": { "className": "LinkedIn", "packageName": "league/oauth2-linkedin", "helpUrl": "https://www.linkedin.com/secure/developer" } } } Backend Usage In ready.php, call the module : if($page->template == 'admin') { $oauth2mod = $modules->get('Oauth2Login'); if($oauth2mod) $oauth2mod->hookBackend(); } Frontend Usage Small note: At this moment the render method is pretty simple. It output a InputfieldForm with InputfieldSubmit(s) into wrapped in a ul:li tag. Feedbacks and ideas welcome! For the following example, I created a page login and a template login which contain the following code : <?php namespace ProcessWire; if(!$user->isLoggedin()) { $options = array( 'buttonClass' => 'my_button_class', 'buttonValue' => 'Login with {provider}', // {{provider}} keyword 'prependMarkup' => '<div class="wrapper">', 'appendMarkup' => '</div>' ); $redirectUri = str_lreplace('//', '/', $config->urls->httpRoot . $page->url); $content = $modules->get('Oauth2Login')->config( array( 'redirect_uri' => $redirectUri, 'success_uri' => $page->url ) )->render($options); } The custom function lstr_replace() : /* * replace the last occurence of $search by $replace in $subject */ function str_lreplace($search, $replace, $subject) { return preg_replace('~(.*)' . preg_quote($search, '~') . '~', '$1' . $replace, $subject, 1); } Screenshot
    1 point
  12. In page-edit mode, it would be nice to have an optional download-button for inputfield type file. i.e. when a user has uploaded two dozen files (perhaps through the frontend), and someone else needs to download these from the backend all at once, without having to open an FTP client. There would simply be a download link / button, and a ZIP would be generated on the fly, containing all files. If someone has an idea how to do that (a hook?), I'd be all ears
    1 point
  13. Right, gotcha. Actually, this module is not installable either despite the requires property being consistent with the module documentation. So I think it's an issue with ProcessModule and/or the Modules directory JSON generator and it should be reported to Ryan.
    1 point
  14. @homma - here is some reading on this issue: https://github.com/processwire/processwire-requests/issues/56 (sorry, @Gideon So already linked to this)
    1 point
  15. I've never tried setting the module info conditionally like that (or the external info.php approach), but it looks like it should work. Tracy should help here to check the resulting $info array.
    1 point
  16. 1 point
  17. Thanks abdus! I guess I was unclear of how to add to the find() in processwire. However, knowing this now, this really helps me condense a lot of my code that I have already written. My head was starting to spin trying to figure out ways (sometimes it was a roller coaster) to deal with my foreachs.
    1 point
  18. You can use AND operator for that. https://processwire.com/api/selectors/#and-selectors <?php $today = new \DateTime(); // set to now $inFiveDays = $today->modify('+5 days'); $tsToday = $today->getTimestamp(); $tsInFiveDays = $inFiveDays->getTimestamp(); // selectors are built in the order: field<operator>value // repeat a field for AND operation $ads = $pages->find("parent.template=manufacturer, expiration_date>=$tsToday, expiration_date<=$tsInFiveDays, sort=expiration_date");
    1 point
  19. Glad it works now! Good luck with the further development of your website!
    1 point
  20. My original code: $m->to($contactFormRecipient) ->from($email) ->subject('Contact form submission') ->bodyHTML($message) ->send(); // SEND #1 if ($m->send()) { // SEND #2 I totally didn't notice the parenthesis in the if block. Doh! It sends the mail, then returns true/false presumably. You were right in your first reply. Thanks @Harmen All working now Full code here (bootstrap 4 alpha 6): <?php namespace ProcessWire; wireIncludeFile("./vendor/vlucas/valitron/src/Valitron/Validator.php"); $captcha = $modules->get("MarkupGoogleRecaptcha"); $contactPageID = '1020'; $contactFormRecipient = 'MY_EMAIL_ADDRESS'; $name = $sanitizer->text($input->post->name); $email = $sanitizer->email($input->post->email); $message = $sanitizer->text($input->post->message); $v = new \Valitron\Validator(array( 'name' => $name, 'email' => $email, 'message' => $message ) ); $v->rule('required', ['name', 'email', 'message']); $v->rule('email', 'email'); if ($input->post->sendMe) { if ($v->validate()) { if ($captcha->verifyResponse() === true) { $message = " <html> <body> <p><b>From:</b></p> <p>{$name}</p> <p><b>Email:</b></p> <p>{$email}</p> <p><b>Message:</b></p> <p>{$message}</p> </body> </html> "; $mail = wireMail(); $mail->to($contactFormRecipient) ->header('Reply-To', $email) ->subject('JS Electrician form submission') ->bodyHTML($message); if ($mail->send()) { $session->flashMessage = "<h2>Thank you for your message! I will get back to you shortly.</h2>"; $session->sent = true; $session->redirect($pages->get($contactPageID)->url); } else { $session->flashMessage = "<h2>Sorry, an error occured. Please try again.</h2>"; } } else { $session->flashMessage = '<h2>Recaptcha must be complete.</h2>'; } } else { $session->flashMessage = 'Please fill out the fields correctly.'; } } ?> <div class="container"> <div class="row justify-content-between"> <div class="col-sm-12 col-lg-8 py-3"> <?php if($session->flashMessage):?> <div class="alert <?php echo $session->sent ? 'alert-success' : 'alert-danger'?>" role="alert"> <?php echo $session->flashMessage;?> </div> <?php endif;?> <form id="contact-form" method="post"> <div class="row"> <div class="form-group col-sm-12 col-lg-6 py-2 <?php echo $v->errors('name') ? 'has-danger' : ''?>"> <label for="name">Name (required)</label> <input class="form-control" name="name" id="name" type="text" value="<?php echo $sanitizer->text($input->post->name); ?>"> </div> <div class="form-group col-sm-12 col-lg-6 py-2 <?php echo $v->errors('email') ? 'has-danger' : ''?>"> <label for="email">Email (required)</label> <input class="form-control" name="email" id="email" type="text" value="<?php echo $sanitizer->text($input->post->email); ?>"> </div> </div> <div class="form-group py-2 <?php echo $v->errors('message') ? 'has-danger' : ''?>"> <label for="message">Message (required)</label> <textarea class="form-control" name="message" id="message" rows="8"><?php echo $sanitizer->text($input->post->message); ?></textarea> </div> <div> <!-- 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">Send message</button> </div> </form> </div> <div class="col-sm-12 col-lg-3 py-3"> <h2>Have a question?</h2> <p class="mb-0"><i class="fa fa-phone" aria-hidden="true"></i> <?php if($clientPhone) echo $clientPhone; ?></p> </div> </div> </div> <?php $session->remove('flashMessage'); $session->sent = false; echo $captcha->getScript(); ?>
    1 point
  21. There's also $pages->count(selector) method available. <?php $today = strtotime('today'); // $today = strtotime('now'); is also available // count pages that have expired before today $alertCount = $pages->count("parent.template=client, expiration_date<=$today"); https://processwire.com/api/ref/pages/count/ FYI, you dont have to convert date back and forth, strtotime returns UNIX timestamp, and PW understands it perfectly.
    1 point
  22. Hi, I think if you replace this: $m->to($contactFormRecipient) ->from($email) ->subject('Contact form submission') ->bodyHTML($message) ->send(); with the following: $m->to($contactFormRecipient) ->from($email) ->subject('Contact form submission') ->bodyHTML($message); that it will work and the email will be send one time, that's how my contact form works , I hope this helps you ~ Harmen
    1 point
  23. One thing to make your foreach loop a bit smaller and faster is to move these lines of code (below). Just set them before the foreach loop. As far as I can see you are checking the date for each ad, but it's always the same so it's faster to define it once. $todaysdate = date("F j, Y H:i"); $today = strtotime($todaysdate); So that results in this: $ads = $pages->find("parent.template=client, sort=expiration_date"); // === Get $ads $alert_count = 0; // === Set alert count $todaysdate = date("F j, Y H:i"); // === Get the date $today = strtotime($todaysdate); // === Make a string from the date foreach ($ads as $ad) { // === Start foreach $expireson = $ad->expiration_date; $expires = strtotime($expireson); // === I think you can also shorten this to $expires = strtotime($ad->expiration_date); Maybe you can even try $fiveaway = strtotime($ad->expiration_date) - 432000; $fiveaway = $expires - 432000; if ($today > $expires) { $alert_count += 1; } } // === End Foreach echo $alert_count; // === Echo the counter result Hope this helps...
    1 point
  24. You are not incrementing $alert_count. It should be : $alert_count += 1; // not =+ 1;
    1 point
  25. hi, could be a perfect fit for my Handsontable module: if the headers are always the same you could just set them up in your field settings. the problems with my module are that the field will not be queryable (does that word exist?) and that it is currently not easily possible to add columns to the field lateron since the field settings will change but the data stored in the field will not. if that's no problem for you it could be worth a try @szabesz the datatables module is more for presentation inside the admin, not for input
    1 point
  26. Or better yet, under API & Templates? Some sections have subsections like Modules/Plugins -> Module/Plugin Development It would be great to see: API & Templates - Bootstrap - Zurb Foundation - UIkit - Others
    1 point
  27. Hi @holmescreek Have you already considered taking a closer look at @bernhard's RockDataTables? DataTables supports Complex headers (rowspan and colspan). Should you decide to implement your own module, there is another free package called W2UI which also supports it.
    1 point
  28. And I was sure YOU will ask that ! Sure, I am already trying to get back my Gitlab server. The server was hosted in a VMware guest machine, and when plugged the hdd and put the virtual machine ON, the network simply does not work anymore. Can't ping anything, but I know how to fix it, i am just too lazy those days. Edit: Just to say, I still have the code and used the module in the last days, but it look like its not the Windows compatible version..
    1 point
  29. Or if not I do believe this is put their in readiness by your hosting company that you may wish to. It may even be enabled without you knowing, try going to the https:// version of your site and see what it says.
    1 point
  30. I've been using PW for quite a while, now, so I would like to give back to the community that helped me so many times. I had this customer that wanted to use the Google Translate API to automatically translate the site, so I built this function that takes advantage of it without the need to use the API on every page cycle. I put it on a file that gets called on the _init.php, so that I can use it on every template. Here it is: <?php function googleAutoTranslate($page, $field) { // Turn off outputFormatting $page->of(false); // Get current language and field content for this language $current_language = wire('user')->language->name; $field_content = $page->getLanguageValue($current_language, $field); // Is there any content for this language? if($field_content != '') { // Do nothing! } else { // No content, lets translate... // Get default language text $text = $page->getLanguageValue('default', $field); // Translate only if there's content in the default language if($text != '') { // Translate it $apiKey = 'YOUR API KEY HERE'; $default_language = 'pt'; // Your default language here! $url = 'https://www.googleapis.com/language/translate/v2?key=' . $apiKey .'&q=' . rawurlencode($text) . '&source=' . $default_language . '&target=' . $current_language; $json = json_decode(file_get_contents($url)); $field_content = $json->data->translations[0]->translatedText; // Save translated text $page->$field->setLanguageValue($current_language, $field_content); $page->save(); } } // Turn on outputFormatting $page->of(true); // Return result return $field_content; } ?> Whenever you use a field on a template that should be auto translated, just call the function with a page object and the field name, like so: echo googleAutoTranslate($page, 'body'); Features: Translation occurs only once per field, so you don't need to keep paying translations (it stores the translation into the field language); You can correct the translation in the admin area and it won't be overwritten; If you need the translation to be made again, just delete the field content in the needed language. For the translation to occur, content must exist in the default language. I had to fight a little to get this working, so I hope this helps anyone, who comes across this particular need. Nice Things To Have If someone wants to give it a shot to make this into a module, please do. It would be nice to have a checkbox "Enable Google auto translate for this field", when you edit a field input features. Don't Spend Too Much Mind you that the Google translate is a payed service! and needs a Credit Card to get it going (even with $300 free credit); With a relatively small site (and the tests made to get this to work) I already spent about 80.000 translated characters = $3, Hope this helps someone!
    1 point
  31. Hey guys, hey @baba_mmx I just released a new version of this module on github. I also got a question, as I am planning to take this project under my wing: Should I make a new thread for it and add it to the modules directory? @baba_mmx would that be ok with you? One problem is that if I put it in the ProcessWire Modules directory it does not install it dependencies, as they are installed via composer. How could I handle this? What has been done in the latest release? v0.9.1 made the register form public so you can alter the markup and classes added Foundation classes for the errors and notices. Have to make this configurable added new function showMessage to echo messages and errors login user after successful registration removed automatic redirect enabled autocompletion for the form show either displayName from OAuth or email address after login added the ability to save the last name, first name and gender from OAuth in the user profile. Just add the fields "lastName", "firstName" and "gender" to the user template in ProcessWire
    1 point
  32. Hello friends, I have been using the wireRenderFile() function a lot. Since the inclusion of the wireRenderFile() method I made all my websites using this pattern. This is a medium post that I made explaining it. https://medium.com/@clsource/the-wire-render-pattern-806bf6d6097a?source=featured---------1 All the files will be uploaded here https://github.com/NinjasCL/wire-render-pattern
    1 point
  33. For the pages belonging to an author I think you can use the following selector created_users_id= (as per cheatsheet) so $auth_pages = $pages->find("created_users_id=$userpage->id"); Not tested.
    1 point
  34. With url segments (http://processwire.com/api/variables/input/ scroll to the middle of the page). Allow them on the authors page template, and on this template's file put something like this: if ($input->urlSegment1) { ​$username = sanitizer->name($input->urlSegment1); $userpage = $pages->get(name=​$username, template=user, include=all); if ($userpage->id) { // echo the user info. these would be custom fields added to the "user" template echo "<h2>{$userpage->first_name} {$userpage->last_name}</h2>"; echo "<p>{$userpage->bio}</p>"; } } You can add any info you want to the users pages by adding fields to the "user" template (on the templates page, under "filters", enable "show system templates?") Edit: Wanze beat me again. He beats everyone lately Edit2: corrected my code to make the check for guest visitors that Wanze refered, except that I'm using $pages instead of $users to get the user page
    1 point
  35. Hi patrik, You can use urlSegments for this case. In your template used by the /author/ page, enable urlSegments in the Template config. Then in the template file (example code): if ($input->urlSegment1) { $username = $sanitizer->selectorValue($input->urlSegment1); // Maybe you need to add 'check_access=0' to your selector if also guest users can see this page... $u = $users->get($username); if ($u->id) { // Display the information about user } else { throw new Wire404Exception(); } } // No urlSegment passed - throw a 404 or output some message
    1 point
  36. You could also do this: $result = wire('db')->query("SELECT `page_id` FROM `field_favorite` WHERE `created_user_id` = $user->id"); $ids = array(); while($row = $result->fetch_row()) $ids[] = list($row); $fav = $pages->getById($ids); Or, if 'favorite' is a ProcessWire field (which you maybe added a 'created_user_id' column to the table), you may be able to do this: $fav = $pages->find("favorite.created_user_id=$user->id");
    1 point
×
×
  • Create New...