Popular Content

Showing content with the highest reputation since 09/20/2018 in all areas

  1. 23 points
    ProcessWire 3.0.114 is a relatively minor core version update. Most of the ProcessWire stuff I've been working on this week isn't quite ready to commit/release, so will save for later. This version adds a $database->supportsTransaction() method that returns a true or false as to whether or not the current DB engine supports transactions. Or if you give it (as an argument) the name of a table in the database, it'll return a true/false specific to that table. This version also adds importFiles() and replaceFiles() methods to $page->filesManager, which is what manages all the files for a page. These methods aren't likely to be useful in site development, but are useful for a module I'm working on, and maybe useful to other modules, so I went ahead and added them. Finally, probably the most interesting update in this version is that modules can now specify autoload order. This is something that Adrian requested, as TracyDebugger needs to load before other modules, so this update simplifies that. If you develop a module that has a similar need, be sure to see the notes for the autoload getModuleInfo() property in the Module class. That's all there is this week, so I'm not going to do a blog post this week, but stay tuned for more next week! Have a great weekend.
  2. 16 points
    Building your very own custom Fieldtypes in ProcessWire seems to be hard, but it actually is not, once you get the concept. In this post I'll share a simple and as minimalistic module as it can get that everybody can use as a boilerplate for his own Fieldtypes. A Fieldtype that does not store any information in the database A Fieldtype that stores information in the database (to be done) Make your Fieldtype configurable 1. A Fieldtype that does not store any information in the database Some of you might know the excellent RuntimeMarkup module by @kongondo. I've used it a lot in the past, but I get more and more into developing custom fieldtypes rather than hacking the runtime module to my needs. That has several advantages, but it has also one major drawback: It is always a pain to setup a new Fieldtype, because there are lots of methods (see the base class /wire/core/Fieldtype.php) and you have to know which methods you need, which ones you have to remove and adopt etc.; Not any more! Ryan has developed a showcase module (the Events Fieldtype) to learn from, but when I first peaked into it, it felt quite complex and I thought it would be a lot of effort to learn Fieldtype development). There are also some easy and small Fieldtypes to learn from, like the FieldtypeCheckbox. But all of them require a good understanding of what is going on, you need to modify existing config inputfields that might have been added to that fieldtype and afterall it's not as easy as it could be. With my new approach I plan to use a boilerplate fieldtype to start from (in OOP terms to "extend" from) and only change the parts i need... More on that later. Here is the boilerplate module with some debugging info to illustrate the internal flow on the tracy console: See the module in action in the tracy console ( @adrian has done such an amazing job with that module!!!): The code should be self-explaining. What is interesting, though, is that after the ### getUnformatted ### dump there is only one call to "___formatValue". All the other calls (loadPageField, wakeupValue and sanitizeValue) are not executed because the value is already stored in memory. Only the formatting part was not done at that point. With that concept it is very easy to create your very own custom Fieldtypes: <?php namespace ProcessWire; /** * Demo Fieldtype Extending the Boilerplate Runtime Fieldtype * * @author Bernhard Baumrock, 03.10.2018 * @license Licensed under MIT * @link https://www.baumrock.com */ class FieldtypeDemo extends FieldtypeMarkup { public static function getModuleInfo() { return [ 'title' => 'Demo', 'version' => '0.0.1', 'summary' => 'Demo Fieldtype', 'icon' => 'code', ]; } /** * convert the wakeupValue to the given format * eg: convert a page object to a string */ public function ___formatValue(Page $page, Field $field, $value) { $value = parent::___formatValue($page, $field, $value) . " - but even better!"; d($value, '___formatValue --> convert to whatever format you need'); return $value; } } Notice the change "but even better" in the last two dumps. I think it can't get any easier, can it?! I'll continue testing and improving this module, so any comments are welcome! 2. A Fieldtype that stores information in the database To be done - I'll update this post once I had the time to dig into it!
  3. 10 points
    http://tonsky.me/blog/disenchantment/ regards mr-fan
  4. 8 points
    Just for display in the repeater label? That can be done with a little hook in site/ready.php: wire()->addHookAfter('InputfieldRepeater::renderRepeaterLabel', function (HookEvent $e) { $label = $e->return; $page = $e->arguments('page'); $label = preg_replace_callback('/\\[([a-zA-Z0-9_]+)\\]/', function($match) use($page) { return number_format($page->{$match[1]}, 2, ',', '.'); }, $label); $e->return = $label; }); This looks for a field name between square brackets (something like "[price]" in "#n: {title} - {item} - [price]") in the label and replaces it with the formatted value of that field.
  5. 8 points
    Boolean logic says that, if you want to negate a compound term, you need to negate each individual term AND change the operator. This is commonly referred to as De Morgan's law. !(a and b) = !a or !b Thus, you only need to change the and to or in your if clause: <?php if($item->size->value != 'half' || $item->prev()->size->value != 'half'): ?>
  6. 8 points
    In some ways yes, but I think the key thing is: GitHub is a commercial company built around an open protocol. The problem with GitHub is monoculture, just like the problem with Gmail having too much of an influence on how we use and consume email these days. Slack is completely proprietary all the way down to the protocol level. Let's not forget that Slack used to be able to talk to IRC and XMPP, but suddenly removed support in March 2018. When a company like Slack changes something, users just have to deal with it. When it goes bankrupt, a whole galaxy of stuff built around it goes down the drain. This sort of scenario is playing over and over again while IRC and email are still with us after decades of service.
  7. 8 points
    An action that I made for my own convenience but that others might find useful too: Unordered List to Pages An action for the Admin Actions module for ProcessWire CMS/CMF. Creates a structure of new pages from an unordered list entered into a CKEditor field. The nesting of further unordered lists within the list will determine the nesting of the created pages. This can be useful to quickly create a page structure; especially so if you are rebuilding an existing non-ProcessWire site that has a Sitemap page that you can copy and paste from. All the created pages get the same template - for any pages that should use a different template you can easily change this as you edit the page to add content, or use the Page Manipulator action for bulk template changes. Usage Install the action by copying the "UnorderedListToPages" folder to /site/templates/AdminActions/, and then visiting the Admin Actions config screen and enabling the "Unordered List to Pages" action for the roles who are allowed to use it. Navigate to Admin Actions > Unordered List to Pages and fill out the config fields: Enter/paste an unordered list in the Source field. Select a parent page that the new pages will be created under. Select the template to use for the new pages. Execute the action. Screenshots Action config: Result: https://github.com/Toutouwai/UnorderedListToPages Update: https://github.com/Toutouwai/AdminActionsUnorderedListToPages This action module now has its own support topic:
  8. 7 points
    Last night my cat bit my hand for no apparent reason while he was sitting in my lap. He's a very friendly cat, but also very old and I think may be getting a little senile. It was a deep bite, though didn't seem like all that big of a deal. But this morning my hand was hurting pretty bad, then it swelled up, and then a swelling red line appeared on my skin that went from my hand to my shoulder. I went to the doctor and he said it was a bad one, and if I hadn't come in today I would have been in the hospital tomorrow. Apparently cats have some mean bacteria in their teeth and these kinds of cat bites can get pretty bad, quickly. They shot me with a bunch of antibiotics and now I've got to go see another doctor and get an x-ray because they think that there's a possibility the cat's tooth broke off and may be stuck inside my hand (I hope not!). If the antibiotics do their thing, all should be fine in a few days. I'd planned on writing a blog post today about ProcessWire 3.0.115, but it looks like that's not going to happen (and one of my hands doesn't work so well), so I'll write about it next week in combination with 3.0.116 updates. But if you want to see what's new in 3.0.115 before that, be sure to check out the dev branch commit log. Thanks for reading and have a great weekend!
  9. 7 points
    Would be nice to have a timer that shows the time to auto-log out. This would prevent losing work when the user tries to save input while the session was terminated in between.
  10. 7 points
    Are you saying that I can just find a right ProcessWire and include its index.php to my web app, and I have full access to its pages and users? I can't but wonder and love the chances of this platform. Thanks! This is so awesome work.
  11. 7 points
    Some time ago I created a site profile for creation of a REST API with ProcessWire. Since I kept struggeling with updating stuff between different projects which use this, I decided to convert it into a module. It is now ready for testing: https://github.com/thomasaull/RestApi Additionally I added a few small features: automatic creation of JWT Secret at module install routes can be flagged as auth: false, which makes them publicly accessible even though JWT Auth is activated in module settings To check things out, download and install the module and check the folder /site/api for examples. If you find any bugs or can think of improvements, please let me know!
  12. 6 points
    I'm sure you'll get more elaborate answers, just a short question: Do you know about bootstrapping pw? https://processwire.com/api/include/
  13. 6 points
    I would do this: Backgrounds Use media queries, as you are already doing. Images Use the picture element for art directed images with media queries. That is what its meant for. Content Output all versions of the content in your template and use media queries to show/hide the versions for different devices. If you are using a framework, there are components for this use case: UIkit: Visbility Bootstrap: Display I would strongly avoid user agent detection.
  14. 6 points
    Creating a support topic for this action now that the new actions-as-modules feature has been added to Admin Actions. Unordered List to Pages An action for the Admin Actions module for ProcessWire CMS/CMF. Creates a structure of new pages from an unordered list entered into a CKEditor field. The nesting of further unordered lists within the list will determine the nesting of the created pages. Created pages get a default template that you select, and you can override this default template per list item by specifying a template name between [[ ]] delimiters. This action can be useful to quickly create a page structure; especially so if you are rebuilding an existing non-ProcessWire site that has a Sitemap page that you can copy and paste from. Usage Install the Unordered List to Pages module. Visit the Admin Actions config screen and enable the "Unordered List to Pages" action for the roles who are allowed to use it. Navigate to Admin Actions > Unordered List to Pages and fill out the config fields: Source Enter/paste an unordered list in the Source field. There is a "cheatsheet" field above that explains the syntax you can use to set some template options for each list item. If you want to override the default template for an item you can specify a template name after the page title between double square brackets. If the template doesn't already exist it will be created. Example: Page title [[staff_members]] You can also specify one or more allowed child templates for a template like so: [[staff_members > manager tech_support]]This would create the page using the staff_members template, and set the allowed child templates of staff_members to manager and tech_support. Alternatively you can specify one or more allowed parent templates for a template like so: [[manager < staff_members]] This would create the page using the manager template, and set the allowed parent templates of manager to staff_members. Parent page Select a parent page that the new pages will be created under. Default template Select the default template to use for the new pages. Screenshots Action config: Result: https://github.com/Toutouwai/AdminActionsUnorderedListToPages https://modules.processwire.com/modules/admin-actions-unordered-list-to-pages/
  15. 6 points
    PW has an option to keep a history of pageviews in $session. You use a setting in /site/config.php to define how many history items you want to keep... // Keep the last 10 pageviews in the session history $config->sessionHistory = 10; ...and then get a multi-dimensional array of history data with... $history = $session->getHistory(); You could use this history to build your breadcrumb trail from.
  16. 6 points
    Great read! A bit off topic (hey, this is the pub) but this is part of the reason why I love reading about old-school software development, and game development in particular. You know, when folks had to figure out how to run complex software while dealing with various limitations – such as being limited to something between 32 and 64 KB of memory in total. Good times. For the record, there are some awesome videos about old school development and hardware at YouTube by user The 8-Bit Guy. Not only does he clearly know his "old-school" computers inside out, he has also released amazingly polished new games for old hardware
  17. 5 points
    Thx @Robin S, I had a look to those fieldtypes and you where partially right. I removed sleepValue and deletePageField since they should never get called on a non-db fieldtype. But your runtimeonly field does actually have too few methods if you want to keep it completely out of the db. Your fieldtype creates an empty db table. Not sure if that is intended? I've invested some more time and really like this approach of building new Fieldtypes! Is really simple, see this example of a new Fieldtype called "FieldtypeNow": I renamed the base fieldtype to "BaseFieldtypeRuntime" and it really does not do anything other than providing the boilerplate. It does not even show up in the list when you create a new field in your pw installation (screenshot later). This is the current code: Actually it does only define the inputfield and add some hooks to replace the render and renderReady methods by our own implementations and define all the functions necessary to keep the db out of the game: Simple, right? This is how the installation screen looks like: The BaseFieldtype is set as dependency, so FieldtypeNow can only be installed when the Base Fieldtype is available. Once installed, you can easily create a new field of that type: Notice that there is no Fieldtype "BaseFieldtypeRuntime" in this list as I mentioned above. You can then add your field to a template and edit any page of that template: <?php namespace ProcessWire; /** * Demo Fieldtype Extending the Boilerplate Runtime Fieldtype * * @author Bernhard Baumrock, 03.10.2018 * @license Licensed under MIT * @link https://www.baumrock.com */ class FieldtypeNow extends BaseFieldtypeRuntime { public static function getModuleInfo() { return [ 'title' => 'FieldtypeNow', 'version' => '0.0.1', 'summary' => 'Fieldtype showing the current time', 'icon' => 'code', 'requires' => ['BaseFieldtypeRuntime'], ]; } public function render() { return time(); } } Another Fieldtype rendering the content of a php file named like the field (very similar to the existing modules by @kongondo RuntimeMarkup, @Robin S RuntimeOnly and @kixe FieldtypeMarkup). You actually only have to implement the render() method, and if you need you can load scripts in the renderReady() method... This fieldtype loads files that are named like this: site/templates/FieldtypeRenderFile/{fieldname}.{templatename}.[php/css/js] site/templates/FieldtypeRenderFile/{fieldname}.[php/css/js]
  18. 5 points
    For me it's the worst you can do, and I hate it when I get redirected to a language I don't want. Sometimes you can't even get to another language. Just don't ever do automatic redirection based on anything.
  19. 5 points
    Latest version adds a new Inputfield Settings section to the RequestInfo panel when viewing a field in the admin. This is not turned on by default, so visit the module settings if you want to take it for a spin. Speaking of the module settings, all relevant panels now have direct links to their section in the module config settings, eg: The cog/gear icon at the bottom right will take you directly to this, which will hopefully make changes to panel settings much easier/quicker. Thanks to @bernhard for this suggestion.
  20. 5 points
    @joshuag Are there any updates on this awesome module already? Can't wait to try it.
  21. 5 points
    And if you want to make it responsive: <div uk-grid> <div class="uk-width-1-6@s"> </div> <div class="uk-width-expand"> </div> <div class="uk-width-1-6@s"> </div> </div> I find most of the time when the grid is not working it's because a div has not been closed somewhere or your parent grid is not setup correctly. It's almost always a markup error somewhere.
  22. 5 points
    Here's something to chew on. Start with this tutorial: https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/ Some code to play with. This creates a paginated ProcessWire-rendered HTML table. Create a module as per above tutorial. Use the following code in your Process module's execute() method. You need to create some people pages. In this example, they use the template 'people'. Edit functionality not included. Have a look at Blog module for that, here. For CSV upload (not included), have a look at Matrix module here for uploading CSV file and here for reading CSV file. /** * Display, Add and Edit People. * * Called when the URL is peoples's page URL + "/people/" i.e. URL Segment. * Renders a table with People information. People can be edited via modal. * * @access protected * @return mixed $form rendered form * */ public function ___execute() { $modules = $this->wire('modules'); $input = $this->wire('input')->post; $pages = $this->wire('pages'); // CREATE A NEW FORM $form = $modules->get('InputfieldForm'); $form->attr('id', 'people'); $form->action = './'; $form->method = 'post'; // CREATE AN INPUTFIELD MARKUP: Will hold list of people table $m = $modules->get('InputfieldMarkup'); $m->textFormat = Inputfield::textFormatNone;// make sure ProcessWire renders custom HTML // $m->label = $this->_('Edit'); // $m->description = $this->_('Click on a title to edit the item.'); // CREATE A NEW TABLE: for people $t = $modules->get('MarkupAdminDataTable'); $t->setEncodeEntities(false); $t->setClass('peopleTable'); // set header rows $peopleTableHeaders = array( '<input type="checkbox" class="toggle_all">', $this->_('Title'), $this->_('Name'), $this->_('Surname'), $this->_('Another Column'), $this->_('One More Column'), $this->_('Published'), #$this->_('Date'), ); $t->headerRow($peopleTableHeaders); // grab a limited number of people to show in people dashboard. Limit is hardcoded in this example $people = $pages->find("template=people, include=all, sort=-created, parent!=7, limit=10"); foreach ($people as $p) { if (!count($people)) break;// if no people found, break early // check if person page is published or not $p->is(Page::statusUnpublished) ? $status = '<span class="unpublished">' . $this->_('No') . '</span>' : $status = $this->_('Yes'); // set table rows $peopleTable = array( "<input type='checkbox' name='posts_action[]' value='{$p->id}' class='toggle'>",// disabled sorting on this in .js file "<a href='{$this->wire('config')->urls->admin}page/edit/?id={$p->id}&modal=1' class='editPeople pw-modal pw-modal-medium'>$p->title</a>", $p->title, $p->person_name, $p->person_surname, $p->another_column, $p->one_more_column, $status ); // render the table rows with variables set above $t->row($peopleTable); }// end foreach $people as $p // display a headline indicating quantities. We'll add this to people dashboard $start = $people->getStart()+1; $end = $start + count($people)-1; $total = $people->getTotal(); if($total) $peopleCount = "<h4>" . sprintf(__('People %1$d to %2$d of %3$d'), $start, $end, $total) . "</h4>"; // add a description to people dashboard {postsCount, limitSelect and instruction OR no people found status} $m->description = $total == 0 ? $this->_('No items found.') : $peopleCount . $this->_('Click on a title to edit the item.'); $m->notes = "People table notes"; $currentUrl = $this->wire('page')->url . $this->wire('input')->urlSegmentsStr."/";// get the url segment string. In this case it is "people" $pagination = $people->renderPager(array('baseUrl' => $currentUrl)); $m->attr('value', $pagination . $t->render() . $pagination);// wrap our table with pagination $form->add($m); $post = $this->wire('input')->post; // render the final form return $form->render(); }
  23. 5 points
    I freaking love this! It is like the Add mode from BatchChildEditor, but on steroids! I'd be keen to include this as a core action if you're ok with that and you'd like to submit a PR. I can see using this for kickstarting many new sites. If you do want to include, maybe move simple_html_dom.php into the libraries folder under actions, unless you feel like removing this need and coming up with a DOMDocument solution?
  24. 5 points
    "There are some bright spots indicating that improving over state-of-the-art is not impossible." The author is probably not aware of another excellent piece of high quality software which should also be listed: ProcessWire
  25. 5 points
    http://php.net/manual/en/language.oop5.decon.php __construct() is called automatically. init() not. Every property defined/ populated with __construct() is accessible inside the class/ module and outside if public. If you define properties or change their values with init() you have no access inside a function of your class without calling init() from inside this function. If you init a module the processwire way inside a template you get what you expect. EXAMPLE <?php namespace ProcessWire; class TestModule extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => "Test Module", 'version' => 1, ); } public $colours = array(); public function __construct() { $this->colours = array( 'Blue' ); } public function init() { $this->colours = array( 'Red', 'Orange', 'Yellow' ); } public function getColourArray() { return $this->colours; } } If you call Module/ Class via ProcessWire or directly inside your template you will get different results: <?php namespace ProcessWire; // INSTANTIATE VIA PW var_dump($modules->TestModule->getColourArray()); // init() is called by PW // array(3) { [0]=> string(3) "Red" [1]=> string(6) "Orange" [2]=> string(6) "Yellow" } // INSTANTIATE CLASS $test = new TestModule(); // the PHP way, init() is not called var_dump($test->getColourArray()); // array(1) { [0]=> string(4) "Blue" } // CALL INIT AND CHANGE RESULT $test->init(); var_dump($test->getColourArray()); // array(3) { [0]=> string(3) "Red" [1]=> string(6) "Orange" [2]=> string(6) "Yellow" }
  • From Twitter

    • Get notified of updates

    • ProcessWire Weekly #231 - October 13 2018
      In the 231st issue of ProcessWire Weekly we'll talk a bit about the rebuild process of the processwire.com websites, introduce a new module from Bernhard Baumrock, and check out the ProcessWire powered Finnish marketing website of the global sportswear brand Umbro. / Subscribe / More at weekly.pw