Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/13/2021 in all areas

  1. Work continues on the next master/main version here as we close out older issue reports and finish minor tweaks and adjustments. Eight issues were resolved this week. That might not sound like much, but with the most pressing issues already resolved, more of the GitHub time now goes towards discussion, support and more administrative related stuff, than to actual work in code. Issues remaining and being worked on are those that affect very few and might be more time consuming or difficult to reproduce, or are more subjective. We're very close to our next master version and unless anything new that's particularly pressing arises this coming week, I think we may be there next week. If you have a chance to help us test the current dev branch, please do. Thanks for your help and have a great weekend!
    13 points
  2. So... this is not a big deal by any means, but I do wonder if it might make sense to split Adminer into a separate module — one that integrates with Tracy Debugger, if installed? I get that Adminer is behind some pretty high fences here, but still. It's likely to raise some red flags, at the very least. And yes, personally I would choose to leave Adminer out, if it was possible without losing all the other goodies I get from TD. Obviously that would be a big change, so perhaps something to consider in a future major release. Or not. Just saying ?
    4 points
  3. There are probably as many ways of doing this as there are people who use ProcessWire, but this is how I would do it based on what I understand of your set-up. On the template: <?php // Just include one partial here (the HTML code in 'block-sidebar' and 'block-sidebar-settings' appears identical) include('views/blocks/block-sidebar.php'); ?> Now in "block-sidebar.php" <?php $aside = page()->aside; // first get the current page aside if ($aside === "") { // If the current page aside is empty, try and get the settings aside $aside = $pages->get('1032')->settings_aside; } ?> <?php // Only show the entire block of code if $aside is not empty (if neither the current page nor settings have content) if ($aside !== "") : ?> <div class="uk-card card-bg uk-padding-small uk-margin-small-bottom"> <h6 class="uk-margin-remove uk-text-uppercase uk-text-normal" style="letter-spacing: 1px; margin-bottom: .5rem !important;"><span uk-icon="icon: info"></span> Aktuelles</h6> <?=$aside?> </div> <?php endif; ?>
    3 points
  4. Just throwing in htmx as an alternative here. If you are interested, I could put together a rough example.
    3 points
  5. It depends who needs to see these test emails. If only you, the developer, needs to see them you can use Tracy Debugger's Mail Interceptor panel and then (I think) you won't need an email server.
    2 points
  6. Thanks for your hard work in getting lots of stuff resolved Ryan! Any chance you could prioritize this one: https://github.com/processwire/processwire-issues/issues/1116 It seems very critical to me for any site that uses URL segments and the link abstraction feature in CkEditor fields. Thanks!
    2 points
  7. @teppo - certainly not a bad idea. It's actually what I did with the Terminal panel for the same reason. However, this is the first report I've had of Adminer being flagged as spam by a host, so I might wait to see if others also have the same issue. I am hesitant because I think this is a such a useful panel - I use it many times a day - I really love the context sensitive initial view it gives depending on what you are currently viewing / editing in the admin. As well as being a great utility for getting things done, I also think it's a great learning tool for users new to PW so I'd hate to make it harder to find for new users.
    2 points
  8. I normally have either Mailgun or Sendgrid help me do this even while on dev. Or there is probably a linux equivalent to something like Mailhog??
    2 points
  9. Not that I have anything to add to LMD's solution, but the shortest answer to your question is this: All you're missing is a condition on the else. } else if ($pages->get('1032')->settings_aside) {
    2 points
  10. That seems good because it’ll continue to work if JavaScript is unavailable. I would keep it. On the server I would keep everything the same and add the $config->ajax condition to send back different output for ajax requests. For example, for a deletion it would suffice to send back success or failure http headers. In your JavaScript you could then hijack all the delete links and open them asynchronously instead: function deleteAsync(event) { event.preventDefault(); const listItem = event.currentTarget.closest('li'); //assuming currentTarget is the clicked link and it’s inside the list item listItem.style.display = 'none'; //immediately hide the item to make the action appear instantaneous const xhttp = new XMLHttpRequest(); xhttp.onload = function() { if (this.status < 200 || this.status >= 300) this.listItem.style.display = 'initial'; //deletion failed, unhide the item and maybe show an error message else this.listItem.remove(); //only really remove the item if deletion was successful }; xhttp.listItem = listItem; //add the item to the request to be able to access it in the onload callback xhttp.open('GET', event.currentTarget.href, true); xhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); //you need this for $config->ajax to work xhttp.send(); }
    2 points
  11. https://octo.github.com/projects/repo-visualization Interesting... This is PW's repo visualized: https://octo.github.com/projects/repo-visualization#explore-for-yourself (enter a repo and you'll get an interactive SVG)
    2 points
  12. I developed the new Geffen Playhouse website over the course of 2018/2019 and launched it in September 2019. It has been perhaps the largest project I have been involved in. The Geffen Playhouse went through an entire re-branding done by Base (including a custom font), and I worked with Teak on the new website. Website https://www.geffenplayhouse.org/ Wikipedia https://en.wikipedia.org/wiki/Geffen_Playhouse Base write-up https://www.basedesign.com/work/geffen-playhouse-always-geffen-playhouse-always-new Teak SF write-up https://teaksf.com/work/geffen-playhouse-ticketing-ecommerce-website-design/ Another write-up: https://www.laurentakayama.com/geffen Their previous website was severely antiquated and it wasn't a responsive website (as of 2019!). Instead, it forwarded mobile users to a "mobile-friendly" website on a different subdomain, which I think was hosted by a third party service. However the data containing all the actors, shows, seasons, news and press articles were all in there. So one major aspect of this website was de-duping and importing their data into ProcessWire, along with some post-import cleaning… that's ~25 years of data. The site is built with UIkit 3 for the most part, and also uses FullCalendar for the large and small calendars. There is a custom integration with AudienceView, their ticketing system, which is used to import all the performance showtimes of their shows into ProcessWire. It's not the easiest API to work with (XML), but I eventually got it working. Repeater Matrix is being heavily used for section-based page building. Building out all the necessary matrix types took a long time as there was quite a bit of thinking what types and layouts we needed as we went along. However the end result has given the editors a lot of flexibility. ProCache is being used as well, including a CDN for all assets. This is crucial because when opening season sales are announced, the site gets slammed, but with caching turned on, it's not a problem anymore. On a deeper level, the site uses my new (well 2 years old now), universal and very opinionated base module that provides a menu builder, a standard set of fields/templates/pages, and a bunch of other tweaks that I tend to use on every site. All the fields, templates and pages are set up in a streamlined and editor friendly way. I wasn't able to access their previous CMS backend for various reasons (I only got the MySQL dump), so when developing the site and data model in ProcessWire, I was able to completely re-envision the editor experience and the data model without bias. A quote from one of the marketing directors at Geffen Playhouse: "We absolutely love ProcessWire." More details on my personal website: https://jonathanlahijani.com/projects/geffen-playhouse/
    1 point
  13. I did a bit of reading about this last night and reports are that in Adminer v4.6.2 and below there was a security hole that hackers exploited to attack WordPress and Magento sites - not sure if other platforms were vulnerable but given that Adminer is a general DB tool I assume so. But this hole was patched and consensus seems to be that recent versions of Adminer are safe. So I wonder if the OP's host has an overly broad rule that is simply flagging Adminer generally rather than detecting specific versions. Having said that, I checked the Tracy Debugger history and the first bundled Adminer version was v4.6.3 so it was kind of a near miss. Maybe it is better that the Adminer panel is separated into its own module so that having it present on a server is more of a conscious choice. I think it's an awesome addition to Tracy so I'll be installing it for sure.
    1 point
  14. I've used Mailjet (from the same company of Mailgun) and it worked fine for me. 6.000 emails per month for free are more than enough for testing purpose I think ?
    1 point
  15. Got it @Jan Romero I counted the card-wrap elements and updated the innerHtml of the span after the cards were removed by the request. Thank you very much!
    1 point
  16. You're going to have to wrap the number in a tag, something like <span id='total-items'>{$matches->count}</span>, then keep a reference to that element around in your Javascript and update it as necessary. When deleting you might just take the innerText and decrement it, or actually count the list items (probably the most robust option). You might even calculate the new total on the server and put it into the responseText, but I would advise against it.
    1 point
  17. If you're just looking for a solution for the "email server sends email" part: Mailgun. Or any other API based service, really. Personally I've just about had it with local servers or SMTP setups. Obviously just my opinion, but I find email sending services way easier to work with, especially if you ever need to work with email related webhooks, check out from the email server/service logs what's actually happening/happened, etc. ? (Mailgun used to provide a free plan, but now it's 5000 messages for 3 months and after that a small cost. I'm still using it on my own projects because $0.80 / 1000 emails is, in my opinion, a pretty good deal.)
    1 point
  18. The minimum you would need is not a local emailserver but an email account somewhere by a hoster. Then you can setup one of the WireMail modules to connect and send through your (online) account.
    1 point
  19. Very interesting, although the visualisation doesn't quite demonstrate the fact that the bundled site profiles make up more than half of the total ZIP filesize when you download PW from the repo. I believe this has some negatives so I'm keen to start a discussion about moving most of the profiles to separate repos. For anyone interested, please participate here: https://github.com/processwire/processwire-requests/issues/415
    1 point
  20. You need to get the unformatted value of the Page Reference field in order to have unpublished pages appear: https://github.com/processwire/processwire-issues/issues/1159 $value = $page->getUnformatted('your_field_name');
    1 point
  21. Hi. Not tested but should work $this->wire()->addHookAfter('LanguagesPageFieldValue::getStringValue', function ($event) { $value = $event->return; $languagesPageFieldValue = $event->object; $languages = $this->wire()->languages; $userLanguageID = $this->wire()->user->language->id; $chineseLanguageID = $languages->get('chinese')->id; $newFallbackLanguageID = $languages->get('english')->id; if($userLanguageID === $chineseLanguageID && !$languagesPageFieldValue->getLanguageValue($chineseLanguageID)) { $value = $languagesPageFieldValue->getLanguageValue($newFallbackLanguageID); if(!strlen($value)) { $value = $languagesPageFieldValue->getDefaultValue(); } }; $event->return = $value; });
    1 point
  22. You have several possibilities depending on whether you are looping through items or whether you just needed a single item from your items. Here are examples of both scenarios. Inside a loop <div> <!-- getGridItems here is a function that returns the current grid items --> <template x-for="(item, index) in getGridItems"> <!-- bind id to item id and its text to item state --> <span :id='item.id' x-text='item.state' :key="index"></span> </template> </div> Get One Item Several possibilities here: // use filter and since expecting only one item, get it at the first array index const myItem = items.filter((item) => item.id === itemId)[0]; // loop let myItem; for (const item of items) { if (item.id === itemId) { // you have found your item myItem = item; // break out of your loop break; } } // find const myItem = items.find((item) => item.id === itemId); // do some sanity checks here before using myItem For more on loops and iteration, have a look at the Mozilla docs. Depending on the app you are building, you might want to keep a caniuse tab open ?. I see that you are storing tagName (div, etc), meaning you are creating elements on the fly? You can use vanilla JS for this or depending on the number of element possibilities (div, span, ...n), you could use a number of x-ifs. Note, though, that there is no x-else in Alpine. The flatter an object, usually the easier your work. However, sometimes this is not always possible. To access nested data, again, you have several options. You could create a function that returns the object property you want. You can also use either of brackets or dot notation (myItem.breakpoints.base.css.color). However these can get messy if the nesting is very deep. Maybe you could flatten the breakpoints object since really, it is all mainly CSS? It would make it easier to bind styles to an element.
    1 point
  23. I'll make a video of this in the near future but here's the extremely short version of the page builder journey I went on. There are 2 approaches that ultimately make sense: section-based and component-based Section Based: This is the "intended" way repeater matrix (and similar fieldtypes in other CMSes -- WordPress ACF has flexible content, Craft has Matrix) is supposed to be used. Each matrix-type represents a section with the necessary fields to populate that section. No depth. Pros easy for editors to understand they just need to put in the content and it will work; no need to worry about layout because it's baked in; hard to mess up Cons not flexible / requires a lot of discussion to make sure all sections, fields and their variations are covered can't move content from one section to another can lead to field bloat Component Based: Each matrix-type represents a component (headline, text, image, video, description list, etc.). Furthermore, 4 additional matrix-types for layout: section, container, row, column. Depth is enabled as well as the new "family friendly" option which I pushed Ryan to implement earlier this year and makes this approach more usable. Pros extremely flexible; closely follows YOOtheme Pro's approach but in a matrix-way can move content anywhere Cons higher learning curve compared to section-based since layout and nesting is involved structures must be repeated over and over again since each component is independent uses many more pages behind the scenes -- Which approach is better? The answer is it depends on the nature of the content of the site and the technical ability of editors. If the site has a level of consistency from page to page, the section-based approach would work better. However if there is less consistency and/or the editors need and/or are willing to put in extra effort to build truly unique pages, then the component-based approach makes sense. The thing is, you can actually use both approaches. The matrix field name for the section-based approach that I use is called 'sections' and the component-based approach field name is called 'builder'. My base module sets up these fields automatically and uses Mystique for all the settings. You can add both the 'sections' and 'builder' fields to a template and the editors can decide which one makes more sense given a page's needs.
    1 point
  24. Hey reno, You can set your defaults like this. Just put it before your init(): protected static $configDefaults = array( "defaultSelector" => "default value here" ); /** * Data as used by the get/set functions * */ protected $data = array(); Add this line to your inputfield: $field->attr('value', $data["defaultSelector"]); And add the following at the top of your static public function getModuleConfigInputfields(array $data) {: foreach(self::$configDefaults as $key => $value) { if(!isset($data[$key]) || $data[$key]=='') $data[$key] = $value; } You can then access this throughout your module using: $this->defaultSelector; At least that is how I have been doing it - maybe someone else has something cleaner Does that make sense? PS, Sorry for all the consecutive edits. I really shouldn't try to offer device when I am busy with other things and rushing EDIT Again - I just read that tutorial you pointed to and I see if uses: public function __construct() to set the default values. I haven't used that before. I guess I started by copying from other modules and never came across that approach. I guess there are a few different options, but construct does seem cleaner.
    1 point
  25. you can use Markdown or Textile: http://processwire.c...text-formatter/ or, if the only thing you want is the <br> where there is a new line; you can use "nl2br" on a regular text area: http://php.net/manua...ction.nl2br.php <?php echo nl2br($page->field); ?>
    1 point
×
×
  • Create New...