Jump to content

teppo

PW-Moderators
  • Posts

    3,259
  • Joined

  • Last visited

  • Days Won

    112

Everything posted by teppo

  1. Awesome, thanks @Robin S and @kixe! Manually copying the file and using ImageSizer on it seems like a really nice approach. Don't think I've ever done that myself; in some cases I've accessed Imagick or GD directly, but this is definitely cleaner ?
  2. So... this may be a bit of a weird question, but does anyone have brilliant ideas for generating thumbnails for Pagefile (not Pageimage) objects? A bit of background: in a recent project I ran into an issue with this in a situation where there's a files field that contains many different types of files, but for image files it needs to display thumbnails. The problem is that those images are Pagefiles, not Pageimages, so they don't have any image handling features built-in. Current solution involves creating a new Pageimages object and a new Pageimage object, passing the image file to the Pageimage object... and hooking into the install method of said object to prevent duplicate file detection from actually spitting out an endless stream of duplicates. I did consider duplicating image files into another (hidden) field behind the scenes (did that in an even earlier project), but in the end neither solution seems particularly straightforward. What's the state of the art approach for this? I've got this nagging feeling that there's something obvious I've missed ?
  3. Just an observation from "an outsider": folks who are not competent in German might still need a German language pack for their projects. It'd be a little difficult to figure out what's going on if the discussion related to said language pack was in German as well. Also, forum guidelines state that the language here is English — though personally I don't think it's going to be a major issue if you do decide that German would be better (in this specific context, based on a good reason; the key point being that it would be an exception to the rule) ?
  4. Ryan might've had other reasons as well, but... this keeps the textformatter from making a mess out of user-generated content where video URLs could be used in links, within regular text, inside table cells, in image captions, etc. ? That being said, it'd be nice if the module provided a public method for converting known single video URL into an embed code. Currently it looks a little hacky: $url = '<p>https://www.youtube.com/watch?v=ytWz0qVvBZ0</p>'; $modules->get('TextformatterVideoEmbed')->format($url); echo $url;
  5. If you look at the first post in this thread, you can see that this module requires a specific format in the texarea ("Converts contents of textarea field..." etc.) If what you've pasted above is literally the contents of your textarea field, then it won't work with this textformatter. Note, though, that this module and Textformatter Video Embed are probably not compatible out of the box due to different format requirements. Depending on your use case you could perhaps use PHP's explode() or preg_split() to split the value of your textarea field into an array (which could then be used in foreach), but it also kind of sounds like a Repeater field would make more sense in this case.
  6. Needed a really simple solution to embed audio files within page content and couldn't find a module for that, so here we go. Textformatter Audio Embed works a bit like Textformatter Video Embed, converting this: <p>https://www.domain.tld/path/to/file.mp3</p> Into this: <audio controls class="TextformatterAudioEmbed"> <source src="https://www.domain.tld/path/to/file.mp3" type="audio/mpeg"> </audio> The audio element has pretty good browser support, so quite often this should be enough to get things rolling ? GitHub repository: https://github.com/teppokoivula/TextformatterAudioEmbed Modules directory: https://modules.processwire.com/modules/textformatter-audio-embed/
  7. In the sense that no automated/programmatic tests are used: most likely yes. Third party modules often don't come with any tests, and as for sites — well, I don't really know, but my assumption is that many don't have tests. ProcessWire can be used for a lot of stuff, but the most common use case are still bespoke websites, and for those testing is rarely a key requirement. Hence the gap in testing support compared to pure web application frameworks such as Laravel ? As for core code, I don't really know. Ryan used to use a set of tests for the Selector engine, but I can't say for sure what the status of that project is.
  8. It's very likely that your IP will change every now and then. My understanding is that regular ISPs often charge extra for static IP addresses and (at least around here) some don't even offer this sort of service to consumers. When your IP changes and session fingerprinting (involving IP address) is enabled, you'll have to renew your login session. This is unrelated to session lifetime limit. That's a valid question! In many services that I use the situation is exactly the same as with ProcessWire. if I disconnect from the company VPN (or first log in to the service and only then connect to the VPN) I'm forced to redo the login process, which in turn may involve new 2FA confirmation request. Most likely these services use a similar fingerprinting mechanism as ProcessWire. On the other hand I wouldn't be terribly surprised if some big services skipped this step, especially if they happen to have many "consumer users". It can indeed be problematic for some users, and on the other hand session hijacking can also be mitigated using other measures. Storing the cookies securely and so that no one should get easy access to them is the most important step (obviously ProcessWire does that as well.) After that it's more about adding extra layers of security. According to Invision Community documentation our forum software has IP address based fingerprinting enabled by default. They recommend keeping it on, unless it causes issues. Just to make sure I just tried "hijacking" my own session — and so far it looks like the forum doesn't really care about which IP I'm using, what my UA string look like, etc. I was able to "transfer" a session to another browser, and it continued to work even after IP address change. It's important to keep in mind that lacking session fingerprinting is not a security issue in itself, more like a precaution that could've (and, in my opinion, almost always should've) been taken, yet wasn't. In this particular sense our forum could indeed be considered less secure than a typical ProcessWire site where fingerprinting is enabled ?
  9. I don't want to dismiss your frustration — I get that problems like this one can be really annoying! — but I do want to stress a couple of points about this: This is very much a needed (even required) security feature. I wouldn't recommend disabling it unless it's causing major issues, and even then there's a 99% chance that you should just fall back to one of the "less strict" options (as mentioned earlier). Without session fingerprinting attacks involving session hijacking are a very real possibility. Providing UI way to disable any security feature is something I'd be wary of. Of course it depends on the situation, but generally decisions like these should be a) made by folks who have enough technical know-how to make educated decisions knowing what the consequences will be, and b) disabling any security feature should never, ever be something you can do "on a whim" — it needs to be a decision made after serious consideration. Of course technical know-how and well considered decisions don't equal being a developer with access to site's config files or code, but the point is that providing an easy way to decrease the security of the system is definitely not something I'd consider a best practice. Quite the opposite, in fact. Also, one more thing to consider is that if someone did somehow gain illegitimate access to the admin panel, providing an UI way to disable security features could potentially allow them to escalate the attack. (This particular setting is not the best example of that, but generally speaking.) As for session fingerprinting: I've personally not had real problems with it, but I know others have, so not trying to dismiss this problem. It should, though, only happen if your IP or user agent string changes constantly, which is a pretty rare situation — though I'm not an expert in this subject. For me the only case where I've experienced something similar was while testing the site using developer tools, going between mobile UA string and regular UA string... ?
  10. @LostKobrakai did some testing related work back in the day as well, he might have some additional insight on this ? (https://github.com/LostKobrakai/pw-test-helpers etc.)
  11. I added tests for two of my modules, VersionControl and ProcessChangelog, back in the day. VersionControlTests is the more recent project, though I haven't touched or used it in years. There's only one test class in that project, and sadly I'm pretty sure it goes against so many best practices that I probably wouldn't consider it a very good starting point ? While I did use PHPUnit, it wasn't really unit testing — more like integration testing. The test class starts from a blank ProcessWire installation with required module files included, installs the module, sets up language support and adds some languages, makes changes to page(s) and after each one checks what was stored in the database, etc. In the end it attempts to restore the site to its original "untouched" condition, so that new tests can be started. In my experience ProcessWire involves so many interconnected parts and processes that creating "good enough" mock data would've been a major pain, and still wouldn't really have answered the question of "does this module work as expected in all supported ProcessWire versions, different operating systems, and different database system(s/ versions)". Of course there's still need for unit testing, but in my case it just didn't seem like the best approach ? As for current testing best practices with ProcessWire, I'd definitely check out Process Nette Tester. And — this is very opinionated, sorry in advance! — I'd probably steer away from PHPUnit. I mean... I'm sure it's an amazing tool once you really get to know it, but the more I've worked (read: fought) with it, the more frustrated I've become. In my humble opinion it's not particularly developer friendly, and there are too many limitations. Again, this might be a result of using it for wrong type of testing, so take it with a grain of salt. I just feel that there are now better options out there.
  12. This is generated on the fly when a result is rendered. Behind the scenes Renderer::renderResultDesc() and Renderer::renderResultsJson() both get field values using Renderer::getResultValue(), which in turn calls Renderer::getResultAutoDesc _auto_desc "pseudo field" (as in: not a real field) is requested. There's currently no public API for accessing this directly, but if you've got a use case that can be solved by adding one, I wouldn't be against it. Though in that case I'd like to know a bit more about the context ? Sorry! Accidentally introduced a dependency for ProcessWire 3.0.160 in the Config class. This is now fixed: latest module version (0.25.1) provides proper fallbacks for core versions prior to that.
  13. Regarding a) and b) you might perhaps find some useful bits and pieces from here: https://github.com/teppokoivula/VersionControlTests/blob/master/tests/VersionControlTest.php. If I remember correctly, installing language support and adding new languages was indeed relatively simple, though if you want ProcessWire to recognize them right away you need to go through some extra hoops (look for "reloadLanguages" and "LS_init"). In fact reloadLanguages() was initially added for this case. That being said, this is some very old code, so I have no idea if it still runs (properly) ? Edit: looks like you solved it already ?
  14. Looks like GitHub itself is down right now, so this probably has nothing to do with SettingsFactory ?
  15. Heya folks! Just wanted to say that I finally got a chance to properly test this module, and... wow. Amazing work! It looks like you had a bunch of additional stuff planned, but the features that already are there are very useful, and apart from a few minor glitches the module seemed to work like a charm. While the built-in template editing tools we have in the core are not at all bad, at least for me the workflow with Designme is still a huge improvement ? At this point I'm mostly curious about what else you might've had in store when you said that the module was "far from being good enough for release". @elabx, care to provide some insight on this? I mean... it feels to me like you could've removed some of the "less "critical" features (widgets, perhaps even the code editor, etc.) and just released the module as-is. I might be missing something important, of course, but that's my impression anyway. Either way I'm blown away by just how awesome this module is! ?
  16. Quick heads-up: SearchEngine 0.25.0 was just released. This version adds support for the new selector operators added in ProcessWire 3.0.160, and also adds a new details section below the selector operator setting. If someone has defined the operator in site config ($config->SearchEngine), that's still a valid option and new operators can be used there as well.
  17. teppo

    Wireframe

    ?‍♂️ Makes sense. I've added this to my todo list, will take care of it soon. Again, makes sense. I'm personally not a huge fan of tutorials — it's just not my thing. I prefer to learn by finding a project to work on, or alternatively by digging into existing implementations. Probably explains why there's no tutorial available for Wireframe either. Another item on my todo list ? Yes. On a very minor note the API for redefining component view would look like Wireframe::component('foo')->setView('bar'). Also: I typically choose the view in the component, i.e. the constructor picks the most suitable view based on the params it received. Both approaches are fine though, depends on the context! ? Interesting idea! I can definitely see value in this, but I'd still like to give it a bit more thought. It's easy to add features, but hard to remove (or significantly alter) them, so I prefer not to rush things ? Out of interest, how do you see this comparing to Markup modules using render method(s)? For an example: <!-- RockSearch with partial --> <section><?= $packages->RockSearch->partials->searchform() ?></section> <!-- SearchEngine --> <section><?= $modules->SearchEngine->renderForm() ?></section> One benefit would be that if I wanted to use the default search form as a starting point and start building on top of that, I could just copy the file to local partials directory and change the reference in the layout. This would, obviously, mean no more easy updates, so it's a double edged sword. In SearchEngine I decided to go with a set of interconnected render methods, each tasked with some specific part of the markup. I felt that this provided the best balance between reusability and customization: one can get pretty far by modifying config settings, but if that isn't enough, it's also possible to make more drastic changes using hooks. All in all I really like the idea, but it will require a bit more thought and probably some experimenting to strike the perfect balance ? Hopefully I'm answering the right question: Controllers and views are specific to a single template. Controllers' job is to accept arguments, process data, and pass processed data to the View layer. View — which consists of layout(s), view files, and partials — is there to output said data, so it should be as "dumb" as possible. View doesn't need to know anything about what's going on behind the scenes. Partials were originally just "include files" without the ability to accept params or a dedicated approach for processing data. They were great when you had a relatively static block you wanted to repeat in multiple templates, but if you wanted to pass them params, you'd have to define them in the parent context, etc. Components were added to fill this void. There's always a class that can accept arguments and process data, and usually there's at least one view file meant to render output. (Components can also render output directly by implementing the render() method, or they might not produce any markup at all, so technically component views are optional.) ... and then things changed a bit when partials also got the ability to accept params. Now the biggest difference between components and partials is the class: I prefer not to mix code with markup, which means that if I need a reusable "thing" that needs to, say, fetch data from an API, it's a component. On the other hand if I just need to reuse a block of HTML and perhaps iterate/output some variables in there, most of the time I go with a partial. In my mind controllers + views (and layout(s)) are the typical way to use Wireframe. Components are handy when you need an element that should be reusable across multiple templates. I guess they're sort of "template-agnostic miniature controller + view" bundles ? Note: how you actually use Wireframe may vary. Your site might not have any controllers, relying on components instead. Or you could produce all the markup in the layout and have no other files (apart from the bootstrap file). What I've described above is just the way I prefer to do things ?
  18. I'm not really familiar with this module, but it looks like the formatted output will indeed be a single date. Have you tried $result->getUnformatted('programm_date_advanced') to get the unformatted version?
  19. Check the "Advanced" tab in the Template settings. There you'll find an option to make the createdUser modifiable:
  20. Hey @michelangelo! just a quick heads-up: the Modules area of the forum is reserved for third party module support threads, one per module. This topic is about a core feature, so I'm moving it to General Support instead.
  21. I could be too tired to wrap my head around this properly, but it seems to me that your module's init/ready is going to be called after the (admin) page::render method is called, which would explain why it has no effect at all. Your module is not autoloaded, so the init/ready should only trigger when this specific inputfield is being rendered, which is likely too late in the process. Might be easier to go along the lines of what Adrian suggested and a) split the hook into a separate module that extends Wire, and b) make that separate module autoload (preferably with conditional autoloading, i.e. when the template is admin or something) ? (Note: making the Inputfield module itself autoloading should probably work too, but this way you'll end up loading some unnecessary baggage even when it's not necessarily needed.)
  22. Don't worry, it's not a stupid question ? You can definitely build a custom search feature and get great results with that, but things tend to get a little more complicated if your site contains a larger amount of fields, and particularly if you're using Repeater, RepeaterMatrix, PageTable, or other types of fields with repeatable content — or perhaps page reference fields gluing content from different pages together. In other words content that isn't technically (directly) part of the page, but needs to be tied with the page in the context of site search. Although in many cases you could no doubt include all those fields in your search queries, this can result in pretty complex queries, and such queries also tend to become inefficient. Generally speaking the more fields you join in the query, the more complex the resulting SQL query will get, and the more time and resources it'll take to process. Not a great thing for scalability. First version of SearchEngine was really just an easy way to reuse bits and pieces of code that were developed over time to mash field values together so that they could be searched more efficiently. Soon after along came the markup generating parts (which now make up a notable portion of the module), a set of features for automatically filtering and sanitizing queries and processing the index, JSON output option (mostly for AJAX requests), indexing support for field types requiring specific handling (core ones as well as third party), etc. From the initial post in this thread: These days in my projects I install SearchEngine, set it up, and trigger the render function. The module takes care of everything else and "just works". In a nutshell SE bundles most of the stuff a typical site search will need into one package, and tries to do it efficiently and following best practices ? Hope this answered your question!
  23. In the end I couldn't reproduce this issue: when a page is indexed, output formatting should be disabled, and thus this sort of problem shouldn't happen. Likely there's some scenario I've missed, so in 0.24.0 I switched that get() to getUnformatted(). I hope that resolves the problem — but if not, I may need a bit more information on how to reproduce it ?
  24. Quoting myself here, but just wanted to add that they do indeed have a solution for this ? ... so if you're using purge as defined in the Tailwind config file you need to make sure that NODE_ENV is not production when you're doing your dev build.
  25. I had to take a closer look, and it's actually mostly related to our PHP task, which runs PHP_CodeSniffer (which can be very time-consuming). You can use this with any files, though — check out https://www.npmjs.com/package/gulp-cached. It's really easy to add, basically just require the package and add a single line to your gulp task. The basic idea is that gulp-cached keeps track of files, and makes sure that files are only passed downstream if they've changed since last run. What this means in practice is that when using watch, the initial build may still be slow (none of the files being watched are cached) while subsequent ones are going to be much, much more performant, as all files that didn't change will be skipped over. Other differences I can see with our setups: You seem to be running sourcemaps on every build. If this is really the dev/watch process, then I don't really see a reason to do that, and it's definitely going to slow things down. We're using gulp-if to check for env and only setting sourcemaps up if it's a production build (basically gulp build vs. gulp watch). I'm not seeing anything related to purge here. If you're using the purge setting in Tailwind config, this is a relatively new thing and I really can't say anything about that — for me it seems easier to just run purge as a part of the gulp task: // Tailwind extractor for purgeCSS const tailwindExtractor = (content) => { return content.match(/[A-z0-9-:\/]+/g) || [] } ... .pipe(gulpif(argv.prod, purgecss({ content: [ config.paths.base + '**/*.php', config.paths.base + '**/*.js', config.paths.site + 'modules/InputfieldCKEditor/*.js', ], extractors: [ { extractor: tailwindExtractor, extensions: ['php', 'html', 'js'] } ] }))) ... Actually it shouldn't — just having something like px-3 in a file with nothing else should be enough. Again this is based on the code I've posted above, so if the native feature is using some sort of "advanced" matching algorithm, it could be a major problem for a lot of code. Weird. Note also that unless Tailwind has a mechanism for disabling purge on dev builds, you're going to be doing a lot of work that you probably don't need there. That could be another bottleneck. I'd probably just stick to a manual purge declaration in gulpfile. There's good documentation for that here, in case you need more details: https://tailwindcss.com/docs/controlling-file-size/.
×
×
  • Create New...