Jump to content

Jan Romero

  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Jan Romero

  1. Yeah but still, count_years is always going to flip on New Year’s Day, so if you’ve been placing great value since December 31st, it’s going to say 1 year even though it’s barely been a day.
  2. Btw, just subtracting years from each other may yield unexpected results if you’re thinking in terms of “birthdays”, as most people likely will. That is, considering your example of 1980-07-01, right now you would get 42. If that’s a person’s birth date we would think of them as 41 years old, though. Also, I realize your site is probably not in English, but as I understand it, this is one of the classic “false friends” where “since” feels like the German “seit”, but unlike “seit” it’s not used with time spans: (I. e. you would only say “since 1980” or “since the relaunch”.)
  3. Since these tags are introduced by CKEditor you know they’ll always be there and always look the same (I guess). So you can pretty much just count how many characters you want to skip at the beginning (3) and end (4) and do it without ever mentioning anything about <p> and </p> to PHP: $bodyCopy = mb_substr($pages->get("/nastavitve/")->kontaktni_podatki, 3, -4); Or you can go the replace route: $bodyCopy = mb_ereg_replace('^<p>|</p>$', '', $pages->get("/nastavitve/")->kontaktni_podatki); Note how using mb_ereg_replace you don’t need those annoying slashes. The regex ^<p>|</p>$ just means, “find a <p> at the beginning OR a </p> at the end”, so this leaves all the inner p-tags alone. You can get more fancy if you need to take into account all the ways a HTML tag might appear, but eventually you’ll get into this territory. There is also the ol’ strip_tags function and ProcessWire ships with a Textformatter module called ParagraphStripper, I believe. As well as HTMLPurifier if you really want to get your hands dirty.
  4. The regex solution you mention only strips paragraphs containing a single non-breaking space, aka. &nbsp; aka. &#x00A0;. Do you really only want to remove the surrounding <p> tags? It’s likely to become a mess if you have more than one paragraph. To get rid of all <p>s a bog-standard str_replace should do the trick, I imagine. Unless there are arbitrary attributes on it, for example.
  5. Haha, I did the exact same thing at first 😄 Glad it’s working for you
  6. Hmm, what is the expectation? It looks fine to me if I inject my snippet into the CSS: This is in Firefox, but I also tested in Edge. Edge doesn’t show whitespace above the link’s underline, but that’s a line-height issue. When done this way, the image’s size can be controlled using only the width attribute set in CKEditor. If you set width=100 it looks like this:
  7. Try: .align_left { display: block; width: min-content; } .align_left > a { display: block; width: max-content; } This will only work if the <img> is wrapped inside an <a>.
  8. Cool site! There are obviously all kinds of ways to achieve the desired result with CSS. I’m not the best person to ask because I have no experience with CKEdit. The easiest CSS-only way would be to give .align-left the desired width, like maybe 30%, and set the img to width: 100%. No need for display: table, imho (indeed, if you do this, you should remove display: table and table-row). This would however prevent you from having different widths for left-aligned images, which may or may not be what you want.
  9. Hi, just checking, is this solely about the appearance of images in a WYSIWYG editor (CKEdit), or do you have a question about styling actual the frontend of your site? If it’s the latter, please post the relevant markup and CSS, or ideally even link to a live example, if possible.
  10. Do you have access to the PHP code? Try searching the directory /site/templates/ for “WireMail”. If you don’t find anything, search all of /site/ (but not /core/). You’re probably looking for something like this: $m = new WireMail(); $m->to($mailTo); $m->from($mailFrom); Change the $mailFrom bit to 'noreply@yoursite.com' or whatever. If you’re uncomfortable, post the code snippet and the file path, and we’ll be able to tell you if you’re breaking anything. If a module like FormBuilder is used, this may actually be configurable in the ProcessWire backend.
  11. Ah, interesting! Do you still need the explicit flush() at all with implicit_flush on?
  12. What does ob_get_status(true) output?
  13. Does this happen on a specific device? I’m aware of a similar problem with iOS/mobile Safari. ProcessWire doesn’t set an expiration date on its session cookie, which, as I understand it, technically advises browsers to throw the cookie away at the end of the browsing session, ie. when you close the browser. I’ve never seen a desktop browser actually do this, but mobile stuff operating systems are traditionally more conservative with that stuff and zealously clean up after themselves. Try putting this in your config.php: ini_set('session.cookie_lifetime', 31556926); //1 year lol Now, that’s a whole-ass year, after which your desktop sessions, which would otherwise have continued indefinitely, will probably terminate. I’ve been meaning to submit a real fix, which would involve extending the cookie every time the user is active, but this is what I live with right now. I’m also surprised no one else has ever mentioned this, given the prevalence of mobile browsing. Maybe it’s just a problem with my setup.
  14. The Role comes into it because it’s what connects the Permission to a User 🙂 A User has one or more Roles, a Role has one or more Permissions which it grants to those Users. So if you create a Permission for your Process and give it to only one Role, “content-manager”, only Users with that Role will be able to access the Process (apart from superusers who can access anything, I guess). I don’t know, it’s difficult to come up with a succinct example, but basically you can use roles to group users by their jobs and permissions to define what activities those jobs entail. Then if you need someone to do two jobs, you just give them two roles. If a role needs to do more things, you give the role more permissions (instead of going through the users separately).
  15. Well, yeah, but you can’t give the Process to a Role. You can give it to a Permission and add that Permission to the Role content-manager.
  16. Is this a Permission or a Role? You have to put a Permission.
  17. Well, it depends on the page’s template. It will be all of this https://processwire.com/api/ref/page/ plus one property per field, so if the page has a template that contains your image field called “caroussel”, you can access the first image like this: $firstImage = $page->caroussel->first(). Now $firstImage will be an object of type PageImage. $page->caroussel is an object of type PageImages (which inherits from WireArray, which is where the first() method comes from). What properties and methods a Page object has also depends on hooks you (or a module) may have set up, and on whether the page uses a custom class. There are also special pages built into ProcessWire. It is often said that in ProcessWire everything is a Page, so for example users are special pages that have some extra functionality, as are repeater items. If you’re just getting into ProcessWire it’s helpful to keep this in mind and not mentally connect the Page class to frontend pages too much (for example you may want to create pages just to hold some data, but with no accessible URL of their own). Btw afaik the spelling in English is carousel, so if you’re giving your fields English names you might want to fix that before it’s all over your codebase 😄
  18. Hi Roy, welcome to ProcessWire! ProcessWire likes to remain “markup agnostic”, so it won’t really “generate” this sort of thing for you per se. This leaves you flexible to set up your site the way you deem best. For the carousel you would want to use a javascript solution such as Swiper.js or Slick.js. Whatever you choose will probably have its own expectation of what the markup should look like. On the ProcessWire side of things, it can be as simple as creating an multi-image field for your homepage template and uploading some pics. Outputting the markup for those images is very easy with PW, and PW will help you make sure the images are the right size, aspect ratio, compression and so on. It’s also great for managing further information about the images, such as textual descriptions, licensing info or links. Anyway, depending on your requirements, it obviously doesn’t have to be images from a multi-image field. ProcessWire makes it just as easy to have a carousel of each of your site’s subsection’s main image, or something. Or no images at all. The hard part then is making sure the javascript slider you chose interacts well with the rest of your site and works responsively. These frontend concerns are outside of ProcessWire’s scope. The other thing also depends greatly on your requirements. If you just want some testimonials on your homepage, you might use one of the multi fields (eg. the Repeater field). Editors will be able to add as many customer quotes as they like, and your site might randomly show some number of those. Again, ProcessWire’s role here is to help structure that data and make it accessible to your frontend code, but the HTML and CSS are up to you. Since you mentioned the ProcessWire homepage, I noticed each item has a link to some other part of the site for more information. There are plenty of ways to achieve this and you’ll have to pick the one that’s best for you and your client. ProcessWire’s homepage not only links to various pages but also to specific sections on those pages. Using the central repeater I suggested above, you might add a url field to the repeater and fill it accordingly. This gives you the most freedom: you can put anything in there, even an external link to Youtube. It’s also the worst user experience for your client, who now has to copy and paste stuff from the address bar around (it’s also error prone for this reason). Another option would be to use a page reference field. Now you’re bound to pages on your site and you can even control specifically which pages may be chosen. This will also enable you to select all pages that are referenced on the home page, if you ever need to. Pretty solid. An entirely different approach would be to store this information not on the home page at all, but on the detail pages themselves. You could have a couple of fields on every single page (“attentionblock_title”, “attentionblock_snippet”…) and if they’re filled, you show that page on the home page. It might even be a just checkbox.
  19. Hi, welcome to the ProcessWire forums! I’m not sure I fully grokked you requirements, but I made you this monstrosity: function getTemplatesFromField(Field $field, array &$templates) { foreach ($field->getTemplates() as $tpl) { $fieldUsingThis = fields()->get('type=FieldtypeFieldsetPage|FieldtypeRepeater, template_id=' . $tpl->id); if ($fieldUsingThis->id) { getTemplatesFromField($fieldUsingThis, $templates); } else { $templates[] = $tpl; } } } $templates = []; getTemplatesFromField(fields()->get('nav_item'), $templates); var_dump($templates); That should print out all templates that contain the field “nav_item” inside their own fieldgroups or nested anywhere inside their FieldsetPage and Repeater fields. You could probably make something similar in SQL with an iterative CTE, but it’s going to be a bit of a pain because some of the data is stored in JSON columns and it’s hard to get from a repeater/fieldsetpage template to its field… Doing it in PHP should be fast enough, because all this info is loaded by ProcessWire anyway.
  20. Does your frontend do anything special related to sessions that the PW Admin doesn’t do? Maybe you can isolate what exact property of a request triggers this problem. Could anything happen outside of that template file, like append/prepend files or ready.php or something?
  21. Hi, yeah, repeater items are just pages, so you should be able to load them the regular way using pages()->find(). I think every repeater field creates a hidden template named after the field, so in your case it should be pages()->find('template=repeater_clientsubscriptions, include=all') You probably have to use “include=all” to bypass the permission system. When you have a repeater page, you can get the page it belongs to by calling $repeaterItem->getForPage(). Also, maybe check this out: https://processwire.com/blog/posts/processwire-3.0.95-core-updates/. Also have a look at this blog post on some new performance features: https://processwire.com/blog/posts/find-faster-and-more-efficiently What does this do?
  22. That’s how it’s supposed to work. You can also use the whole path: $pages->findOne("template=whatever, path=/es/donde/esta/la/pagina/")
  23. Not thinking about this too much, one obvious problem is that you’re querying the database for every item in your inner loop. This is problematic for two reasons: It’s going to be a lot of individual queries Each query seems to depend only on $client, but you’re running them in the subscriptions loop. So every client’s subscription fetches the same data redundantly. Might be worthwhile to fetch all actions in one go and then select from those. So something like pages()->find('template=action, selectedClient.parent=1080, action_start>'.$today) or something. Although this might not work if there are many matching actions per client, since you only want the first one. ProcessWire does not support grouping selectors as far as I know, so this is kind of hitting the limits of the selector system. Tbh I would do this entire thing in SQL and be done with it, since you’re not returning ProcessWire objects anyway. You may have to do some output formatting yourself, but only to $action->selectedTrainer->text1, $action->selectedTrainer->text2 and $client->title, and it will be super fast.
  24. Confirmed on PW 3.0.188 and 3.0.191. Also, the HTML5 input for floats seems to be broken? It tells me the nearest valid values are -1 and 0 when trying to input -0.00001253. You should open an issue on GitHub about this. It seems pretty messed up for PW to fudge numbers by a factor of 100,000.
  25. Ah, but it wasn’t fruitless at all! Now you have the error message: “Page name does not contain restore information”. What is $trashedPage->name? It’s supposed to be the page’s ID, a period, the parent’s ID, another period, the sort position, an underscore, then the actual name, e.g. “2048.1999.4_felt-cute-might-trash-later”. ProcessWire needs this info to know how to restore the page. If it’s not there, something must have gone wrong when the page was trashed, but you can probably just add it manually. If everything else is good, the restore button should then appear in the page tree. It would be neat if ProcessWire showed this info to superusers. It could just be where the restore button would otherwise be, or the restore button could be deactivated with the note appearing on mouseover.
  • Create New...