Leaderboard
Popular Content
Showing content with the highest reputation on 06/09/2021 in all areas
-
If the system is working well, and all you want to change is this detail, you can can use the Page Table field (it's in the core, you just have to install it). If all you want is to have an easy way to look at those contacts, and don't mind still having those pages as children, just create a "ProFields: Page Table" field, set "Select one or more templates for items" to "contact", and leave "Select a parent for items" empty. Then add this to your code right after $p->save(); $contacts_page = $pages->get("/contact/"); $contacts_page->of(false); $contacts_page->contacts->add($p); // assuming the name of the new field is "contacts" $contacts_page->save(); If, for any reason, you don't want the pages as children of the contacts page, you can create a page only for this purpose, and set it as the value to "Select a parent for items" in the field. Then you just have to replace $pages->get("/contact/") in the code by the correct parent.3 points
-
If you're seeing an uncaught exception (i.e. an error screen) and have the latest version v4.22.5 Tracy Debugger installed then you might be affected by this issue: https://github.com/adrianbj/TracyDebugger/issues/59 (Update: fixed now in v4.22.6, thanks @adrian) But there's also a core bug that makes the "Move" action appear in Page List in situations where it shouldn't, and I've opened a GitHub issue and suggested fix for that here: https://github.com/processwire/processwire-issues/issues/13943 points
-
Easy ? https://processwire.com/modules/table-csv-import-export/2 points
-
ProcessWire is unopinionated. I get that. It’s a good thing. And yet, this lack of proscription can be bewildering to newbies like me who struggle to figure out how best to accomplish something — even a simple something. Case in point: I’ve created an “organizations” template, and have added a couple of obvious fields to it (sortTitle (fieldText), address (fieldStreetAddress), etc.). Now I realize that I have a bunch of similar-but-distinct bits of information that I’d like to store for each organization — basically, various competing “unique identifiers” such as PURLs, DOIs, ORCids, that kind of thing. Each organization will have 0–n of these, and I’m sure that over the years, more such IDs will crop up, and I’ll want to easily add new ones. So, I could define lots of different FieldTexts (one for each type: ORCid, DOI, etc.), most of which would be empty for most organizations. And then I could continue adding new ones over the years. This seems less than graceful. Or I could (I think) define a repeating field — though I’m pretty sure that would allow me to collect values of such IDs, without saying what kind of ID each was (am I right?), so that wouldn’t be a good plan. Or I could define a FieldSet, which might be more efficient (since it’s just one field), but would have the same long-term drawbacks that using lots of FieldTexts would have. Or I could use a ProField Table … I think. (I’ve purchased ProFields for other reasons, so I’ve no reluctance to go this route if it makes sense.) Or I could create a “Unique Identifier Code (UIC)” template with N FieldTexts defined on it, and could create a new UIC page for each organization that had any kind of UIC. I’m sure there are more options, too — possibly including the best choice. I’ve read (and done!) many of the tutorials, dozens of full forum threads, all of the relevent official documentation, and many module descriptions … and I feel like I know less than I did when I started. So my questions are two: What would you do — and why? Is there somewhere where the community has assembled a list of broadly-agreed-upon best practices for ProcessWire development? Something along the lines of Ryan’s PHP Coding Style Guide? Thanks in advance for all constructive suggestions. I’ve now read a lot of threads in this forum, and I have to say that I’m very impressed with the friendliness of the community, and with the exceptionally high signal-to-noise ratio here. I’ll try not to add too much noise!1 point
-
That's for ProFields Table, but the OP appears to have this info stored in a Page Table. As far as I'm aware there is no way to export the data in a Page Table without writing a custom script.1 point
-
Just follow the instructions on those messages. Add one of the suggested options to the end of your config.php file. This file is situated in the "site" directory of your Processwire install. Be aware that the debug option should be used only only on non public websites, so don't forget to remove it when you publish. Or just use the second option to always allow installing modules via upload. You can also add modules manually via ftp, as you can see on the bottom of your screenshot. Make sure to get yourself acquainted with how to install modules https://modules.processwire.com/install-uninstall/1 point
-
I love the module! I was wondering how do you handle creating a page reference field when the templates and pages are created in the same migration. Because you don't know the id's yet. 'fields' => [ 'pageSelect' => [ 'type' => 'page', 'template_id' => XX, //template ID (foo-template to be created) 'parent_id' => XX // Parent ID (parent-foo to be created), 'inputfield' => 'InputfieldAsmSelect', ], ], 'templates' => [ 'foo-template', 'parent-foo-template', ],1 point
-
@ErikMH Great question. I think elabx has pretty much covered the repeater and table options - both of which work really well. So I'll skip these and just mention a couple of other possibilities, both of which I've used in various sites (in addition to the table and repeater fields) Child pages Repeater Matrix Child Pages It might be possible, depending on you application, just to use child pages to house your set of related items. This won't be the case if you intend using the page url structure for something specific on your site, but if you aren't then you can set up a template per type (one each for purls/orcids etc) and use the template family relationship to restrict the parent-child relationship as needed. Thereafter you would just add child pages to each of your organisations. I use this method in my little invoicing system for the payment methods accepted by each of my personas: Output in the API is simple, just iterate over each of your page's children to produce your output: Repeater Matrix If you have access to the ProFields package, this is probably slightly easier than using regular repeaters as you get to specify the allowed "types" of the items when constructing the field. I also find the interface more intuitive than normal repeaters and the rendering is particularly nice as it allows each item's code to be in its own PHP file. In the case you mentioned (Organisation with 0-n links or IDs of vaious types) I would probably go with a repeater matrix or the Table field as mentioned by elabx.1 point
-
@donatas - the only viable approach is to use teppo's add-on module: https://processwire.com/modules/admin-restrict-branch-select/ Any other approach would be a complete rewrite and would have other complications.1 point
-
I don't think there is a "best practice" written down somewhere for this sort of scenario. I agree it can be confusing to figure out the "right solution" when there would seem to be so manyw ays to achieve the same. If all the values from the identifier are okay with being a text type value, I would go with a Table field with two columns, a Page Reference that fills its options with the "catalogue" of "possible IDs" and a text field that acts as the field for the actual value, this way you can have whatever fields you want on each organization, and you can do stuff like: $pages_with_purls_identified_orgs = $pages->find('template=organization, ids_table.id_type.name=purls'); This also guarantees you can also add new identifiers in the future very easily and consistently. You could do almost exactly the same with repeaters. Why table and not repeater? I just prefer the interface of the table field, I think it's less clunky visually when few fields are involved and has a more snappy feel. If each identifier would need more data added, I'd go for a repeater, but since it seems it's just an ID name and the actual value, table field seems enough. Repeaters would also have the "overhead" of loading an extra page on memory per repeater, since each repeater item is a processwire page. Although another scneario, what if the value of each identifier is a different type, then the table field would not work as nicely. Say you need DOI to be alphanumeric and ORCids to be integers, maybe for this case a repeater could work, with the same catalogue of identifiers, except that you create two additional fields (one text type, one integer type) and show them conditionally depending on the value of the page reference field where the type of identifier is selected. Please take this idea with a grain of salt, just something I came up with right now. It might be a hassle to manage the relationship of "identifier - type of value" on the actual code, or it might be worth the trouble, or there might be a better solution out there ?1 point
-
1 point
-
https://github.com/chrisbennett-Bene/AdminThemeTweaker Inspired by @bernhard's excellent work on the new customisable LESS CSS getting rolled into the core soon, I thought I would offer up the module for beta testing, if it is of interest to anyone. It takes a different approach to admin styling, basically using the Cascade part of CSS to over-ride default UiKit values. Values are stored in ModuleConfig Module creates a separate AdminThemeTweaker Folder at root, so it can link to AdminThemeTweaker.php as CSS AdminThemeTweaker.php reads the module values, constructs the CSS variables then includes the CSS framework Can be switched on and off with a click. Uninstall removes everything, thanks to bernhard's wonderful remove dir & contents function. It won't touch your core. It won't care if stuff is upgraded. You won't need to compile anything and you don't need to touch CSS unless you want to. It won't do much at all apart from read some values from your module config, work out the right CSS variables to use (auto contrast based on selected backgrounds) and throw it on your screen. You can configure a lot of stuff, leave it as it comes (dark and curvy), change two main colors (background and content background) or delve deep to configure custom margins, height of mastheads, and all manner of silly stuff I never use. Have been developing it for somewhere around 2 years now. It has been (and will continue to be) constantly tweaked over that time, as I click on something and find something else to do. That said, it is pretty solid and has been in constant use as my sole Admin styling option for all of those 2 years. If nothing else, it would be great if it can provide any assistance to @bernhard or other contributor's who may be looking to solve some of the quirkier UiKit behavior. Has (in my opinion) more robust and predictable handling of hidden Inputfields, data-colwidths and showIf wrappers. I am very keen to help out with that stuff in any way I can, though LESS (and any css frameworks/tools basically) are not my go. I love CSS variables and banging-rocks-together, no-dependency CSS you can write with notepad.1 point
-
As a designer with limited development experience who found PW a few years back, I can say this discussion has been very encouraging to read. PW has enabled me to make functional sites, but this thread opens my eyes to what’s possible. The last thing you want as someone not well versed in the intricacies of programming is leaving a client in the position of being hampered by the original decision in choosing a platform. For instance, anyone with a non-biased eye can see the real pain die-hard proponents of Webflow vocalize on their community forum. It’s come to an impasse. Whether it’s the limitation of the number of custom fields, or of the number of related records one can have, or the speed of queries, or the responsiveness of the dev UI slowing to a crawl because even a small dataset can make building a site laborious. PW eliminates those pain points. The challenge is communicating its value to a wider audience. My forte is communications, strategy, and brand building. So I tend to look at brand voice as part of evaluating a product or service. The great thing is that PW is architecturally sound. Thanks Ryan and everyone for refining it while keeping it true to its ideals.1 point
-
@fedeb Very interesting, thx for sharing! ? @ryan Wouldn't it be great to abstract all that findings/knowledge into the files API? Importing data from CSV is a quite common need and thinking about all the pieces (like utf8 encoding, wrong delimiters etc) can be tedious and does not need to be ? $file = "/my/large/file.csv"; $tpl = $templates->get('foo'); $parent = $pages->get(123); $options = [ 'delimiter' => ',', 'length' => 100, 'firstLineArrayKeys' => true, ]; while($line = $files->readCSV($file, $options)) { $p = $this->wire(new Page()); $p->template = $tpl; $p->parent = $parent; $p->title = $line['Foo Column']; $p->body = $line['Bar Column']; $p->save(); } Support this request on github: https://github.com/processwire/processwire-requests/issues/4001 point
-
Yes, this is also what I was liking about it. I think the only thing that gave me pause is the development side of it. The plugins don't look as simple to develop as I thought they would be. At least, the learning curve there looks a bit high, and the amount of code to develop something simple seems more than I would have expected. But the same is true of developing CKEditor plugins, and none of those are deal breakers. This seems to be the nature of JS based plugin systems. I do feel like I need to find all the editor.js type options, as I'm guessing there are similar projects we should explore before picking one to build from; even if editor.js seems the most likely at the moment. Sounds awesome. I'd encourage you to release it as a module if you can. The reason I'm looking at two strategies is because I agree that the editor.js approach is great, and probably a good fit for many (or most). But there's also users like Jonathan Lahijani, where the editor.js/bard approach is not nearly powerful enough. The repeater approach does have the power, even if it's not as immediately intuitive. That's why my plan is to further develop RepeaterMatrix to better support those that want to use it as a builder, while also pursing a simpler strategy along the lines of editor.js. Does this mean that either approach is going to answer every need and interest for everybody? That's unlikely, but hopefully it'll be a good start and get the momentum going. If we were to use editor.js, then I wouldn't expect one's template code to consume JSON. We'd map the JSON to an object (or array) so that it could be used just as easily as page fields. Right, same kind in terms of what it stores. In terms of implementation, I think we are talking about 1 core direction, but 2 different directions overall. Neither direction at the expense of the other. A reasonable one that the core provides (editor.js approach or similar). And then upgrades to RepeaterMatrix for those that want to use it as a more powerful builder. So the 2nd option would simply be ProFields RepeaterMatrix, and it wouldn't even be a builder per se, but it would be ready to be used as a builder a lot more than it is now. Not flaws per se, but features that would make it better support use as a builder. That's what I'm looking to add. For a repeater matrix based builder, this would be at the discretion of the developer as to how and what they wanted to store. So in your case you might want to store something more abstract, whereas someone else might want something directly tied to their output framework. For the simpler/editor.js type builder, I don't think it would get into this type of layout thing at all. This is all true, I don't think you would be able to on the editor.js side. The elements are defined by editor.js plugins, static code. Just like CKEditor plugins. Though we'd probably bundle a lot of plugins and build some of our own. Ultimately the editor.js route will never be as powerful as the repeater route in this regard. But it will be very easy to setup and very accessible. This is something Jonathan and I discussed on our call last week. The storage behind Repeater/Matrix is overkill for the needs of a builder, so what would be ideal is if repeaters had an option to merge some of the storage needs. It's something I'm going to be looking into, though I'm not yet sure what's possible. This is basically what the new Combo field does. Though they are connected to the database, but a repeatable Combo field wouldn't require pages for storage the way Repeaters do. Nevertheless, for a builder, it seems that the underlying pages do bring a lot of benefits, even if they are overkill for the need. This is already true. But I still think the two-tier route offers the most benefits. On one side something simple like editor.js, and on the other side, something ready for more complex needs based off an existing Fieldtype like RepeaterMatrix. Also, Bernhard's solution in the other thread looked pretty great too; he said it was similar to repeaters in some fashion, also using pages from what I understand. Will do. That's true. Use ProcessWire (or any other tool) for what it has right now. You are right there are no guarantees about which features or ideas will be implemented, even for me. There have been cases where someone needed something and decided to sponsor it for the community, by hiring me or someone else in the community to build it. Outside of that, I have to find a crossover between feature requests and the needs of the projects that I work on with my clients, or with Pro modules. I can't afford to build features just for the sake of building them; I still have to find a way to fund them and then support them afterwards. The way I do that is by developing stuff that finds a balance between client needs and project needs. That way I don't have to bear all the development costs myself. The Pro modules also help to fund the core, though they also are significant projects in their own right, so I try to put much of Pro module budgets back into Pro modules themselves too. Though I put the question out there because I thought this year I could get into a couple of things that go beyond the usual development path. I'm admittedly cautious about what gets pulled in, and there's no guarantee that a PR submitted without prior discussion will ever be added. I'm also serious about supporting this project for 10, 20 years or more, so anything that gets pulled in also becomes responsibility to support it for life. The person that submits the PR does not have that responsibility. I need to make sure I fully understand and can support anything that gets pulled in. I also have to make sure it's worthwhile for the majority of users. So my preference is for PRs to be preceded by a discussion before someone creates it, so that we can evaluate needs and timing, etc. Sometimes something can be added very easily and without a lot of investment to review and understand it all, and I try to cover those once a year, or more if possible. The guidelines are here (https://github.com/processwire/processwire/blob/master/CONTRIBUTING.md) and while they do touch on this, they could go further. I will work on that. Thanks.1 point
-
Maybe a sign that it's times for a break ?. Sometimes it helps to 'speak out your code' to determine if it makes sense. Have a look at that line. tableofcontents_table, I assume, is your Profields Table. Reading that out loud, your code is saying, find me siblings (PLURAL) of this page and get me the value of its (SINGLE) tableofcontents_table field. Doesn't sound right, does it? It's like saying 'find me 10 oranges (PLURAL) and show me its (SINGLE) price. That's wrong. The question would be, which orange's price? We have 10 oranges here! It should read, 'find me 10 oranges (PLURAL) and show me their (PLURAL) prices. Aha, so, we are dealing with a collection. Any collection has to be iterated (foreach) to get each members individual value. Alternatively, you could ask for the first(), last() or nth() orange to deal with one member only. OK, so I need to get some sleep too. The docs say this about $page->siblings(): $toc is a PageArray. If you run this in Tracy console: <?php d($page->siblings("template=tableofcontents")->tableofcontents_table);// null You will get the value null, hence your error message since you are doing this null->render(). Now for some unsolicited advice ?. TracyDebugger is your best friend. The table clearly is there and clearly is a sibling and its template is as stated and the table also. Whilst this might be the case, it is best to always check if your selector/query returned something (and its type) before you start working with it. Hope this helps. ps: Profields Table has its own VIP support forum, accessible to you if you have a current subscription1 point
-
If you're dealing with multiple timezones I'd strongly suggest not involving the db in it. There are two types of datetimes: absolute time (times you want to compare with each other even across timezones) and wall time (11 o'clock stays 11 o'clock for your user). Because timezone defintions can potentially change for future datetimes it's not always as easy to keep both properties as one might think. If only the first one is important to you you should keep everything in UTC. If only the last one is important you could use a datetime in the timezone of the user, but it's rarely the case you don't compare timestamps or it doesn't become a requirement (e.g. for ordering). For past datetimes it's enough to store a utc timestamp and the timezone of the user to get to both the absolute time and the wall time as timezone defintions rarely change in retrospect. For future datetimes you'd need to make sure to save enough information so you can detect changes in the timezone definition when they happen. Then you or your user can decide if absolute time or wall time was meant to be consistent.1 point
-
There's native `Fieldset in Tab` for creating editor tabs, but sometimes it could make more sense to put a field that's not directly related to `Content` into `Settings` or `Children` tab (such as for body class or some toggles that I see being used often). You can use the hook below to move fields between the tabs. // site/ready.php wire()->addHookAfter('ProcessPageEdit::buildForm', function (HookEvent $e) { // make sure we're editing a page and not a user if ($e->process != 'ProcessPageEdit') return; // RESTRICT BY TEMPLATE // $page = $e->object->getPage(); // if ($page->template != 'home') return; // RESTRICT BY ROLE // $user = $e->user; // if (!$user->hasRole('editor')) return; $form = $e->return; $contentTab = $form->children->get('id=ProcessPageEditContent'); $settingsTab = $form->children->get('id=ProcessPageEditSettings'); // $childrenTab = $form->children->get('id=ProcessPageEditChildren'); // if page template is set noSettings = true, $settings will not exist if (!$settingsTab) return; // MOVE TITLE FIELD TO SETTINGS TAB $title = $contentTab->get('title'); if (!$title) return; $contentTab->remove('title'); $settingsTab->prepend($title); });1 point
-
https://www.baumrock.com/portfolio/event-voting-tool-social-impact-award/ Another nice little Showcase of what can quickly be done with Processwire I sponsored this voting tool for the Austrian Social Impact Award ceremony (https://socialimpactaward.net/) helping them to pick the winner of the audience voting. The site is based on the default UIKIT theme (obviously) and i basically just placed the logo + changed the colors. The site structure is also very simple, having only one parent to store all teams, one parent to store all votes and one page to show the results (to the admins): The Projects-Template stores some informations of the project and the vote-count: All the votings are single pages as well having only one checkbox, ensuring that every code can only vote once (every visitor got one code at the entrance): Votes are created via Tracy Console as easy as that: The hook that creates the passwords is also simple: /** * create unique code for voting */ $wire->addHookAfter('Pages::saveReady', function($event) { $page = $event->arguments(0); if($page->template != 'vote') return; if(!$page->title) { $rand = ''; while(!$rand OR pages("title=$rand")->count() > 0) $rand = randomPassword(); $page->title = $page->name = $rand; } }); And finally the check if the vote for this code is already done (inside the vote-template). the whole vote-template is as simple as that (thanks to the awesomeness of markup regions and functionsapi): <?php namespace ProcessWire; // handle votes (url segments) if($id = $sanitizer->int($input->urlSegment1)) { // if voting is locked redirect to thankyou message if($page->votingdone) $session->redirect($page->url); // else set voting $team = pages($id); if($team->id) { // increase voting for this team $team->setAndSave('votes', $team->votes+1); // lock this votings page $page->setAndSave('votingdone', 1); } } ?> <?php // if voting is done show thank you and lock page if($page->votingdone): ?> <region id="main"> <div class="uk-card uk-card-primary uk-card-body uk-width-1-1 uk-margin-small-top uk-text-center uk-border-rounded"> <h3 class="uk-card-title">Danke für Ihre Teilnahme!</h3> </div> </region> <?php return; endif; ?> <region id="main"> <div class="uk-text-center uk-margin-top"><?= $page->parent->body ?></div> <?php foreach(pages('template=team, sort=random') as $team): ?> <div class="uk-card uk-card-default uk-card-body uk-width-1-1 uk-margin-small-top uk-border-rounded"> <h3 class="uk-card-title uk-text-center"><?= $team->title ?></h3> <ul uk-accordion="collapsible: true"> <li> <p class="uk-accordion-title uk-text-center"><span uk-icon="icon: chevron-down"></span> Beschreibung anzeigen</p> <div class="uk-accordion-content"> <?= $team->body ?> </div> </li> </ul> <a href="<?= $team->id ?>" class="uk-button uk-button-large uk-button-primary uk-width-1-1 uk-border-rounded">Für dieses Projekt abstimmen</a> </div> <?php endforeach; ?> </region> I'm still impressed by ProcessWire and how much can be achieved with how little effort1 point