Jump to content

Leaderboard

Popular Content

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

  1. You can download the source code for the old skyscrapers demo https://github.com/ryancramerdesign/SkyscrapersProfile Then extract site folder beside wire/ and other site profiles. Then perform setup and check out templates, fields, how PW works. Once you get the hang of it, replace the templates with modern v2 version. https://github.com/ryancramerdesign/skyscrapers2 If you have any questions, ask away
    5 points
  2. Now, the "package manager"; From this window, you can create or delete a package, and also download a packages from the "server backups folder" to your computer. But the best feature is that you can "sync" packages stored on a third-party provider. This mean that the module will check for existing packages on GoogleDrive, Dropbox or whatever (it depend on how you configured Duplicator) and list them so you can delete or download them to your computer, and deploy your nice website in a minute! In the following example, I have packages on my Local Server, on GoogleDrive and Dropbox :
    3 points
  3. ProcessWire DropboxAPI on GitHub: https://github.com/clipmagic/DropboxAPI This module is a wrapper for Kunal Varma's Dropbox PHP SDK https://github.com/kunalvarma05/dropbox-php-sdk It was created to perform a specific function for a client, ie upload PDF files on a PW website to a specific Dropbox account folder. The PDF files, created using @Wanze's excellent PagesToPdf module using the WirePDF functions, are generated from Formbuilder forms completed by front-end site visitors. Works a treat! There's more that could be done to allow ProcessWire to take advantage of all the features of the SDK, eg downloads, multiple Dropbox accounts, etc. You are welcome to request changes and/or fork the GitHub project to extend the feature set. Enjoy! System requirements PHP 5.6.4 or greater Composer The PHP mbstring extension General information This module enables you to access a single Dropbox (www.dropbox.com) account to upload files from a ProcessWire website. All kudos to (https://github.com/kunalvarma05/dropbox-php-sdk) for the PHP API. First steps Visit (https://www.dropbox.com/developers) and read the documentation. Log into Dropbox and create a new application. It's recommended to limit ProcessWire App access to a specified folder Make a note of the App key, the App secret and the name of the Dropbox folder Installation Download the zip file into your site/modules folder then expand the zip file. Next, login to ProcessWire > go to Modules > click "Refresh". You should see a note that a new module was found. Install the DropboxAPI module. Configure the module with your App key, App secret and your Call Back URL You need to generate a Dropbox access token to enable your site to communicate with the nominated Dropbox account. Dropbox will generate a token for you or you can create a page for the front end of your ProcessWire site with a template to submit the token request to Dropbox, eg: <?php namespace ProcessWire; $drop = $modules->get('DropboxAPI'); if ($input->get->code && $input->get->state) { $code = $sanitizer->text($input->get->code); $state = $sanitizer->text($input->get->state); //Fetch the AccessToken $accessToken = $drop->getAccessToken($code, $state); echo "Copy/paste this code into the module configuration: " . $accessToken; } else { echo "<p><a href='" . $drop->getAuthURL() . "'>Log in with Dropbox</a></p>"; } ?> Once you have entered the token in the module configuration, you can unpublish this page. Usage Read the dropbox-php-sdk documentation! An example template for sending a file to a Dropbox App folder from ProcessWire: <?php namespace ProcessWire; use Kunnu\Dropbox\Dropbox; use Kunnu\Dropbox\DropboxApp; use Kunnu\Dropbox\DropboxFile; // send pdf to Dropbox $drop = $modules->get('DropboxAPI'); $app = new DropboxApp($drop->app_key, $drop->app_secret, $drop->authorization_code); if ($app) { //Configure Dropbox service $dropbox = new Dropbox($app); $dropboxFile = new DropboxFile('/path/to/myfilename.pdf'); $file = $dropbox->upload($dropboxFile, "/myfilename.pdf", ['autorename' => true]); //Uploaded File meta data if ($file) { $success = $file->getName() . " uploaded to Dropbox"; $drop->log($success); } }
    2 points
  4. @ComputerKid the SkyScraper profile is what several persons (including me) used to disect the code and find out about the power of PW Api. Please, do yourself a favor and do not just install the profile, but have a look "under the hood" and try to assimilate what, how, why etc. I can guarantee you that quite soon you will realize that Wordpress has also nothing comon other than being developed under PHP I worked myself on Wordpress for quite a few users (as an end user) and was not even able to edit some scripting parts to add custom fields etc. Now with PW in zero time I started developing my own theme with quite extensive functionality. And there is so much more to improve my coding skills, so just search the forum, search in google for ProcessWire and you will be more than good to add what is needed to your website
    2 points
  5. You can use SimpleXML to parse XML string http://php.net/manual/en/simplexml.examples-basic.php Then create new repeater items using API
    2 points
  6. Hi everyone, Here's a new module that I have been meaning to build for a long time. http://modules.processwire.com/modules/process-admin-actions/ https://github.com/adrianbj/ProcessAdminActions What does it do? Do you have a bunch of admin snippets laying around, or do you recreate from them from scratch every time you need them, or do you try to find where you saw them in the forums, or on the ProcessWire Recipes site? Admin Actions lets you quickly create actions in the admin that you can use over and over and even make available to your site editors (permissions for each action are assigned to roles separately so you have full control over who has access to which actions). Included Actions It comes bundled with several actions and I will be adding more over time (and hopefully I'll get some PRs from you guys too). You can browse and sort and if you have @tpr's Admin on Steroid's datatables filter feature, you can even filter based on the content of all columns. The headliner action included with the module is: PageTable To RepeaterMatrix which fully converts an existing (and populated) PageTable field to either a Repeater or RepeaterMatrix field. This is a huge timesaver if you have an existing site that makes heavy use of PageTable fields and you would like to give the clients the improved interface of RepeaterMatrix. Copy Content To Other Field This action copies the content from one field to another field on all pages that use the selected template. Copy Field Content To Other Page Copies the content from a field on one page to the same field on another page. Copy Repeater Items To Other Page Add the items from a Repeater field on one page to the same field on another page. Copy Table Field Rows To Other Page Add the rows from a Table field on one page to the same field on another page. Create Users Batcher Allows you to batch create users. This module requires the Email New User module and it should be configured to generate a password automatically. Delete Unused Fields Deletes fields that are not used by any templates. Delete Unused Templates Deletes templates that are not used by any pages. Email Batcher Lets you email multiple addresses at once. Field Set Or Search And Replace Set field values, or search and replace text in field values from a filtered selection of pages and fields. FTP Files to Page Add files/images from a folder to a selected page. Page Active Languages Batcher Lets you enable or disable active status of multiple languages on multiple pages at once. Page Manipulator Uses an InputfieldSelector to query pages and then allows batch actions on the matched pages. Page Table To Repeater Matrix Fully converts an existing (and populated) PageTable field to either a Repeater or RepeaterMatrix field. Template Fields Batcher Lets you add or remove multiple fields from multiple templates at once. Template Roles Batcher Lets you add or remove access permissions, for multiple roles and multiple templates at once. User Roles Permissions Batcher Lets you add or remove permissions for multiple roles, or roles for multiple users at once. Creating a New Action If you create a new action that you think others would find useful, please add it to the actions subfolder of this module and submit a PR. If you think it is only useful for you, place it in /site/templates/AdminActions/ so that it doesn't get lost on module updates. A new action file can be as simple as this: <?php namespace ProcessWire; class UnpublishAboutPage extends ProcessAdminActions { protected function executeAction() { $p = $this->pages->get('/about/'); $p->addStatus(Page::statusUnpublished); $p->save(); return true; } } Each action: class must extend "ProcessAdminActions" and the filename must match the class name and end in ".action.php" like: UnpublishAboutPage.action.php the action method must be: executeAction() As you can see there are only a few lines needed to wrap the actual API call, so it's really worth the small extra effort to make an action. Obviously that example action is not very useful. Here is another more useful one that is included with the module. It includes $description, $notes, and $author variables which are used in the module table selector interface. It also makes use of the defineOptions() method which builds the input fields used to gather the required options before running the action. <?php namespace ProcessWire; class DeleteUnusedFields extends ProcessAdminActions { protected $description = 'Deletes fields that are not used by any templates.'; protected $notes = 'Shows a list of unused fields with checkboxes to select those to delete.'; protected $author = 'Adrian Jones'; protected $authorLinks = array( 'pwforum' => '985-adrian', 'pwdirectory' => 'adrian-jones', 'github' => 'adrianbj', ); protected function defineOptions() { $fieldOptions = array(); foreach($this->fields as $field) { if ($field->flags & Field::flagSystem || $field->flags & Field::flagPermanent) continue; if(count($field->getFieldgroups()) === 0) $fieldOptions[$field->id] = $field->label ? $field->label . ' (' . $field->name . ')' : $field->name; } return array( array( 'name' => 'fields', 'label' => 'Fields', 'description' => 'Select the fields you want to delete', 'notes' => 'Note that all fields listed are not used by any templates and should therefore be safe to delete', 'type' => 'checkboxes', 'options' => $fieldOptions, 'required' => true ) ); } protected function executeAction($options) { $count = 0; foreach($options['fields'] as $field) { $f = $this->fields->get($field); $this->fields->delete($f); $count++; } $this->successMessage = $count . ' field' . _n('', 's', $count) . ' ' . _n('was', 'were', $count) . ' successfully deleted'; return true; } } This defineOptions() method builds input fields that look like this: Finally we use $options array in the executeAction() method to get the values entered into those options fields to run the API script to remove the checked fields. There is one additional method that I didn't outline called: checkRequirements() - you can see it in action in the PageTableToRepeaterMatrix action. You can use this to prevent the action from running if certain requirements are not met. At the end of the executeAction() method you can populate $this->successMessage, or $this->failureMessage which will be returned after the action has finished. Populating options via URL parameters You can also populate the option parameters via URL parameters. You should split multiple values with a “|” character. You can either just pre-populate options: http://mysite.dev/processwire/setup/admin-actions/options?action=TemplateFieldsBatcher&templates=29|56&fields=219&addOrRemove=add or you can execute immediately: http://mysite.dev/processwire/setup/admin-actions/execute?action=TemplateFieldsBatcher&templates=29|56&fields=219&addOrRemove=add Note the “options” vs “execute” as the last path before the parameters. Automatic Backup / Restore Before any action is executed, a full database backup is automatically made. You have a few options to run a restore if needed: Follow the Restore link that is presented after an action completes Use the "Restore" submenu: Setup > Admin Actions > Restore Move the restoredb.php file from the /site/assets/cache/AdminActions/ folder to the root of your site and load in the browser Manually restore using the AdminActionsBackup.sql file in the /site/assets/cache/AdminActions/ folder I think all these features make it very easy to create custom admin data manipulation methods that can be shared with others and executed using a simple interface without needing to build a full Process Module custom interface from scratch. I also hope it will reduce the barriers for new ProcessWire users to create custom admin functionality. Please let me know what you think, especially if you have ideas for improving the interface, or the way actions are defined.
    1 point
  7. Hi PW fanatics In this post I share two of my addHookMethods for those interested. As you surely already know (if not, time to take a look at it) the Wire::addHookMethod() and the Wire::addHookProperty() API methods can be used to "breath some extra OOP" into your projects. Using addHookMethods and addHookProperty are alternatives to "Using custom page types in ProcessWire". The methods I want to share: basically the idea here is to get the URL pointing to images uploaded in the admin without writing much code in the template files. With methods like these below, it does not matter what Formatted value is set to the images, because some predefined defaults are used in all circumstances. #1 Example template file code: <?php $img_src = $latest_article->siteFeaturedImage(); ?> <img src="<?= $img_src ?>" alt="<?= $page->title ?>"> addHookMethod goes into /site/init.php <?php /* Returns URL of the original Pageimage of Article. * Image field's value can be either null (default missing image), Pageimage or Pageimages. * * @return string */ $wire->addHookMethod('Page::siteFeaturedImage', function($event) { $page = $event->object; if ($page->template != "article") { throw new WireException("Page::siteFeaturedImage() only works on 'Pages of article template', Page ID=$page is not such!"); } $article_featured = $page->getUnformatted('article_featured'); //always a Pageimages array if (count($article_featured)) { $img_url = $article_featured->first()->url; } else { $img_url = urls()->templates . "assets/img/missing-article_image.jpg"; //we show this when image is not available } $event->return = $img_url; }); ?> #2 Example template file code: <?php $img600_src = $page->siteProductImageMaxSize(600, 600, ['rotate' => 180]); ?> <img src="<?= $img600_src ?>" alt="<?= $page->title ?>"> addHookMethod goes into /site/init.php <?php /* Generates image variations for Product images. Returns URL of Pageimage. * Image field's value can be either null (default missing image), Pageimage or Pageimages. * * @param int arguments[0] Max allowed width * @param int arguments[1] Max allowed height * @param array arguments[2] See `Pageimage::size()` method for options * @return string */ $wire->addHookMethod('Page::siteProductImageMaxSize', function($event) { $page = $event->object; if ($page->template != "product") { throw new WireException("Page::siteProductImageMaxSize() only works on 'Pages of product template', Page ID=$page is not such!"); } $width = isset($event->arguments[0]) ? $event->arguments[0] : 48; //default width $height = isset($event->arguments[1]) ? $event->arguments[1] : 48; //default height $options = isset($event->arguments[2]) ? $event->arguments[2] : $options = array(); //default empty options $product_image = $page->getUnformatted('product_image'); //always a Pageimages array if (count($product_image)) { $img_url = $product_image->first()->maxSize($width, $height, $options)->url; } else { $img_url = urls()->templates . "assets/img/product-missing-image.jpg"; //we show this when image is not available } $event->return = $img_url; }); ?> BTW, you can find more examples here: How can I add a new method via a hook? Working with custom utility hooks Adding array_chunk support to WireArray addHookProperty() versus addHookMethod() Have a nice weekend!
    1 point
  8. 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
  9. 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.
    1 point
  10. Here's a mixin I put together for creating hamburger icons. It utilizes the checkbox hack so you can use CSS only to show a mobile menu (or off-canvas menu, etc). Unlike other mixins here you can specify a selector for the label tag if it's not directly below the checkbox, so the label (the icon) can be placed anywhere in the DOM. There is also a "hamburger_tint" helper mixin included to easily colorize the icon/text on hover or in a checked state. Parameters: width: the width of the icon. default: 32px thickness: the thickness of the bars. default: 3px gap: the vertical space between the bars. Overall height is: thickness*3 + gap*2. default: 7px color: the color of the icons. default: #000 (black) radius: border-radius value to round edges. default: 0 anim: seconds of animation duration (transition-duration) or timing function + duration (eg. "ease-out 0.3s"). Use -1 to disable morphing to an "X". default:0.25s labelselector: in case the label is not right after the checkbox, use this setting to tell the mixin where to find it. Eg. "~ div.content header nav label". default: "+ label" padding: extra spacing around the icon. default: 0 text: show text next to the icon, by default on the right. Values: "left" or false to disable. Requires an extra "span" tag. default: "right" CodePen demo GitHub
    1 point
  11. Yeah, Console is a part of @adrian's Tracy Debugger. It's a great tool to keep under your belt. http://modules.processwire.com/modules/tracy-debugger/
    1 point
  12. You could make use of the repeater field to achieve this. You simply create the repeater and assign it the fields in questions, and the customer could add them quite easily. https://processwire.com/api/fieldtypes/repeaters/ Example <?php foreach($page->articles as $article) { echo $article->some_field; } ?>
    1 point
  13. Thank you abdus, this seems to be what I need. I am working on getting the output exactly as I want it, per the example array to string above, but I can confirm that it build an array containing the information I need!
    1 point
  14. Here's what I did. I set up a Page Reference Field, where client can pick a parent. This means with $page->related_random I can get the parent. Getting its children is simply $page->related_random->children->find(). I then iterate over them and output some data
    1 point
  15. If you define the namespace on top of your script, you wont have to prefix functions with \Processwire\ #!/usr/bin/php <?php namespace ProcessWire; // remember to include namespace include("./index.php"); // bootstrap ProcessWire // ... function createMockUsers() { $u = new User(); $u->of(false); // short for outputFormatting // inside closure you cannot access global $wire variable // unless you set function myFunction() use ($wire) {} // but you can call wire() function instead $u->name = wire()->sanitizer->pageName("newname"); $u->pass = "yo12345"; $u->email = wire()->sanitizer->email("example@processwire.com"); $u->addRole('guest'); $u->save(); } // ... createMockUsers();
    1 point
  16. Check the output of phpinfo() to see whether php extension is enabled. If not, you can install it with sudo apt install php-imagick
    1 point
  17. speaking of download icons – there is a (probably not used much, but nonetheless awesome) module called Secure File - for that module, the download button doesn't work, i guess AOS is not compatible with that module; I disabled the "Add Asset Download Button", since that module already provides a download link for the file. Just wanted to post that here in case someone else uses secure file and comes across the non-working download (if they have AOS add asset download enabled)...
    1 point
  18. Hey @Macrura - not much help I know, but I thought I should mention that I have one site hosted with Site5 and haven't had any problems like this. PS - nice "Tracy Settings" link
    1 point
  19. This rules, Robin! i am using it for a similar case where the select field in the repeater should be highlighted if selected. (later on three highlights are shown in a teaser) if($p->techhighlight == 1) { $fieldset->addClass('is-highlight'); }
    1 point
  20. great, will be sending you some Pull Requests in the near future
    1 point
  21. Yeah, I was meaning until the bug is fixed.
    1 point
  22. Today, there is a small a preview of a successful deployment (on localhost) using Duplicator : Create a package in the backend Download the package and the installer Upload it to the new hosting Navigate and run the installer
    1 point
  23. Could you do? 1=1|Kalundborg Red 2=1035|Education Teal 3=1036|Living Orange 4=1037|Good Life Blue 5=1038|Careers Cyan Then you access it through $page->option->value
    1 point
  24. Here's the documentation on that http://processwire.com/blog/posts/processwire-3.0.43-core-updates/#new-filecompiler-options Without the /*NoCompile*/ it would probably cause unneeded additional processing. I think Processwire would also probably try to add namespaces to those third party libs which may cause random problems. The code above looks correct, I'm not sure why it is still compiling.
    1 point
  25. Thank you! This is very useful because I'm not a php expert. Welcome everyone!
    1 point
  26. The module got renamed and updated a bit as its not intended to run only on the backend, but work also on frontend side. - Now, the administrator can choose to activate or not the backend login buttons. - The providers are added "dynamically". You have to simply edit a JSON config file which once saved, will show the required fields in the module settings. For example the following JSON config will only provide Google as login provider : { "providers": { "google": { "className": "Google", "packageName": "league/oauth2-google", "helpUrl": "https://console.developers.google.com/apis/credentials" } } } Small note for pw users : If like me you did not know, there is another module that manages OAuth2 authentication. Feel free to use the one which suit your needs! more info there: @jmartsch you should create a new module thread
    1 point
  27. Hello, in the last couple of days I've built a complete new Polish translation for the ProcessWire 3.0.63. It may need some cleanup of typos, some translations were done without the context, as I'm new to ProcessWire, so those may need corrections. Anyway, all language files reported by Processwire (168) and all contained phrases were translated. @PawelGIX, I hope that you don't mind that I post here, but I don't want to open a new topic if topic about Polish translation already exist @Ryan and everyone involved, thanks for building this great CMS! Github repo: https://github.com/sevenstudio/polish-wire ZIP package also attached to this post. I hope this will be usefull for Polish users of PW. Bug reports, suggestions are welcome! Thanks! Tomasz polish-language-pack-ProcessWire-3.0.63.zip
    1 point
  28. For those people who cannot get this to work in PW3, the instructions say to put this in your head: <script type='text/javascript' src='https://maps.googleapis.com/maps/api/js?sensor=false'></script> This actually needs to be: <script src="https://maps.googleapis.com/maps/api/js?key=<?= $modules->get('FieldtypeMapMarker')->get('googleApiKey') ?>"></script> Or however you like to include your JS files. The sensor=false is no longer needed, but the API key is. Seemed to work for me, I havent had time to investigate the inner workings of the module to see if this should be done or not but is just a bug. Happy mapping.
    1 point
  29. Cracked it i think.... i'm sure someone will know a much smarter way though <?php /** * Search template * */ $out = ''; if($q = $sanitizer->selectorValue($input->get->q)) { // Send our sanitized query 'q' variable to the whitelist where it will be // picked up and echoed in the search box by the head.inc file. $input->whitelist('q', $q); // Search the title, body and country fields for our query text. // Limit the results to 50 pages. // Exclude results that use the 'admin' template. $matches = $pages->find("title|body|DMCcontact_Country~=$q, template=dmc, limit=50"); $count = count($matches); if($count) { if(!$config->ajax){$out .= "<h2>Found $count pages matching your query:</h2>";} $out.= "<ul class='nav'>"; foreach($matches as $m) { $out .= "<li><p><a href='{$m->url}'>{$m->title}</a><br />{$m->DMCcontact_Country}</p></li>"; } $out .= "</ul>"; } else { $out .= "<h2>Sorry, no results were found.</h2>"; } } else { $out .= " "; } // Note that we stored our output in $out before printing it because we wanted to execute // the search before including the header template. This is because the header template // displays the current search query in the search box (via the $input->whitelist) and // we wanted to make sure we had that setup before including the header template. if(!$config->ajax) include("./dmcheader.inc"); ?> <div class="container"> <div class"row"> <div class="col-md-6"> <?php if(!$config->ajax){ echo "<h2>Please enter a country name</h2>";} ?> <form id='my_search_form' action='<?php echo $config->urls->root?>dmc-search/' method='get'> <input type='text' name='q' id='my_search_query' value='<?php echo htmlentities($input->whitelist('q'), ENT_QUOTES, 'UTF-8'); ?>' /> <button type='submit' id='search_submit'>Search</button> </form> </div> </div> </div> <?php echo $out; if(!$config->ajax) include("./dmcfooter.inc");
    1 point
  30. My opinion is that a good default behavior is to retain the original filename as much as possible. Otherwise you lose relation to the original file on your computer. Usually when a CMS auto-generates filenames, it's because they don't have another means of relating back to the source (Page/id), are using it to define a sort order, or they don't want to go to the effort of making sure the filename is secure (auto-generated names have no user input). Auto-generated names are the quick and dirty way out for a CMS. Never realized they would actually be desirable. If you have a preference for it to auto-generate names like that, it could certainly be done though. One way to accomplish it would be to make a module that hooks before Pagefile::install and rename the file, and send the new filename to the function. That function receives a single argument of just the filename to add. That filename can be local or http, so you'd only want to attempt a rename if local. public function init() { $this->addHook('Pagefile::install', $this, 'hookPagefileInstall'); } public function hookPagefileInstall(HookEvent $event) { $filename = $event->arguments(0); if(strpos($filename, '://')) return; // don't attempt to rename http-based files $page = $event->object->page; // page that will own the file $info = pathinfo($filename); // PHP's pathinfo() function $n = 0; // find the next available filename do { $n++; $newFilename = "$info[dirname]/{$page->name}-$n.$info[extension]"; // my-page-name-1.jpg } while(is_file($filename)); rename($filename, $newFilename); $event->setArgument(0, $newFilename); // update the argument to the install function } The above was written in the browser and not tested, so may need adjustments before functional. What it does is rename the file before it gets added. The do loop may not actually be necessary here, but that is just to account for the possibility that the directory (PHP's upload dir) already has a file with the target name in it. ProcessWire already takes care of adding numbers to files that are placed in it's own assets/files/ dirs.
    1 point
×
×
  • Create New...