Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/09/2019 in all areas

  1. From time to time, when I'm on a website, I'm checking the source, because I'm curious. But may be since two years, I got the feeling, that the more and more websites are stuffed with interesting crap. Today I found these body styles. It's from Squarespace. There were times, when a webpage was stuffed with table constructions and local styles. Now this madness appears again.
    3 points
  2. There's also Module::upgrade https://processwire.com/api/ref/module/ which is what the core and may existing modules are using. Pw already keeps track of versions for modules, so you mostly need to find a good way to manage what should actually happen when the version changes.
    3 points
  3. I agree that this is a challenge. I also find the Mystique approach very interesting! Did you see my approach of migrations? From the docs: Migrations are shipped with the module in /site/modules/YourModule/RockMigrations/XXX.php // 0.0.5.php <?php namespace ProcessWire; /** * Änderungen für neues Feld "Kundenstatus" */ $upgrade = function(RockMigrations $rm) { $rm->createField('ernum', 'text', [ "label" => "ER-Nummer", ]); $rm->addFieldToTemplate('ernum', 'rockprojecteffort', 'cost_gross'); }; $downgrade = function(RockMigrations $rm) { $rm->deleteField('ernum'); }; I can then just do: git pull $rm = $modules->get('RockMigrations'); $rm->setModule('YourModule'); $rm->up('0.0.5'); It's not at all complete yet, but it works well on several production projects and simplified my workflow a lot! Here an example of a more complex migration (that is IMHO still self expanatory and easy to create and manage): <?php namespace ProcessWire; /** * tweaks */ $upgrade = function(RockMigrations $rm) { $rm->setFieldData('invoiceto', ["labelFieldFormat" => "{rockcontact_parent}, {title}, E-Mail = {rockcontact_email}"], 'rockproject'); $rm->installModule('Prozesse'); $rm->installModule('ProcessProzesse'); $rm->installModule('Rechnungsfreigaben'); $rm->installModule('ProcessRechnungsfreigaben'); $rm->addPermissionsToRoles( ['prozesse','prozesse-rechnungsfreigaben'], ['office-management', 'senior'] ); $rm->createField('iscurrent', 'checkbox', [ 'label' => 'Ist der aktuellste von mehreren Einträgen', 'collapsed' => Inputfield::collapsedNo, ]); $rm->addFieldToTemplate('iscurrent', 'invoiceconfirmation'); foreach($this->pages->find('template=invoiceconfirmation') as $p) $p->save(); }; $downgrade = function(RockMigrations $rm) { $rm->deleteField('iscurrent'); $rm->uninstallModule('ProcessRechnungsfreigaben'); $rm->uninstallModule('Rechnungsfreigaben'); $rm->uninstallModule('ProcessProzesse'); $rm->uninstallModule('Prozesse'); $rm->setFieldData('invoiceto', ["labelFieldFormat" => "{rockcontact_parent}, {title}"], 'rockproject'); }; You see that it makes task that are usually tedious via the API very easy. The first line (setFieldData for invoiceto) sets new field settings in template context, for example. IMHO the way to go are migrations. The mystique approach looks very interesting indeed, but it will not work in all scenarios (eg when you need to manage/edit/install/uninstall modules or templates or roles and permissions. @LostKobrakai had a reason for developing his module and it took me quite long to understand that ? I just didn't like the implementation a lot due to the reasons mentioned in the docs of RockMigrations. Said that I have to admit that RockMigrations is also still a very early stage implementation of would would be necessary in my opinion. I think PW would strongly need a solid API to handle all those migration stuff properly and easily. Something that makes it easy to migrate between different module versions, upgrade modules, downgrade modules, revert changes, check for compatibility before installation and so on. Something that maybe even automatically syncs the module versions with the migration versions (so that your code is always in sync with your DB, otherwise it would be possible that your code requests a field that does not exist in the DB yet). If that worked all we would have to do would be a "git pull" and pw would take care of the rest. My module is kind of a quick and dirty implementation of that dream, but it works quite well ?
    3 points
  4. @Robin S I have created a first shot for this. Maybe you have time to take at look at it and play around a bit. I'm very interested in your opinion and how we should finish this. image-histo-test.zip
    2 points
  5. One huge strength of ProcessWire is the ability to create fields and templates on the fly in the admin and the beautiful architecture of it all. WordPress on the other hand does it the 'postmeta' way which is more loose, but flexible in that fields don't have to be 'registered' and custom templates are purely handled through the existence of a PHP file. Many pros and cons to each approach, but for modules, the WordPress way allows module developers to not have to worry about field settings and such since the configuration of it is NOT stored in the database. (the new Mystique module is similar to the postmeta approach, very cool) ProcessWire's approach gets a little complicated in situations where a custom module relies on a set of fields (native fieldtypes) and/or templates. The MarkupSEO module does this... upon installation, it creates a set of regular ProcessWire fields that the module relies on. But what happens if a future version of the module requires changes to the settings of a field, needs a new field or needs to delete a field (same for templates)? At this point we're talking about 'migrations' found in webapp frameworks like Rails, Laravel, etc. There's the Migrations module, but that's more general purpose. ProcessWire uses the system updater to update core changes. Is there a best practice for keeping fields and templates in check for 3rd party modules? Are there any examples of modules that do this?
    2 points
  6. @SebastianP, give this a try... 1. Remove the "lang_id=18712" portion of the selector string for the autocomplete field. 2. Add the following to the selector string for the autocomplete field: name!=12345 This part of the selector string is deliberately set to something that should always be true - in this case that the page name should not be "12345". The purpose of this is to let us identify the selector when it is sent in the AJAX request. 3. Add the following hook to /site/ready.php: $wire->addHookBefore('ProcessPageSearch::executeFor', function(HookEvent $event) { $input = $event->wire('input'); /// If this request is coming from the autocomplete field... if($input->get('name!') === '12345') { // ...then set the lang_id GET variable $input->get->lang_id = 18712; } });
    2 points
  7. You still have the "Unpublished" checkbox on the Settings tab and the "Pub" action button in Page List to deal with. Plus to be extra sure you can hook Pages::publishReady to prevent publishing by any means. Some hooks... // Remove publish button and unpublished checkbox in Page Edit $wire->addHookAfter('ProcessPageEdit::buildForm', function(HookEvent $event) { /* @var InputfieldForm $form */ $form = $event->return; /* @var ProcessPageEdit $ppe */ $ppe = $event->object; $page = $ppe->getPage(); // Return early if user is not an agent or it's not a restricted page if(!$event->user->hasRole('agent') || $page->template != 'property') return; // Return early if page is published if(!$page->isUnpublished()) return; // Get status field /* @var InputfieldCheckboxes $status_field */ $status_field = $form->getChildByName('status'); // Remove unpublished checkbox $status_field->removeOption(2048); // Get publish button $publish_button = $form->getChildByName('submit_publish'); // Remove button $form->remove($publish_button); }); // Remove publish button from Page List $wire->addHookAfter('ProcessPageListActions::getExtraActions', function(HookEvent $event) { $page = $event->arguments(0); $extras = $event->return; // Return early if user is not an agent or it's not a restricted page if(!$event->user->hasRole('agent') || $page->template != 'property') return; // Return early if page is published if(!$page->isUnpublished()) return; // Remove publish action unset($extras['pub']); $event->return = $extras; }); // Prevent publishing by any means $pages->addHookAfter('publishReady', function(HookEvent $event) { $page = $event->arguments(0); // Return early if user is not an agent or it's not a restricted page if(!$event->user->hasRole('agent') || $page->template != 'property') return; // Return early if page is published if(!$page->isUnpublished()) return; // Throw exception throw new WireException('You do not have permission to publish this page'); });
    2 points
  8. Same here... I just did my own thing then and created a template for that where I did what I wanted to create. I build the whole JSON based on the things I needed and it worked out quite well. It was easy to cache as well which was a benefit back at that time. I neither worked with sub-pages, nor AJAX but with a repeater field that contained a page reference (Occupation - in your case) and a text field (for more details about that if needed). Therefore I had everything in my object (a product in my case) and could iterate over every item (product) I defined by an URL. It looked similar to this: domain.tld/api/{object}/{identifier} or domain.tld/api/product/9876 Maybe I have still access to some of the files and post some snippets here. Just in case... what will be the result of this whole setup. Just to get in the right context.
    2 points
  9. Could you try something like this? // only allow access to the page if logged in with editing permissions // otherwise throw a 404 if viewed directly if(!$page->editable() && (!count($options['pageStack']))){ throw new Wire404Exception(); }
    2 points
  10. This is the thread for the old version of RockMigrations wich is deprecated now and has been renamed to RockMigrations1 Here is the latest version of RockMigrations: -- Old post from 2019 -- https://github.com/baumrock/RockMigrations1 Quickstart First make sure you have backups of your database!! Install RockMigrations Create this ready.php <?php /** @var RockMigrations1 $rm */ $rm = $this->wire('modules')->get('RockMigrations1'); $rm->migrate([ 'fields' => [ 'myfield' => ['type' => 'text'], ], 'templates' => [ 'mytemplate' => [], ], ]); Open your PW Backend and you'll see the new field and new template! Now add the new field to the template: <?php /** @var RockMigrations1 $rm */ $rm = $this->wire('modules')->get('RockMigrations1'); $rm->migrate([ 'fields' => [ 'myfield' => ['type' => 'text'], ], 'templates' => [ 'mytemplate' => [ 'fields' => [ 'title', 'myfield', ], ], ], ]); Reload your backend and inspect the template: Now let's add a label for our new field and make title+myfield 50% width: <?php /** @var RockMigrations1 $rm */ $rm = $this->wire('modules')->get('RockMigrations1'); $rm->migrate([ 'fields' => [ 'myfield' => [ 'type' => 'text', 'label' => 'My Field Label', ], ], 'templates' => [ 'mytemplate' => [ 'fields' => [ 'title' => ['columnWidth' => 50], 'myfield' => ['columnWidth' => 50], ], ], ], ]); That's all the magic! You can easily lookup all necessary properties in Tracy Debugger: Let us add a Textformatter as an example! Add the textformatter via the PW backend (not via RM), save the field and inspect via Tracy: Now add this data to your migration: <?php /** @var RockMigrations1 $rm */ $rm = $this->wire('modules')->get('RockMigrations1'); $rm->migrate([ 'fields' => [ 'myfield' => [ 'type' => 'text', 'label' => 'My Field Label', 'textformatters' => [ 'TextformatterEntities', ], ], ], 'templates' => [ 'mytemplate' => [ 'fields' => [ 'title' => ['columnWidth' => 50], 'myfield' => ['columnWidth' => 50], ], ], ], ]); Ok maybe you noticed that migrations are now running on every request which may slow down your site a lot! RM2 will have a feature to automatically detect changes and fire migrations automatically. RM1 does not have this feature, but I've used a technique in all my projects that fires migrations on every modules refresh. Simply wrap the migration in a fireOnRefresh method call: <?php /** @var RockMigrations1 $rm */ $rm = $this->wire('modules')->get('RockMigrations1'); $rm->fireOnRefresh(function() use($rm) { $rm->migrate([ 'fields' => [ 'myfield' => [ 'type' => 'text', 'label' => 'My Field Label', 'textformatters' => [ 'TextformatterEntities', ], ], ], 'templates' => [ 'mytemplate' => [ 'fields' => [ 'title' => ['columnWidth' => 50], 'myfield' => ['columnWidth' => 50], ], ], ], ]); }); How to remove things you created before you may ask? Use the declarative syntax: <?php /** @var RockMigrations1 $rm */ $rm = $this->wire('modules')->get('RockMigrations1'); $rm->fireOnRefresh(function() use($rm) { $rm->deleteField('myfield'); $rm->deleteTemplate('mytemplate'); }); Refresh your backend and everything is as it was before! PS: Make sure you have proper Intellisense support in your IDE to get instant help:
    1 point
  11. Please note that on line 695 of MarkupRecurme.module, the string 'All day' has not been available for translation: // if allDay if($event->allDay) { $event->time = 'All Day'; }
    1 point
  12. Thx @wbmnfktr, this is not what I need ? if($options['returnRelative']) { $filename = str_replace($options['_startPath'], '', $filename); } It only removes the startpath but does not list a relative path to the pw root. I've added a little tweak to make this possible: It would be a simple addition to $config->urls/paths in /wire/core/Paths.php: Edit: Just created a PR for that. If this feature is already there please tell me so that I can close the PR. Otherwise please like it to support this request, thx ? https://github.com/processwire/processwire/pull/142
    1 point
  13. Can't test right now but does that help? returnRelative (bool) Make returned array have filenames relative to given start $path? (default=false) https://processwire.com/api/ref/wire-file-tools/find/
    1 point
  14. This worked for me. Thank you for the update!
    1 point
  15. @gregory Please don't post the same question twice. You asked the same question here as well...
    1 point
  16. Robin, I don't have the "Unpublished" checkbox because I'm using the RestrictTabView module to hide the Settings and Delete tabs for this role. Thank you for the hooks code, this will come in handy very soon.
    1 point
  17. Oh man - you are my hero! That works like a charms! Thank you, best regards! Sebastian
    1 point
  18. I guess you could do a CSS solution: https://www.google.at/search?q=css+truncate+multiline+text&oq=css+truncate&aqs=chrome.1.69i57j0l5.4338j0j4&sourceid=chrome&ie=UTF-8 Or you could also create custom labels via a hook: // /site/ready.php $wire->addHookAfter('Pages::saveReady(template=yourtemplate)', function(HookEvent $event) { $page = $event->arguments(0); $page->yourcustomlabel = $this->sanitizer->truncate($page->yourtextarea, 150); });
    1 point
  19. I challenged myself for something similar in the past but ended that due to my lack of knowledge in JS/AJAX handling. The thing I mentioned before was done with Angular JS - and a third-party developer involved to do that magic - and I re-created the JSON he needed in PW-page/queries. If it's ok I will dig through to my archives the following weekend and look for the templates/JSON I created for that project. It will not be perfect for your things but maybe it gives you an idea somehow.
    1 point
  20. Snippet to easily add Inputfields with intellisense support ? "Get PW Inputfield": { "prefix": "field", "body": [ "/** @var Inputfield$1 \\$${2:f} */", "\\$${2:f} = \\$this->modules->get('Inputfield$1');" ], "description": "Get PW Inputfiel" }, PS: Turns out that the chaining syntax as shown in the demo does not properly work with intellisense, so I'll use single line method calls in the future ?
    1 point
  21. Hey Eduardo. Thank you a lot for the honest status update. It's nice to read something about the module again and get some insights why there wasn't an update in a while. I (and probably many others in this community) would love to get my hands on the module. The teaser videos looked just too awesome. For me it definitely looks polished and powerful enough to be a sold as a Pro module.? But if you lack the time and resources to support it at the moment, I'm sure the community would be infinitely grateful if you just released it as is.
    1 point
  22. I don't have cats ? Yes that's true. I know the "redirect if domain name is found in url" would need even a much more sophisticated parsing method, but it gets too complicated for my brain. I think having random strings as root name would be a much easier solution.
    1 point
  23. @MrSnoozles and everyone! This project is certainly halted at the moment and we are discussing what to do with it. We have not publish because one of our original intentions was to make it a Pro module. We still need to clear our heads from work and decide what to do.
    1 point
  24. Keep an eye on that file. It will save you lots of time knowing about it. Believe me. ?
    1 point
  25. Yes the problem is most likely that both sites share the same names in it. abelt.test is in both setups and even in the root name. Just rename the root to something else more unique would do the trick. It's not something you would see anyway. "abelt.test" => array( // domain name is used to map to root page "root" => "abelt", // page name for the root page "http404" => 1031 ), "alexander-abelt.test" => array( // funktioniert nicht mit /en/ auf Home "root" => "alexander", "http404" => 1029 ),
    1 point
  26. +1 Version: DEV (3.0.130) AdminTheme: Uikit - defaults
    1 point
  27. Just want to announce that I've uploaded a first public beta to the ProFields board. So all owners of ProFields may give this module a try:
    1 point
  28. A small news about Duplicator. There is a work in progress on a development version (v1.3.10-ATO) - nothing which can harm your server and could be already tested on different setup. You can download this dev version on GitHub : https://github.com/flydev-fr/Duplicator/archive/dev.zip or at the end of this post. The module still contain minor issues but the overall processing is faster than before and packages can be built and restored as well. Thanks to @Autofahrn for putting his hand in the module! Autofahrn also added a great feature which give the possibility to exclude file through regular expression. Also, image variations created by ProcessWire are now excluded by default. Duplicator-dev-1.3.10-ATO.zip
    1 point
  29. The system that's proven more effective for me is: 1 — do all the non destructive database changes on the live site (adding fields and adding them to templates, creating new templates and so on) 2 — import the database to the development server and do the templates changes 3 — pull the new files to the live site without touching the database 4 — do some cleaning on the live database if needed (remove fields, templates and so on) Another tip, although this one doesn't really answer your question, just because I think it can be useful One system that I already used effectively was to create another install of PW (a copy of the other) in the live server (on a subdirectory or subdomain) that connects to the same database, and develop all the changes on the template files right there, using real and up-to-date content. Then I simply replace the template folder by the new one.
    1 point
×
×
  • Create New...