-
Posts
3,227 -
Joined
-
Last visited
-
Days Won
109
Everything posted by teppo
-
I agree that there are valid use cases for page builders. In fact some of the biggest projects I've built on top of ProcessWire have utilized some form of that. Not just for fast mockups, but also because these sites often have hundreds or thousands of pages with varying layouts, meaning that a predefined fields approach would become a hot mess of dozens or even hundreds of separate templates and fields. That's simply not feasible. Regarding the idea of porting one of those tools to ProcessWire... if you're talking about a direct port, so far I'm not convinced. Elementor advertises itself as the only fully free and open source editor, and if that's true, then it's the only one we could port, and even then we'd have to convert a lot of WP specific code over. Elementor consists roughly of some 20k lines of JS, 20 external JS libraries, and plenty of PHP on top of that. In short it would be a massive project, and maintaining such a fork would be a full-time job. That being said I haven't had a closer look at the Elementor JS part, so it may be more portable than I currently think – but considering that it probably wasn't designed with portability in mind, that seems unlikely ? If only there was some sort of a CMS agnostic page builder framework, that'd be awesome ?
-
Hey @Soma! Sorry, finnish UI in the screen capture might've been a bit confusing. Hakutulokset = search results, tulokset = results. Anyway, the point was that I tried a dozen or so addresses and some local landmarks, and the only response was that error in red. Now it seems to work. ?
-
Probably a dumb question, but in $_form->render($form, function($form, $template) { ... }) what exactly is $_form? I'm assuming it's a instance of InputfieldForm, but is that right? Also, how are you adding callback support? As far as I can tell, by default InputfieldForm->render() doesn't take any arguments ? You mentioned that you "placed some bdb() calls in the createUser callback", but if you meant placing them within the createUser() function, have you tried placing them before it's called, i.e. before the "return $this->createUser($form, $template, true);" line? Just to make sure whether we reach that point at all. Assuming that this is all server-side code, I don't see how the browser could be relevant. The first options I can think would be ... To make sure that however you're adding these new features to the render() method, it really gets done on each page load. To make sure that this issue isn't caused by an error in the form, i.e. a required field being blank or having invalid value. To make sure that caching isn't involved (seems unlikely, but it might be worthwhile turning all kinds of caching off and test if the issue still appears).
-
Not sure at what point this was added, but if you click the name of the image in admin, you can edit it in context. Save, and the filename will change. Personally I prefer sorting items in the order they appear in the admin. This way you can simply drag the images to the correct order, no need to tweak filenames ?
-
Slightly off-topic, but ... Not a very good first impression in terms of reliability. There's another search provider as well, but that one was unable to find anything with the keywords I could think of. This probably isn't a major issue for the whole platform, but the downside of a completely free and open service is often that "it works if it works". Best make sure that the client is also aware of this – i.e. that there are no guarantees whatsoever ? On topic: so far I think that providing Google with proper credit card details and defining daily quotas where applicable is the most viable solution. This change will likely limit our enthusiasm to offer certain Google Maps based solutions to clients as well. One possibly interesting thing is that previously Google Maps terms of service stated that the implementation "must be generally accessible to users without charge". IANAL, but one (strict) interpretation of this was that using Google Maps on a non-public site, such as an intranet, would require the premium version – and I can assure you that it's not particularly cheap, so most organisations wouldn't want to pay for it unless it was a key part of their business model. It seems to me that this limitation has now been lifted, making the use of Google Maps API a bit more flexible. I am not a lawyer though, so don't take my word for it ?
-
As @OLSA explained above, that's not how Repeaters work. In order to connect more than one instance of a specific field, behind the scenes they create pages, and store field values on those new pages. The change you've suggested here wouldn't be a trivial one, at least. Calling field value ($page->field_name) when multiple fields have the same name is one issue, and selectors are another ($pages->find("field_name=value")). Probably a few other issues as well, but at least in those cases we'd need to do a lot more – that would ultimately add a ton of complexity for a use case that, in my humble opinion, is very rare. Now, getting back to your original issue: Although I think I get what you're trying to do here, you're approaching this in a really "non-ProcessWire" way. When using any given system, you'll eventually run into things that work in a certain, perhaps unique way – and that's where you can either try to work with the system, or work against it. The latter, obviously, is not particularly productive approach. In ProcessWire fields are most useful (considering data architecture, use in selectors, keeping your code readable, and so on) when each of them has a specific and semantic meaning: "this field stores phone number, so we'll call it phone_number – and this one stores a first name, so let's call it first_name". When you need to reuse multiple fields on a single page, we're often talking about some sort of a content block builder, even if in your case you need to predefine the number of items, the order of items, and so on. For such constructs ProcessWire provides two options right out of the box, Repeaters and PageTable. Both have their own benefits, but it essentially boils down to this: while Repeater UI is more embedded to the Page editing workflow, PageTable uses modal windows for editing content – and while PageTable supports multiple different content types, Repeaters only support one (although you can use showIf settings to define rules governing when a specific field is displayed). Commercial RepeaterMatrix field (part of the ProFields package) essentially provides the best of both worlds, at least in my opinion: in-context editing like Repeaters and proper support for multiple content types. That's what I usually use for my client sites when a content block builder is required. If you're looking for a free (as in beer) solution, PageTableExtended is definitely worth checking out as well. To summarise: it seems that your use case would greatly benefit from the use of a repeating field type (Repeater, PageTable, or RepeaterMatrix). If the number of items and the order of them is the main issue and things will fall apart if those two are wrong, I would try to find a programmatic solution to that: use hooks to force each new page to have specific items – and when a page is saved, make sure that those items are still there. You could also hide or disable features that sort items or remove/add them using some simple JS or CSS, which you can embed yourself (via hooks), or by using a module such as Admin Custom Files. Finally, if you're adamantly against the idea of using a repeating fieldtype, one more (commercial) solution you should check out would be the Table fieldtype, which is also included in the ProFields package. It's essentially a flexible fieldtype you can use to create new custom fieldtypes on the fly, so more or less what OLSA suggested above, but with a nice GUI. This way you can quite easily make each of your fieldsets a single field, and you'd have much fewer fields in total. --- Hope I didn't come out too smug, but while I do sympathise with your struggle with this particular use case, in my opinion it is something that ProcessWire already supports – it just doesn't do it exactly the way you'd like to. Also: while this is no doubt among the use cases that can be solved using ProcessWire, in some cases you have to face that ProcessWire might not be the best possible tool for the job. Given the wide variety of web based solutions, such situations are bound to pop up eventually ?
-
Nothing wrong with this approach. You can always build your own, site-specific modules for such features, and as long as the module has "autoload" set to "false" ProcessWire won't load it unless you really need it – i.e. unless you specifically request it via a template file, a bootstrap script, etc. A "bare-bones" alternative would be separating this logic into a regular PHP file, which you then include as needed. Which approach makes most sense tends to depend a lot on the complexity and your use case, and even then it's ultimately a matter of preference ? If you do go with a module approach, you'd probably want to use something like this: <?php namespace ProcessWire; class MyModule extends WireData implements Module { ... } You can use .module or .module.php as a file suffix. ProcessWire supports both, but as far as I can tell .module is still more commonly used ?
-
Help with IMPLODE (different output of last page)
teppo replied to Hajosch's topic in Getting Started
There are various ways you can achieve this, including plain PHP and even plain HTML+CSS (depending on your use case you might be able to convert this to a list and add those delimiters as ::after pseudo-elements – it might even make more sense semantically), but probably the easiest way would be the implode() method of the WireArray class. Since $page->authors returns an instance of PageArray and PageArrays inherit the methods of the WireArray class, you can do something like this in your code: <!-- Query of the authors --> <?php if (count($page->authors)) { echo "<u>AUTOR/EN</u>: "; echo $page->authors->implode("; ", function($item) { return "<a href='{$item->url}'>{$item->title}</a>"; }); echo "."; } ?> A plain PHP solution using a counter variable would look something like this – this is probably the easiest method to understand for a not-so-experienced developer: <!-- Query of the authors --> <?php $author_count = count($page->authors); if ($author_count) { $count = 0; echo "<u>AUTOR/EN</u>: "; foreach ($page->authors as $author) { ++$count; echo "<a href='{$author->url}'>{$author->title}</a>"; echo $count < $author_count ? "; " : "."; // note: this is a ternary operator, see http://php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary for details } } ?> -
@netcarver, re-opening issues depends on who closed them. Here's the key part, borrowed from this StackOverflow answer: you can re-open your own issues *if you closed them yourself. you cannot close or re-open issues opened by someone else. you cannot re-open your own issues if a repo collaborator closed them Also: thanks for your work there – the issues repository is looking much better already ?
-
Hey there, All in all this sounds like a editor issue, not a ProcessWire issue per se – i.e. for some reason your code editor crashed and emptied the main.inc file, and perhaps deleted / emptied other files as well. Do you have any backups of the site files? It's a bit late to say this, but you should make regular backups of your work. Using a version control system like Git or SVN is preferable, but manual or automatic backups will do as well. If you're using ProcessWire 3.0+ you could take a look at /site/assets/cache/FileCompiler/ – if you're really lucky, you might have a compiled version of your main.inc in there. Although since you're having issues with the site, this seems unlikely. Sorry for not being able to help more here. The thing is that sometimes editors and such mess up, and the best protection you can employ is a version control system, or at least those regular backups. Hope you get this sorted out!
-
What you probably want to do is hook after Pages::saveReady instead. Something like this, perhaps: public function init() { $this->pages->addHookAfter('saveReady', $this, 'checkStateAndHide'); } public function checkStateAndHide($event) { $page = $event->arguments[0]; if(!$page->active){ $this->message("{$page->title} now hidden"); $page->addStatus(Page::statusUnpublished); } } Written in browser and not tested, but that's the general idea anyway. Note also the $this->page->addStatus() -> $page->addStatus() change: here you're trying to change the status of $page, not a class property $this->page. This should also work if you hook before Pages::save and just set the value there, but in my opinion saveReady is usually what you should use. If you hook after Pages::save, the page has already been saved, so you'd need to do another $page->save() or $page->save('field') in order to save any changes – but f you hook before Pages::save or to Pages::saveReady, the page has not yet been saved, so you can just set the value and it will be stored soon enough ? (By the way, you might want to check that the template of this page actually has "active" field – otherwise you could end up in a situation where pages without this field will be unpublished each and every time they're saved.)
-
Old thread and this is a bit off-topic, but this bit caught my attention, so I thought I'd mention it. The Link Checker module I released some time ago (it was never quite finished, hopefully I'll get a chance to work more on it soon...ish) makes use of a crawler script that is intended to run as a background process and (u)sleeps between external requests. Reading this made me wonder if I should rethink my strategy, but a quick Google search for "is php sleep always bad" resulted in this Stack Overflow thread discussing valid use cases for sleep – and sure enough, the first one raised was "some kind of a crawler". I guess there's at least the off chance that what I'm doing is not entirely evil ? That being said, though, I'll have to agree that there are very few valid use cases for sleep, and most situations could no doubt be better handled using a different approach. I'm also pretty sure that Link Crawler is the first piece of production code I've ever used sleep or usleep for ?
-
I wouldn't call that a bug, but it would definitely improve API consistency ?
-
Half joking: the beauty of lawmaking is in that you don't ever have to worry about any of that inconvenient real world stuff. Those abiding by said laws are the ones who have to figure out how to make them work – or not, and risk being penalized ? On a more serious note: automation can't handle all cases, so what this will likely mean is more false positives, more manual work, and more severe consequences when something is reported by real users. From my point of view that won't be a major (or breaking, as some have claimed) change for the entire Internet, but perhaps I'm just not able to see the Big Picture yet. This is awfully optimistic and very much out of character for me, but.. let's just wait and see how this works out. Then again, at this point that's pretty much all we can do ?
-
Every time this topic comes up I'm slightly worried about the relation between any community-led documentation project and the new(ish) API reference at https://processwire.com/api/ref/. This already gets (somewhat?) automatically populated based on the latest core release, and I seem to remember @ryan mentioning something along the lines of updating / releasing a new cheatsheet that would use same data. If that's really the plan, it could easily make any manually updated documentation obsolete. That being said, I'm not 100% sure that this actually was Ryan's plan – or even if it was, is that still true? Additionally it might take a long time before he gets there (he's a busy fellow, after all.) Would be great if the man himself could chime in and let us know what the current plan regarding the docs is, and if we can somehow help make that happen ? One problem with the current, auto-generated docs might be that (as far as I remember correctly) the code that generates it is also powering the (commercial) API Explorer module, which could make Ryan somewhat hesitant to share it with others – which is perfectly fine, of course, but could also mean that we can't do much to help him there. But anyway, this is mostly just guessing. I've been quite happy with the new API reference, with the main problem being that one can't switch between core versions. For us who manage and work on different ProcessWire versions (for me this means everything from 2.2 .to 3.0) that's a major downside: currently when I'm working on anything other than my own projects, where the core version is generally speaking always the latest one, it's much easier to forget the docs and dive into the codebase to see which methods were available at the time.
-
Definitely an interesting move, and I'm also wondering what Microsoft is planning to do with GitHub ? How will the focus of the platform evolve and will there be new restrictions for projects or users? Do they plan to integrate GitHub more tightly with their own tools? Could this mean that they're so attached to the GitHub platform that they need to make sure one of their competitors doesn't buy it first? Or perhaps this is just one more step in their ongoing effort to impress developers? There's not enough data to make any kind of educated guesses yet, so we'll just have to wait and see how it goes. One obvious thing is that a corporate entity like Microsoft wouldn't just go around buying services/platforms for the heck of it, or because said services/platforms have a great community, or whatever. Their primary goal will always be growing their business and bringing in more money – and somehow, directly or indirectly, GitHub is now part of that. Although I'm not particularly worried, I do think it's reasonable to be a bit concerned when a massive corporation like Microsoft buys out a platform as influential as GitHub – especially when that influence is probably most prominent within the open source community and individual developers working on non-commercial projects. Anyway, I can't see how wrecking the legacy of GitHub would be good for their business, so there's (probably) no need to be worried.
-
Fieldtype Page IDs is a third party Fieldtype that, simply put, stores Page references as integers (Page IDs). This fieldtype was built as a quick and dirty workaround for Page Reference fields' inability handle self-references due to circular reference issues. A project I've been working on for a while now includes a combination of RepeaterMatrix content blocks and tagging/categorization system that would've resulted in a lot of duplicate pages (and plenty of unnecessary manual work for content editors) had I used built-in Page Reference fields, and thus a new Fieldtype felt like the most sensible approach. Fieldtype Page IDs was designed to be loosely compatible with Page References in order to make conversions between the two feasible, but it is quite limited feature wise: largely due to the fact that stored values are actually just integers with no connection to Pages whatsoever some advanced selectors and related features are not supported, and page values can't be directly accessed configuration settings are limited to the bare essentials (selector string and Inputfield class) only a handful of Inputfields (AsmSelect, Checkboxes, Text) are (currently) supported Anyway, in case you need to store Page IDs (and Page IDs only) and are happy with the limitations mentioned above, feel free to give this Fieldtype a try. It has been working fine for me in one particular project, but hasn't been tested that much, so please tread carefully – and let me know if you run into any issues. GitHub repository: https://github.com/teppokoivula/FieldtypePageIDs Modules directory: https://modules.processwire.com/modules/fieldtype-page-ids/
-
Just a quick heads up: Modules area of the support forum is intended for dedicated support boards for third party modules. This seems to be a a general / core related issue, so I'm moving this thread to the General Support area.
-
Hey there, @theo! Just wanted to notify you that I'm moving this topic to the "Module/Plugin Development" subforum. The "Modules/Plugins" forum area is where support boards for existing modules live, while all module development related topics belong to the "Module/Plugin Development" subforum. Thanks, and sorry for the disturbance ?
-
@Thomas108: this is a Textformatter module, so you need to enable it via field settings: Setup > Fields > your-fieldname > Details > Textformatters.
-
@horst, sorry to bother you with this (and sorry if it's a dumb question in the first place), but what's the current state of this module like? I'm in desperate need of "pixel perfect" pre-defined crops, and while the focus and zoom feature is really cool, it solves a different problem entirely. Reading some of the posts here I'm wondering if this module is still something I should go with, or do I just need to wait and hope that @ryan decides to add pre-defined crop areas to the core one day? Thanks! ?
-
Depends on your use case, but.. that's not entirely true. When you embed an image into a CKEditor field, for an example, you get to choose from which page you want to pick the image from. Similarly you can request an image from any given page via the API in your template files. So no, an image is not strictly tied to one page: you can embed images anywhere, and you can indeed use them in multiple places on your site. There are also some modules that make reusing media easier, such as MediaLibrary (free) and Media Manager (commercial). It is true, though, that behind the scenes an image is always connected to a single page, and because of that ... A) you can't have a single image showing up in image fields of multiple pages, B) only one copy of each image file is stored in a page-specific directory under /site/assets/files/, and C) if you have restricted access to a given page and enabled $config->pagefileSecure, access to files (including images) on that page will also be restricted.
-
There's a little gotcha related to this module: if you have it enabled on a late version of ProcessWire, it could break the language translation UI if one or more of your translation strings include the phrase "</head>". ProcessPageDelete inserts a script block in front of all of those, which breaks the scripts on the page. None of such phrases in the core (by default) as far as I can tell, but it is found from some rather popular modules (Minify, FormBuilder). Not sure if this module is even needed on newer installations – just happened to have it installed on a site I'm currently updating from 2.x to 3.x, ran into this issue, and thought I'd mention it in case it will save someone else a bit of debugging time