Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/19/2018 in all areas

  1. Hi all, Feel like I've been to hell and back :-)! No LAMP environment I set up worked! There was always something going wrong; not being able to connect to host, some PHP file extension missing, some cryptic errors!!! I tried Docker so many times I lost count. I even tried XAMPP and quite a number of other variants! Laradock almost worked but then failed on 'cannot connect to host'. In addition, it took a long time to set up. I don't know how many times I went back and forth with docker! I tried using it directly, I tried using docker clients, nothing worked! I almost installed WINE just to ran laragon! I then stumbled upon this Python (command line) docker app called Stakkr. It works! I'm using it in combination with Portainer and Traefik (both running in Stakkr as services). The Stakkr PHP images include all the extensions I need and then some. Yes, even Imagick! This was a pain to set up when I tried other docker PHP images. I needed a database tool to replace Heidi SQL now that I'm not on windows but still need to connect to remote hosts. I found this wonderful tool, DBeaver. I'm using it both locally (so I ditched phpMyAdmin andAdminer) and for remote connections. On the one hand I feel like I've wasted 2 weeks of dev work! On the other, I learnt quite a lot about docker and some related technologies. I have no more hair left to pull out and I haven't been 'nice' to be around not to mention the writer's block I picked up along the way... Back to work I go. Hopefully, no more technological interruptions...at least for some time ?. @fbg13, Thanks for Solus Plasma! I'd gone with Budgie but then tried plasma and wow! It's what I'm using now. It just works, even the printing. I was able to connect without using CUPS in the browser.
    5 points
  2. Its easy to integrate ProcessWire if the systems you are using are compatible with composer. So you can for example save information in ProcessWire and all the cart logic could be delegated to woocommerce, opencart, prestashop, etc. $ composer require processwire/processwire Then on your phps something similar to this use \ProcessWire as Pw; $pw = new Pw(); $pw->config->dbHost = getenv('MYSQL_HOST'); $pw->config->dbName = getenv('MYSQL_DATABASE'); $pw->config->dbUser = getenv('MYSQL_USER'); $pw->config->dbPass = getenv('MYSQL_PASS'); $pw->config->dbPort = getenv('MYSQL_PORT'); $pw->config->dbCharset = 'utf8mb4'; $pw->config->dbEngine = 'InnoDB'; $pages = $pw->pages;
    4 points
  3. Have you noticed those statuses are marked as internal? I guess this is for use of ProDrafts. I can check later tonight how this module uses these statuses.
    3 points
  4. Hey guys, now the language pack is also linked in the modules directory at https://modules.processwire.com/modules/german/
    3 points
  5. Hi @suntrop pages('template=board, children.children.created>="-24 hours"'); It works for me.
    3 points
  6. Nothing is future-proof, not WordPress, not ProcessWire and not even PHP. If it wasn't for ProcessWire I probably wouldn't even be working in PHP anymore, but for now I find PW the most flexible, versatile and most fun tool to work with. While I would like more recognition and user base for PW, a lack of it is not going to stop it being my tool of choice. If clients trust me, they will accept my recommendations. I continue to refuse jobs where the client only wants WP - it's just not worth the hassle during development, security issues, and updates. To each his/her own though - if WP floats your boat then by all means use it - it's huge userbase, number of plugins, and developers familiar with it is both a blessing and a curse. For me I'd rather be part of helping to build something unique in the CMS space and the reason I built my own custom CMS's for each project for so many years - it's the ultimate flexibility of PW that drew me to it in the first place.
    3 points
  7. If you're not in a hurry, you can wait the new version of Padloper from @kongondo ... it looks great
    2 points
  8. Padloper is the one. But you can always integrate PW with other systems based on PHP. Just a composer command away ?
    2 points
  9. @d'Hinnisdaël, thanks for the report. FieldsetClose needed to be excluded - fixed in v0.1.3.
    2 points
  10. I have made some updates to the module, in case someone wants to check it out ? The module will now correctly exclude unpublished pages. There's also an additional check to make sure a page is viewable by the current user before it gets linked. Hidden pages are not included by default, but this can be changed through the module settings. I adjusted the option for including the current page; this option is now disabled by default. Also, this will now work inside Repeater or Repeater Matrix fields. The updated README file on Github reflects all changes. I still have a couple of things I want to add before I call it a stable release, but feel free to check out the current version and let me know if anything doesn't work! I'm not sure if the formatter will work with the ProDrafts module, as I don't own that module and I'm not sure how the draft and version statuses interact with the default statuses. If someone can test the module on a site using that module or shed some light on those questions (forum thread here), it'd be very much appreciated!
    2 points
  11. 2 points
  12. This week we take a look at what's new in ProcessWire 3.0.119 and then we finish up by taking a look at a few screenshots from the new ProcessWire development website. If you read my post last week in the forum, you may already be familiar with some of these updates, but we'll cover them in a little more detail here: https://processwire.com/blog/posts/processwire-3.0.119-and-new-site-updates/
    2 points
  13. The language pack is available at https://modules.processwire.com/modules/german/ or in the github repository https://github.com/jmartsch/pw-lang-de/releases/tag/latest The master branch will (try to) be up to date with the most recent stable version of ProcessWire. The dev branch will (try to) be up to date with the most recent dev version of ProcessWire. If you find any missing translations or errors, please create a PR or submit a bug/improvement. I hope we as a community can work together, to update translatations as soon as a new dev branch is pushed. Please let me know if you want to translate a new dev version, so we are not both doing the same task. If you want to help, you can clone my ProcessWire environment for language packs which provides an easy way for translating a language pack. You simply clone it, make changes to the language in ProcessWire and commit the changes back to your (or the german) language pack repository. This is a boilerplate which could work with any language, but right now it is tailored to the german language pack. Then I am able to quickly release an updated stable language pack when a new ProcessWire stable version is released. Big thanks to @Nico Knoll and @yellowled for their initial work on the translations.
    1 point
  14. // in ready.php $someID = 1000; // Adding a hook property $wire->addHookProperty('Page::customProperty', function($event) use($someID) { $page = $event->object; $event->return = $someID; }); // in home.php template file, for example echo $page->customProperty;// 1000 notice the use()...It's a PHP thing. I can't find a reference to it ATM.
    1 point
  15. Shouldn't, but my experience was different ? You cannot have different htaccess files for example. So using ProCache is all-or-nothing. Things like that bugged me. That's why I switched. Laragon makes it so easy to setup new projects... just create a new folder in C:/laragon/www and click reload. You'll have a new vhost, https support and you can even share that site via ngrok temporarily and publicly. That's great when you want to show something to a client or to try webhooks of a third party service.
    1 point
  16. It shouldn't matter and I don't mean to be pedantic here ? but page creation (actually anything CRUD in ProcessWire) whether via GUI or otherwise, is carried out by the API, the very same API. That's what this will tell you ?: $pages->addHookAfter("added", function(HookEvent $event) { // code here }); It's only called when a new page is created. It will be called whether the page is created directly using the API (ProcessWire, template-file, etc) or via the GUI. It depends on your use case though, so I maybe off here and you could just do a different condition check.
    1 point
  17. Yes, to be more precise, as it look like you want to access this array from a template, you will want to set this array as a property to the right page id or template context. Check : wire()->addHookProperty(...); https://processwire.com/api/ref/wire/add-hook-property/
    1 point
  18. Yup, these are used in ProDrafts. See attached files. I guess you can use them as wel, but since they are marked internal I would not rely heavily and them and in general usage should be avoided.
    1 point
  19. Sorry @MarcoPLY I didn't saw your last ping! This is the correct way to call the hook, put it in ready.php as you did then, go to Modules > Refresh if you still can't see the hook. Code : wire()->addHookAfter('Pages::saved', function(HookEvent $event) { // Get the object the event occurred on, if needed $pages = $event->object; // Get values of arguments sent to hook (if needed) $page = $event->arguments(0); // your code: $page = $event->arguments[0]; bd($page); // tracy debug: User page object if ($page->template == "user") { $mc = wire('modules')->get("SubscribeToMailchimp"); $email = wire('user')->email; $subscriber = [ 'FNAME' => wire('user')->pad_firstname, ]; $mc->subscribe($email, $subscriber); bd($mc); // tracy debug: MailChimp object } });
    1 point
  20. This was the trick - thank you!
    1 point
  21. Snipcart: https://snipcart.com/blog/processwire-ecommerce-tutorial
    1 point
  22. I imagine most often the ecommerce systems are less flexible (by design and necessity) than processwire, so it's easier to integrate the flexible system into the inflexible one than the other way around.
    1 point
  23. It's really just adding the field to the finder:
    1 point
  24. Personally speaking, when it comes to page relationships I use... Page Reference fields: regularly The Page Field Edit Links module can be very useful for creating new pages or editing pages directly from the field via a modal. And the AsmSelect inputfield option has support for modal page editing built-in. You might find the Connect Page Fields module useful for automatically creating two-way relationships. Parent/child structure: sometimes, when it makes sense. PageTable fields: rarely
    1 point
  25. This should work too. (I used the method to output the month as a heading for a list of events sorted by start_date). What it does: Gets the first letter of the first child and output it, eg "A" Gets the next child and compares the first letter of its title with the previous child's title first letter If the same, it continues on If different, it outputs the new first letter <h2>Services</h2> <?php if ($page->children->count) : $children = $page->children('sort=title'); foreach ($children as $child) : $letter = substr($child->title, 0, 1); // get the first letter of the title if ($child->id == $children->first->id) : // first child ?> <h2><?=$letter?></h2> <?php else : $prevLetter = substr($child->prev->title, 0, 1);; if ( $prevLetter !== $letter) : // different first letter in title to previous sibling page ?> <h2><?=$letter?></h2> <?php endif; endif; ?> <p><?=$child->title?></p> <?php endforeach; endif; ?>
    1 point
  26. Hey @MischaK, just wanted to say thanks for going through the trouble of explaining your findings here. Very much appreciated ? I'm also glad to hear that there's still demand for versioning the content. I originally developed the Version Control module when we were in the process of migrating from an earlier, in-house CMS to ProcessWire. Since our old system had extensive versioning system built-in I thought it'd be a necessity for the new system as well, but at this point I'm ready to admit that I might've been somewhat misguided. It's been years since that migration started, and so far I've had a handful of clients request some method of content versioning. The times I've had to solve an issue where content was accidentally removed and couldn't be found anywhere can be counted on fingers of one hand – and yes, we've dealt with some pretty big sites. Talking about dozens of content editors and thousands of pages of content. My conclusion at this point is that it's rarely a real necessity to have content versioning in a CMS, but you're absolutely right that it's a great safety net to have. I guess it's also more important (and more useful) for users that are already used to having it in, say, a system they've used before. Kind of like how you see devs build software without any kind of version control system in place: to me it seems like a horrible nightmare, but they don't know any better – and if they've been doing that for a while already, they've probably developed other approaches to versioning or backing up their work ?
    1 point
  27. @BrendonKoz As you develop custom fieldtype you can add custom js file for the page inside iframe via a hook to page render method. $this->wire()->addHookBefore('Page::render', function ($e) { $page = $e->object; if ($this->input->get('modal') === 'panel') { $this->wire('config')->scripts->add($this->config->urls->YourFieldType . 'your-js-file.js'); } }); Then in 'your-js-file.js' you can directly find doms elements on the loaded page. Additionally, in hook, you can check whether the template of the current page (the one in the panel) has a field with your Fieldtype and then load you js.
    1 point
  28. It's the infinitely useful Console panel in Tracy Debugger: https://adrianbj.github.io/TracyDebugger/#/debug-bar?id=console
    1 point
  29. The item you want to give special treatment to is the last item in the WireArray, so you could use pop() to get that item and remove it from the WireArray: Alternatively here is a more flexible approach that you can use for any item in the WireArray:
    1 point
  30. Probably nothing that complicatied. You can use getForPage() on the repater item to retrieve the page it belongs to. $repeaterPage = $event->object->hasPage; $page = $repeaterPage->getForPage();
    1 point
  31. No worries ? I suggest testing the subscribe function in a normal doc with test data. If this works (which should :)) try to dump your real data wherever you want to implement the subscription. If you can var_dump the right data there, you should be able to perform the subscription there ? Let me know if you have questions regarding the module itself or run into errors there.
    1 point
  32. A pet hate of mine is when an editor uses a paragraph of bold text for what ought to be a heading. When I need to tidy up poorly formatted content like this I will quickly change such lines of text into the heading of the appropriate level, but that still results in markup like... <h2><strong>Some heading text</strong></h2> The <strong> has no business being there, but it's a bit of a hassle to remove it because you have to drag a selection around the exact text as opposed to just placing your cursor within the line. That gets tedious if you have a lot content to process. I figured there has to be an easier way so started looking into the ACF (Advanced Content Filter) features of CKEditor. What I wanted is a rule that says "strong tags are disallowed specifically when they are within a heading tag". (I guess there could occasionally be a use case where it would be reasonable to have a strong tag within a heading tag, but it's so rare that I'm not bothered about it). With the typical string format for allowedContent and disallowedContent there is no ability to disallow a specific tag only when it is within another specific tag - a tag is allowed everywhere or not at all. But I found there is an alternative object format for these rules that supports a callback function in the "match" property. So I was able to achieve my goal with the following in /site/modules/InputfieldCKEditor/config.js: CKEDITOR.editorConfig = function(config) { config.disallowedContent = { // Rule for the <strong> element strong: { // Use "match" callback to determine if the element should be disallowed or not match: function(element) { // Heading tag names var headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; // The parent of the element (if any) var parent = element.parent; if(typeof parent !== 'undefined') { // If there is a parent, return true if its name is in the heading names array return headings.indexOf(parent.name.toLowerCase()) !== -1; } else { // There is no parent so the element is allowed return false; } } } } }; Another tip: if you want to debug your allowedContent or disallowedContent rules to make sure they are being parsed and applied successfully you can log the filter rules to the console. For convenience I used /site/modules/InputfieldCKEditor/config.js again. // Get the CKEditor instance you want to debug var editor = CKEDITOR.instances.Inputfield_body; editor.on('instanceReady', function() { // Log the disallowed content rules console.log(editor.filter.disallowedContent); });
    1 point
  33. v18 adds a plugin that can sync page fields with rockgrid columns: Example Setup Adding the asm in a processmodule. $fs is a fieldset where we add our InputField to. $gridname is the name of the grid that is connected. // which lists to show $this->wire->config->scripts->append($this->wire->urls($this) . "scripts/manageLists.js"); $fs->add([ 'type' => 'InputfieldAsmSelect', 'name' => 'listsToShow', 'label' => __('Show list membership for...'), 'attr' => ['data-grid' => $gridname], 'asmOptions' => ['sortable'=>false], ]); $f = $fs->getChildByName('listsToShow'); $f->setAsmSelectOption('sortable', false); foreach($pages->get('template=rockmailer_lists')->children as $item) { $f->addOption($item->id, $item->title); } And the portion of the javascript file: // sync ASM field with displayed lists in grid // attach event listener when document is ready $(document).ready(function() { var $select = $('#Inputfield_listsToShow'); var colPrefix = 'rockmailer_list_'; RockGrid.plugins.syncAsmSelect({ asm: $('#Inputfield_listsToShow'), grid: RockGrid.getGrid($select.data('grid')), colName: function(pageId) { return colPrefix + pageId; }, colDef: function(col) { col = RockGrid.colDefs.yesNo(col, { isYes: function(params) { var pageId = String(params.column.colId).replace(colPrefix, ''); var lists = String(params.data.rockmailer_lists).split(','); return lists.indexOf(pageId) > -1 ? true : false; } }); col.pinned = 'left'; return col; } }); }); In this case we set a custom callback to modify the colDef for the column. It uses the yesNo plugin to show icons instead of true/false values:
    1 point
  34. The new concept of function for manipulating the columns really makes sense and is great to work with ? Whenever you create useful coldef functions please let me know - maybe others can also benefit from it. Here is one new that I just added: RockGrid.colDefs.yesNo() Here a simple example showing the status of an E-Mail (sent yes or no): col = grid.getColDef('rockmailer_sent'); col = RockGrid.colDefs.yesNo(col, {headerName: 'Status'}); And here a "more complex" example that splits a page reference field with a list of IDs and returns true if a page is part of that list and false if is not: col = RockGrid.colDefs.yesNo(col, { headerName: grid.js.listtitle, isYes: function(val) { if(!val) return false; val = val.split(","); return val.indexOf(String(grid.js.list)) > -1 ? true : false; } });
    1 point
  35. Hi all, We're going to be moving our main Australian Antarctic Division website to ProcessWire. We're taking the opportunity to completely overhaul the site. We'd be really grateful to anyone who can help us out with the structure of the site by completing this online information architecture exercise. Thanks! Optimal Workshop: Optimal Sort for Australian Antarctic Division Margaret
    1 point
  36. Update... The above works okay but it seems that the match callback only fires when CKEditor loads, so to be sure that any disallowed content resulting from the current page edit is removed you have to save the page twice. After a bit more hunting I think I've found a better approach that uses CKEditor's DTD object. It's not quite as straightforward as you'd expect at first because element objects within the DTD object are not fully independent (e.g. CKEDITOR.dtd['h2'] seems to refer to the same object as CKEDITOR.dtd['p']). This SO post helped me find a solution. In /site/modules/InputfieldCKEditor/config.js: // For numbers 1 to 6 for(var i = 1; i <= 6; i++) { // Create the tag name from 'h' plus the number var tag = 'h' + i; // Create clone of DTD heading object so it can be modified individually CKEDITOR.dtd[tag] = Object.assign({}, CKEDITOR['dtd'][tag]); // Disallow strong element from being contained within heading element CKEDITOR.dtd[tag]['strong'] = 0; }
    1 point
  37. Thanks for the clarification, now I know that I haven't overseen something. ? But wouldn't it be better to have an alias for the lates-dev version, something like: $ wireshell upgrade --latestdev Otherwise I have to look up every time, (sometimes multiple times a week), for the latest dev sha-key and copy paste it into my CLI. For example: As you can see, only one hour later than your post, the sha key to the latest dev has changed to: 637f81579e121af8ab4c4a12e21227b36ae0cd8a
    1 point
  38. In recent PW3 versions you can prepend "http" and get absolute urls like this: $config->urls->httpTemplates
    1 point
  39. I've had the go-ahead from @ESRCH and have now pushed this to the module repository. Repository Link
    1 point
×
×
  • Create New...