-
Posts
3,229 -
Joined
-
Last visited
-
Days Won
109
teppo last won the day on June 4
teppo had the most liked content!
About teppo
- Birthday 08/21/1984
Contact Methods
-
Website URL
https://weekly.pw
Profile Information
-
Gender
Male
-
Location
Finland
Recent Profile Visitors
100,681 profile views
teppo's Achievements
-
Hey Ivan, I'll have to get back to this later, but just wanted to say that this is an interesting idea. I've never really gone further than specifying a different layout file for different themes — so basically they've all had their own layouts, styles, etc. but still shared the same template specific views. And had a shared pool of components and partials. Both of your ideas sound feasible, but I must admint that the overrides/theme folder sounds "cleaner". It would probably be conceptually similar to WP child themes, e.g. you can override some features, but those that have not been overridden are the same as in the "parent theme" — right? That being said, the first one sounds like an easy to implement thing as well. I'll have to take a closer look at the code to be sure.
-
Exactly. Composers are useful for cases where we need to share data among different views, or certain types of views. Say, you want all your component views, partials, or perhaps field specific render files to have access to some shared data. Or you have a set of "conceptually related" templates and/or views that all need same variables. In the context of WordPress / Sage I've used this for things like shared settings, details about current session (such as user specific content, or some stats that I don't want to fetch/calculate multiple times, or in multiple locations), blocks of data that all events or news/articles share (such as a list of latest news/events), etc. You can achieve similar results via the bootstrap file (e.g. /site/templates/wireframe.php), and for some use cases it works very well. Especially when combined with utility classes or feature modules. But if there are a lot of "if template is x then..." type if-statements there, it can get a bit out of hand. Not to mention that some things are not automatically passed to all views. Anyway, the main reason I've not jumped right into this is that I'm also debating whether it truly makes sense. I do like the concept and it "feels right", and could potentially be beneficial outside of Wireframe as well. But at the same time I'm not too keen to introduce new concepts just because they sound fun 😄
-
Hey @Ivan Gretsky Going fine, just been busy and all — so nothing new really 🙂 I don't have new features in the works right now, mostly because for the type of projects I've been working on recently I've felt that it's more about the stuff that's outside Wireframe than in the scope of it that needs work. But since you asked, there are some ideas I've been thinking of adding. Either as a part of the framework, or as a stand-alone things. One of these is Composers, likely similar to what they've got in the Sage theme for WordPress: https://roots.io/sage/docs/composers/. Honestly still not sure how good an idea that one, but I can see some benefits, and it might be fun to experiment on 🙂 Makes sense to me, so I've added a new method for that. Usage looks like this: $wireframe = $modules->get('Wireframe'); $wireframe->initOnce(); // pass in an array of Wireframe dir names, or null to create all; defaults to null, // default value is an array with dir names as keys and disk paths as values $dirs = $wireframe->createDirectories([ 'lib', 'views', 'layouts', 'partials', 'resources', 'components', 'controllers', 'dist', 'resources', ]); Note that this is not well tested, and there may be situations I've not accounted for 🙂
-
I hate to break it to you, but... you are now 😉 Seriously though, thanks for sharing this module!
- 1 reply
-
- 3
-
First of all, you’ve got some solid suggestions here. Thanks for sharing. Just a couple of notes: Agreed, IP based blocking should be enabled by default. I did notice that you said this was tested with the default settings, but it should be noted that IP blocking is an option that can be easily enabled. I do not agree with your second suggestion, though. In fact the system should preferably try to make blocked requests look exactly the same (and take exactly the same time) as those that were not blocked. Strictly from security point of view, that is; compromises often have to be made to meet user expectations. Though I definitely appreciate the sentiment, this is not really realistic requirement, in my opinion. HTTPS is always a good idea and available in most cases, but this could become an issue e.g. considering development environments. As such, I feel that current default makes a lot of sense, all things considered. And again, thanks for sharing your findings!
-
What is the logic behind the static resources folders?
teppo replied to Ivan Gretsky's topic in Wireframe
Hey Ivan, Sorry, looks like I've completely managed to miss this topic. Also, this could probably use a bit of an overhaul in Wireframe, and a docs page as well of course. This is indeed the default setup, and your guess is correct: "static" was initially borrowed from somewhere else (possibly some version of Zend Framework, or perhaps our old in-house CMS, but not sure anymore) and eventually replaced by "resources", which seemed to be more common term. assets/dist was added with the idea that this would be the location for built/generated versions. My current workflow actually places dist under resources as well — so there could be e.g. resources/scss/, resources/images/, resources/fonts/, and finally resources/dist/. Additionally I often have a resources/lib/ directory that contains "libraries", which may be third party dependencies that are not installed via yarn or npm, or site-/app-specific JavaScript classes etc. In my opinion this doesn't matter all that much, as long as there is a convention for placing said files, so that it doesn't change from project to project. Personally I would keep "resources", and place generated files in either resources/dist or assets/dist — latter part doesn't matter a whole lot, and as such I am now wondering if the whole assets/dist thing should just be discarded from Wireframe. Hope this helps explain things a bit at least 🙂 Technically I would like to have a "public" directory, but I'm not sure if that is really meaningful here: in the context of ProcessWire files are often accessed from other directories as well, so it is almost impossible to split the project into public and non-public parts in such a way. In something like the Sage theme for WordPress (at least slightly older versions, not sure of the current state) there were "resources" for source files and "public" that contained identical structure with built files — or copies in case of files that were not modified during the build process. -
This (GUI for querying results by field name) is now available. The "field" filter is disabled by default, but can be enabled via module config screen. Stored data may contain removed fields, so free form input is required, but a simple datalist HTML element seemed to work nicely for providing suggestions based on currently existing fields:
-
Finally got around to implementing this (open/collapse all toggle). Other suggestion, querying by changed field via GUI, is still waiting — though I think I might as well add that one too, just behind an "advanced" toggle in the module config ? Have you configured max age for data storage in Process Changelog Hooks module config? If yes, it should "just work". There is also a "prune data now" toggle that you can use to clean data based on the configured max age setting, but the module should also trigger this check once a day via LazyCron. If that doesn't work, it sounds like there could be some sort of issue on the site, though it's a little difficult to say what; anyway, I'd probably start by making sure that Lazy Cron works for something (e.g. via custom hook).
-
Please no ? To elaborate, there are a couple of issues with this: Depending on how this is implemented, it could be a major turn-off for users like me, who have never (and likely will never) click that "download" link on the website, let alone use a configuration tool to get a download package. Most of the time I'm installing ProcessWire via Composer or by cloning it via Git, and obviously my wish would be that this process isn't made more complicated. On the other hand I've seen some users (beginners) kind of trip on things like "you'll have to install a module to get Repeaters working" or "you need to get a separate site profile". As such, I don't think this would necessarily be a good idea considering new users either. A configuration tool would likely be interesting mostly for advanced users, who know exactly what they want... and prefer to use a download link on a website to get it, which (I would assume) somewhat limits its usefulness. That being said, as long as I can still get a "viable" version of ProcessWire (most of what's currently in the core, and future additions as well, assuming that they are meaningful ones — which they undoubtedly will be!) without having to use a configuration tool, I of course don't mind if it is added as an additional option. If someone likes that kind of thing, then great, why not! Also if this would mean that non-essential core modules could be also installed one by one via Composer, that would be nice ? What I'm missing here is the context: is this about getting a smaller downloadable package? Is that still a thing, e.g. is it really a problem for many users? Serious question, because I really don't know. I care a lot about performance on websites, but have never considered the download size of a CMS I'm using; unless it's in gigabyte range or something crazy like that. Or is it about dropping support for some core features? I'm not getting that vibe from here either, but that would make more sense to me, though in that case it might be better to just drop them from the core and perhaps find new maintainers for the packages if possible ? Or is there some other benefit I'm missing?
-
I'd love to suggest other things as well, but for now I'll just say that this is also my experience. Sorry in advance if this turns into a rant, but I feel that this is an important topic ? Past few years we've shifted our focus so that now we mainly use ProcessWire for sites with heavy focus on application like features and structured content, while "regular websites" are more often built with WordPress. There are cases where ProcessWire is stronger, and it can be used to build flexible, content block based sites using something like Repeater Matrix, but to be fair Gutenberg (which I/we use solely, no other page builders) is on another level when it comes to built-in flexibility and WYSIWYG. With one exception: you can't have multiple "Gutenberg fields" on single page, which can, in fact, be a pretty big bummer in some cases; and that could also be a potential benefit if we did have some sort of block builder in the core. (... and if ProcessWire, on a core level, wants to focus more on directory / application type sites, there's nothing wrong in that either. It just means that we, as a group of ProcessWire developers and enthusiasts, will be "losing" a large — and likely increasing — amount of potential clients and projects for other systems.) The work done by Bernhard and jploch is fantastic, but for me the biggest question mark is probably that these are not core features, meaning that they are not something that is "officially supported" by the core / core team. They are also not free / open source software, which means that the community directly participating in their development is not really an option, in my opinion. I'm not sure what the best solution, especially since this is clearly not a common need/requirement for Ryan, but I do hope that we could eventually have some level of support for this at the core — even if it's not "full-featured", but rather a framework that can be expanded / built on top of. Using Gutenberg as an example: I don't have a real figure, but I can tell that a team has worked on it for many years now, and continues to do it on a daily basis. It's not realistic to assume that a single developer could truly compete with that. And one thing I've learned about page/block builders is that there's a lot of nuance and the architecture is a major question that could make or break it, so doing it without solid understanding of what the results of each choice is way down the pipeline would be a huge gamble. (In case of Gutenberg the architecture is a hot mess: there are no dedicated data structures, and they keep changing and breaking internal code all the time. But, again, they have enough resources to handle that, and the project has so much momentum that while developers may complain, eventually they'll have to go with the flow.) As for Ryan's point about preferring to "avoid features that blur the line between content and style or front-end and admin", which I assume was related to this request (to some extent at least), I'm sure there are ways to handle content block GUI in the admin without putting too much focus on how they look like on the front-end. E.g. tje editing interface could be more like a wireframe with some similar structure than "the final product". Front-end editing is an option, but... I must admit that I like the "middle ground" that Gutenberg has, where you're still editing content in the admin. Obviously introducing front-end styles for the content in admin is not a nobrainer, which is why many sites — in my experience — won't even aim for fully stylized (custom) blocks in the admin. WYSIWYG is a big topic in itself ?
-
And here I was thinking that this is so useful that it should be a core feature ? Anyway, just wanted to say that I absolutely love the concept of this module. In fact both Custom Logs and Logs JSON Viewer are brilliant additions!
-
I’ve not touched this module in years. I’m not surprised that the GUI is a little wonky. It was never tested on the UIKit admin theme, let alone recent jQuery versions ? That being said, thanks for testing and identifying the issue, looks like an easy fix. As for alternatives, there are of course third party tools (at least for public content), and there’s also Verify Links from Robin: I can’t say for sure how much time and effort I’ll be able to put into this module, so I’d suggest checking Robin’s module out ?
-
Whether or not the system is built on top of a framework is, in my opinion, largely irrelevant. Or perhaps it would be better to say that "it is impossible to guess if and how it would've mattered in the big picture". Call me cynical, but dependencies are never free. Each adds weight to the codebase, requires upkeep and maintenance (sometimes including major updates or rewrites), and increases potential attack surface. Also many dependencies — and especially frameworks — bring in their own way of doing things, and since ProcessWire's architecture (hooks, data structure, etc.) is really a major selling point for the system, using a framework could've had a massive impact on that. Part of the reason why ProcessWire is such a brilliant system could very well be due to it not being powered by a framework itself. This means that every decision could be made without considering how that would fit the framework. What is also interesting, in my openiin, is the framework landscape itself. Back when ProcessWire 2.0 was launched, Laravel — now considered the latest state of the art PHP framework — wasn't even around yet. Zend Framework was probably the biggest name back then, or at least the one that most serious developers considered "most likely to thrive and stay around"... yet it was discontinued. Had ProcessWire gone with the "safe bet", that would've meant a big rewrite later, or alternatively staying on a platform that is merely a shadow of its former glory. Long story short, I think Ryan made a good choice ? Don't get me wrong, though: I'm a big fan of the Composer ecosystem — almost all of my modules are available as Composer dependencies, etc. And, in my opinion, ProcessWire actually integrates quite nicely with external dependencies. Since HTTP clients were mentioned, I'll use that as an example as well: in some recent projects I've used Guzzle together with ProcessWire. I may not be able to (easily) swap the client used by the core itself, but I've yet to come across such a need anyway. Of course this comes with a cost: I recently had to migrate one project to a new server simply because a third party dependency decided to drop PHP 7.4 support. In a minor version, because why the heck not. Not that it's a bad thing necessarily to bump up the PHP version, but having to do that sort of thing in a hurry just because I prefer to use a recent and patched version of a dependency is just bollocks. This is starting to get a bit rambly, so I'll just leave it here.
- 18 replies
-
- 11
-
There's no such thing as an ignorant question, but in this case I would probably lean towards "unnecessary headache" ? If ithe goal is to use some data from Strapi and combine that with some content produced in ProcessWire, this might make sense. E.g. the data from Strapi would only cover part of the project. But if the client wants to continue to manage all their content in Strapi and you'd just be using ProcessWire for the front-end, this would mean that you'd be mitigating much of what ProcessWire has to offer. Not to mention that it might be a bit of work to make the systems run smoothly together, and when things inevitably change in the future, you'd be doing every update to the content structure twice: once in Strapi, and again in ProcessWire. I'm not familiar with Strapi, but I'm pretty sure they have a decent API already (considering that it's a headless CMS that's kind of their bread and butter) so personally I'd consider building the front-end using something else. Laravel might be a decent PHP choice, but there are many other solutions as well. Most commonly folks seem to combine Strapi and similar headless systems with some JS framework, e.g. https://strapi.io/integrations/vuejs-cms. Anyway, that's just my opinion ?♂️
- 1 reply
-
- 3
-
Reactions is a module that collects reactions for pages from site users/visitors based on a click of a reaction button. It's basically the same thing as those "did you find the information you were looking for" thingies you see on some sites. An example of what the buttons might look like: There is also a very simple process module that displays pages along with their reaction counts for each enabled reaction type. GitHub repository: https://github.com/teppokoivula/reactions Modules directory: https://processwire.com/modules/reactions/ Needed this for a project and was kind of in a hurry, so it's not super polished, but seems to work well for basic use cases. One thing that's kind of fun (or scary) about this module is that it modifies the structure of the reactions database table automatically based on active buttons; this is done using ProcessWire's built-in features ? Getting started You can install the module the usual way; clone or download the code, or install via admin. Or via Composer: composer require teppokoivula/reactions The easiest way to define available buttons is via site config: $config->reactions = [ 'reaction_types' => [ 'like' => [ 'title' => 'Like it', 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M720-120H280v-520l280-280 50 50q7 7 11.5 19t4.5 23v14l-44 174h258q32 0 56 24t24 56v80q0 7-2 15t-4 15L794-168q-9 20-30 34t-44 14Zm-360-80h360l120-280v-80H480l54-220-174 174v406Zm0-406v406-406Zm-80-34v80H160v360h120v80H80v-520h200Z"/></svg>', // optional attributes, either as an associative array or as a string, e.g.: // 'attrs' => [ // 'data-some-attr' => 'value', // ], // 'attrs' => 'data-attr="value"', ], 'love' => [ 'title' => 'Love it', 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m480-120-58-52q-101-91-167-157T150-447.5Q111-500 95.5-544T80-634q0-94 63-157t157-63q52 0 99 22t81 62q34-40 81-62t99-22q94 0 157 63t63 157q0 46-15.5 90T810-447.5Q771-395 705-329T538-172l-58 52Zm0-108q96-86 158-147.5t98-107q36-45.5 50-81t14-70.5q0-60-40-100t-100-40q-47 0-87 26.5T518-680h-76q-15-41-55-67.5T300-774q-60 0-100 40t-40 100q0 35 14 70.5t50 81q36 45.5 98 107T480-228Zm0-273Z"/></svg>', ], 'haha' => [ 'title' => 'Haha!', 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M480-260q68 0 123.5-38.5T684-400H276q25 63 80.5 101.5T480-260ZM312-520l44-42 42 42 42-42-84-86-86 86 42 42Zm250 0 42-42 44 42 42-42-86-86-84 86 42 42ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 320q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Z"/></svg>', ], ], ]; ... though you could also add them programmatically, e.g. if you wanted to manage them via admin: $wire->addHookBefore('Reactions::setReactionTypes', function(HookEvent $event) { $reaction_buttons = $event->wire()->pages->get(1)->reaction_buttons; if ($reaction_buttons->count()) { $reaction_types = []; foreach ($reaction_buttons as $reaction_button) { if (!$reaction_button->title) continue; $reaction_types[$reaction_button->name] = [ 'title' => $reaction_button->title, 'icon' => $reaction_button->icon && $reaction_button->icon instanceof Pageimage ? $reaction_button->icon->filename : null, ]; } if (!empty($reaction_types)) { $event->arguments(0, $reaction_types); } } }); The module has basic styles and scripts bundled in, though you'll have to load them yourself: <link rel="stylesheet" href="<?= $config->urls->Reactions ?>styles/reaction-buttons.css"> <script src="<?= $config->urls->Reactions ?>scripts/reaction-buttons.js"></script> ... and then call the render method to render the buttons in your template file(s): <?= $modules->get('Reactions')->renderReactionButtons() ?> For those interested in doing stuff like displaying something based on the answer, bundled JS triggers an event that you can listen to: document.dispatchEvent(new CustomEvent('reactions-updated', { detail: { pageID: pageID, reaction: reaction, }, }, { bubbles: true }));
- 2 replies
-
- 12