Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 10/05/2019 in all areas

  1. Last week I worked primarily on GitHub issues, and did some of that this week as well. Likely I'll be doing a lot of this in October. Thank you for all of your reports. While there's already a lot of commits on the dev branch, I'm going to wait till next week to bump the version, as I've got some stuff in progress that I want to get committed first (more on that below). Next week I'm releasing version 40 of FormBuilder that supports paginated forms, as well as forms within forms (not to mention some other minor additions). Basically, all the stuff that was covered in this video from a few weeks ago, plus a little more. I actually think it's ready right now, but as is often the case, I started writing instructions for using the new features today and thought of a couple minor tweaks that would be helpful along the way. So I'm going to apply those early next week, finish the instructions, test it all out again, and then release it... likely mid-week next week. For the ProcessWire core, one feature people have been asking for for quite awhile is the ability to specify custom fields with file and image fields. I've been working on that here quite a bit this week, and have the initial test cases working quite nicely! Unlike the Description and Tags fields that come as built-in options with file and image fields, the new option instead uses a subset of ProcessWire's Fieldtype and Inputfield modules to support this (note: it does not use pages like repeaters do). This gives you more flexibility in defining what you want and how you want it to look. Though there are some limitations of what kinds of fields you can use here, but I think you will like what it offers and how it works. For those that just need a description and/or tags, then of course those features will remain as they are. But for those that need something more for file/image fields, you are going to have a whole lot of new options in 3.0.142. Unless I run into any roadblocks in finishing development of this part, I'll have it ready by this time next week along with a blog post that outlines it in more detail.
    7 points
  2. Hi everybody, having worked mostly in the backend for the last weeks and having an upcoming project where I need some frontend stuff soon, I played around with a new concept of creating frontend themes for ProcessWire. That idea is not new... Nico built WireThemes back in 2014 and @teppo has recently launched WireFrame. I've also built two websites using this module (screencast) but that turned out to be too complicated and it was also working only with the uikit frontend framework. But still, it feels like I'm doing a lot of unnecessary work with every frontend project: Getting the framework Setting up the design Setting up the menu Setting up the correct dependencies (scripts, fonts, icons, etc) Setting up the config (markup regions etc) Setting up site settings (logo upload etc) etc, etc A lot of this stuff is the same for every site, so I'd really like to have a solution that is plug&play where I just have to do the customizations and not reinvent the wheel over and over again with every project. Also, I'd like to have everything in place so that I can just git clone a theme and share one theme across multiple projects (just think about the site header with favicon, seo and social tags!). Meet RockThemes ? As you can see in the video, the process is quite straightforward. Just install RockThemes and copy your theme to the templates folder (and set $config->theme to point to that folder, which was already in place in the video). The current status is quite promising: Themes stay entirely in the templates folder One year ago I decided to create themes as PW modules. That makes things complicated because assets are blocked by .htaccess from direct public access! Now themes live in /site/templates and assets are easily accessible for the public. The module uses Markup Regions by default They are great and offer so much flexibility and power. They are perfect for such a module ? The template files stay clean and easy, eg the footer file of the theme: <region pw-replace="footer"> <p>Powered by <a href="http://processwire.com">ProcessWire CMS</a> &nbsp; / &nbsp; <a href="/admin/">Admin Login</a></p> </region> Or the basic-page template (that gets the date from the site profile's template file and just populates the regions): <?php namespace ProcessWire; $sidebar = null; include("../basic-page.php"); ?> <region pw-replace="mainleft"> <h1><?= $page->title ?></h1> <?= $content ?> </region> <region pw-replace="mainright"><?= $sidebar ?></region> Themes are extendable This means that you can build one default master theme that you share across your projects and then create one custom theme per project that only contains the files that you need to change. The module supports any CSS framework I've built a base module that can be extended for every framework. The base module will consist functions that every project needs (eg for rendering favicon markup or SEO tags). The framework version will then extend this module with framework specific functions like rendering a menu or rendering paginations. Switching layouts is as easy as changing one file default.php <div class="uk-container"> <section id="header"></section> <hr> <section id="main"> <div class="uk-grid-divider" uk-grid> <div class="uk-width-expand"> <div id="breadcrumbs"></div> <div id="mainleft"></div> </div> <div class="uk-width-1-3@m" id="mainright" pw-optional></div> </div> </section> <hr> <section id="footer"></section> </div> colorful.php <section class="uk-background-primary uk-light"> <div class="uk-container" id="header"></div> </section> <section class="uk-background-muted"> <div class="uk-container"> <div id="breadcrumbs" class="uk-margin-top"></div> </div> </section> <section class="uk-section-small" uk-height-viewport="expand: true"> <div class="uk-container" id="mainleft"></div> </section> <section class="uk-background-muted uk-section-small" pw-optional> <div class="uk-container" id="mainright" pw-optional></div> </section> <section class="uk-section uk-background-secondary"> <div class="uk-container" id="footer"></div> </section> All other files are unchanged! This of course only works if the regions are named exactly the same. That would lead to the challenge of having the same region names across our themes. I guess that's the case for all CMSs that have theming support? I can remember the times when I worked with joomla (content-top, top, header-a etc). Would it make sense to create a master layout that can be used for almost every project? What regions are you using in your projects? I think such a frontend framework could open up a lot of possibilities. It would for example be a lot easier to develop helper modules for the frontend (think of RockTabulator or something like FREDI) because we would finally have at least a very basic standard how things are done (eg how to add assets to the <head>). It could also be easier to work on projects in a team, because everybody would know how things work. Though, I'm still not sure if such a module would make sense for the public at all. I'd be especially curious what @teppo thinks about that and how you see that approach compared to WireFrame (I wanted to use it before I started this module, but it did not feel right for me). Maybe that's exactly the problem: When it comes to frontend framework / theming approaches things just don't feel right, because everybody is so used to his workflows. So what do you guys think? Would such a module make sense to you? Would you be using it? If yes, what would be necessary features? What would be no-go's?
    5 points
  3. Hey Bernhard! A few initial observations and notes – I will have to dig into your post deeper and check the video when I'm back home. On a trip at Spain at the moment, and the network connection here is... limited ? First of all I still find the idea of themes intriguing, but it's also a complex matter, and there are different aspects to consider. For an example WordPress has (as most here probably know) made great effort to support themes – yet in reality you cannot just switch between themes as you want (which is, in my opinion, a key point in the themes vs. starting profiles discussion) if you have something "out of the ordinary" going on: custom fields, custom views, plugins generating markup, etc. Wireframe doesn't actually try to solve the theming part. In fact it's quite the opposite: it's a framework that provides sensible structure for sites built with ProcessWire – one that separates the implementation into different files/classes ("business logic" vs. views vs. layouts and so on) in a meaningful way, allows for reusability, and continues to make sense even if/when the site scales. While it can be easy to make visual changes to a site built with wireframe – as long as it's used in its entirety, in which case making changes to a single layout file is often all you need – that's really the extent of it. The kind of things you've mentioned, like getting the framework and setting things up, are in that context resolved with site profiles: if you find yourself repeating these tasks over and over, you should build a site profile where you've got the defaults nailed down – or, if you find you often just swap the logo etc. then add a settings area and a custom field for it. The "official" Wireframe boilerplate is one of those, and here at Avoine we've got our own "boilerplate" specifically tailored for the type of sites we work with (and what you've listed are (some of the) things we've covered in it). Long story short: I think we're solving different problems, and as such I wouldn't draw too many lines between those two solutions ? I do agree that you're onto something here, though, and see a need for that. The way you've described RockThemes sounds pretty close to how WordPress works, although I've not had the chance to dig into all the details yet. For an example I don't have a good idea about how much you're planning to let a specific theme override vs. how much you plan to keep things "set in stone". That, I think, is actually one of the most important factors here: figuring out how much you can/should standardise stuff, and if one can "break loose" of the theme by overriding it in a way that changes it radically. ... and that, of course, depends on how far you want to go in terms of "themeability": if one wants to switch a theme and it should always "just work", you might go as far as define basic views and features (such list and archive views etc.) so that theme authors know what to provide markup/logic and styles for. On the other hand if it's enough that the layout is interchangeable and all content types (templates) that don't follow some specific convention (title and body fields, or something like that) will need per-site markup, then a much simpler approach is going to be quite enough. My "a few initial observations" got a bit out of hand, but I'll definitely check the video etc. later. And sorry if I've missed any important points here ?
    4 points
  4. @Orkun, do you know about $page->listable()? It determines whether a page may appear in Page List (and also PageListSelect inputfields, which is probably something you want too). So you could do: $wire->addHookAfter('Page::listable', function(HookEvent $event) { /* @var Page $page */ $page = $event->object; if(!$page->editable() && !$page->addable()) $event->return = false; }); You can hook ProcessPageListRender::getNumChildren to customise the child count. But in some cases depending on what is determining a page's listable status you might decide it's not worth the trouble. Here's one way you might do it (in /site/ready.php): // Work out which templates are editable or addable for the user and store them on the $user object // Doing this here to avoid doing it repeatedly in the getNumChildren hook if(!$user->isSuperuser() && $page->template == 'admin') { $user_roles_ids = $user->roles->explode('id'); $allowed_templates = []; foreach($templates as $template) { $edit_add_roles = array_merge($template->editRoles, $template->addRoles); if(count(array_intersect($user_roles_ids, $edit_add_roles))) $allowed_templates[] = $template->name; } $user->allowed_templates = $allowed_templates; } // Set a selector to correct the children count $wire->addHookBefore('ProcessPageListRender::getNumChildren', function(HookEvent $event) { $user = $event->wire('user'); if($user->isSuperuser()) return; $selector = 'template=' . implode('|', $user->allowed_templates); $event->arguments(1, $selector); }); Be aware that there are some other areas you probably want to consider if you are hiding pages in Page List. Here are some pointers to get you started: Pages that can be found in the admin search - look at manipulating the selector by hooking ProcessPageSearch::findReady Pages that can be found in Lister - look at manipulating the selector by hooking ProcessPageLister::getSelector
    2 points
  5. @ryan Oh WOW, a dream comes true! ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    2 points
  6. Hello @bernhard, What I think? Briliant, I like your thinking here! It would definitely make sense to me, in fact I have 2 sites I would like merged into one system that allows use of all functionailty of the two sites with ease of changing the look and feel front end, but with proven abck end system in place Necessary features? - Repeater matrix list of reusable sections to easily build pages - Easy way of changing the look and feel of a whole site by changing as few things as possible Good stuff Bernhard!
    1 point
  7. I don't want to derail this thread, but just want to say thanks so much for mentioning this. Coincidence or not? Just today someone on a client project mentioned SonarCube (which is basically the same, but installed locally, and also from the same company), and now I took a look at SonarLint, which can be added to IDEs as plugins. I will definitely try out their IntelliJ plugin. Judging from the SonarCloud results for WireFrame, it really sounds like a great tool. Sort of like ESLint, but on steroids :-) The estimated "time to fix" and references to rule (definitions) are a nice touch.
    1 point
  8. Just played around with your example and did a little refactoring ? Thx for sharing your code! $this->addHookAfter('ProcessPageList::find', function(HookEvent $event) { $pages = $event->return; $excludePagesByTemplate = array('admin', 'basic-page'); $pages->each(function($p) use($pages, $excludePagesByTemplate) { if(!in_array($p->template, $excludePagesByTemplate)) return; if(!$p->editable() && !$p->addable()) $pages->remove($p); }); $event->return = $pages; });
    1 point
  9. It looks like a hook to ProcessPageList::find is working. Here is the code $this->addHookAfter('ProcessPageList::find', function(HookEvent $event) { // Get the object the event occurred on, if needed $ProcessPageList = $event->object; // An 'after' hook can retrieve and/or modify the return value $return = $event->return; // Get values of arguments sent to hook (if needed) $selectorString = $event->arguments(0); $page = $event->arguments(1); $excludePagesByTemplate = array( "newsletter-clinic", "sender_2016", "sender_2016_collab", "inside-news-folder", "basic-page", "event-clinic", "domain_root", "brandportal-index", "key-figures", "jobs", "news", "media-mirror", "worker", "xmlexport", "weekly-menu", "intranet_domain_root", "weekly-menu-index", "daily-menu", "daily-menu-index", "benefit", "benefits-index", "pdiatres-de-garde-index", "xml-feed-index", "courses-index", "help-doc", "stocks-index", "dictionary", "iPad-PDF-Index", "pkb-pikettdienst-index", "heisser-stuhl-index", "heisser-stuhl" ); if($return instanceof PageArray){ foreach($return as $p){ if(in_array($p->template->name, $excludePagesByTemplate)){ if(!$p->editable() && !$p->addable()) { $return->remove($p); } } } } $event->return = $return; }); KR Orkun
    1 point
  10. Can't you just add a CSS class to uneditable pages, and use display: none on these? Or maybe check with JS for absence of li.PageListActionEdit and then add a hiding class in the parent div. As for unaddable pages, check for absence of li.PageListActionNew.
    1 point
  11. Updates ? https://2017.stateofjs.com https://2018.stateofjs.com/ https://2019.stateofcss.com/
    1 point
  12. Actually I came to a pretty handy solution with my co-dev! Images have information about their modification time saved within them, so using that I came up with following code: $img = $page->image; // check if image exists if($img) { // fetch cropped images' modification timestamps $tsNormal = filemtime($img->getCrop('normaali')->filename); $tsHigh = filemtime($img->getCrop('korkeampi')->filename); $tsLow = filemtime($img->getCrop('matalampi')->filename); // check if they have the same modification time => user hasn't cropped the image, so use the original if(!($tsNormal == $tsHigh && $tsNormal == $tsLow)) { // stamps are not equal => check which is highest aka last modified switch(max($tsNormal, $tsHigh, $tsLow)) { case $tsNormal: $img = $img->getCrop('normaali'); break; case $tsHigh: $img = $img->getCrop('korkeampi'); break; case $tsLow: $img = $img->getCrop('matalampi'); break; } } } Seems to work quite nicely for my purpose ?Thought it would be nice to share, if anybody else wants to achieve similar effect!
    1 point
  13. Please point me to some examples, thanks. Hi Kongondo... So I'm not sure if this is what B3ta is referring to - one solid piece that has gone through a bit of a wringer in terms of testing and configuration/transformation over the years is CS-Cart, which was originally in itself an offshoot of X-Cart. I believe both carts now have multishop setups. I am more familiar with the CS-Cart edition. Its a bit tricky, because on some level the owner needs to be able to decide if they want to have one unified database in the backend for various shops (the 'food court') model where you have multiple shops for different types of food but they all share one big common kitchen in the back and also share the credit card processing. Or the subcontract model where each store on the back end has its own unique instance in place with a universal dashboard that allows an admin to oversee everything. My advice, do not touch it with a 10-foot pole. As much as I love the idea, in practice the coding and debugging required has been a real nightmare/evolution for other products. How deep will admin go? Will customers be shared? Will customers use different logins for each storefront? Do cart contents carry over from one store to another? Do all storefronts have the same shipping and tax rules? Is there a shared pool of inventory that only the admin sees and that sub-storefront admins can pull from? Are products added by sub-storefront owners shareable? There are just a ton of variables laid on top of the shopping cart platform which already has a tendency to become super bloaty and confusing. CS-Cart made some serious errors during the evolution of their product, it has taken many years for them to iron own the kinks and hurt feelings that multi-vendor has created. I'd love to see a step up from padloper in terms of interface-in-place. Looking forward to the alphabetagamma.
    1 point
  14. To get the options title in current user language use $type_material->getTitle(); or enable outputformatting $type_material->of(true); $type_material->get('title');
    1 point
  15. Actually, it's pretty nice running your API call through the Tracy Console - save it as a snippet so you always have it on hand. This way you can easily see the results of the selector as well as the SQL query used to generate them. PS I think this is the thread that was mentioned regarding teppo's version: https://processwire.com/talk/topic/9408-is-there-a-way-to-convert-a-selector-in-sql-using-pw-engine/ although I think it's actually longer.
    1 point
  16. Your if-statement probably has not worked, because you don't have an input type submit in your form. Instead you have an button with the type submit. Then your original if-statement should work. if ($input->post->submit) { // Form was submitted } else { // Form wasn't submitted } Also I would recommend again to get and sanitize the input from code like mentioned above. Especially if you want to use it as a page name, the corresponding sanitizer is meant for this. You can set a new value for an existing field using the API like this: $p->of(false); // Shortcut for setOutputFormatting(false) $p->set("title", $sanitizer->text($input->post->title)); $p->save();
    1 point
  17. You can set up customs selectors or even PHP code for page fields. I don't think there's a selector for this case so you might want to add PHP code that collects all grand children and returns it in a new PageArray: $rtnPages = new PageArray(); foreach ($pages->get("/items/")->children as $categories) { $rtnPages->append($categories->children); } return $rtnPages; Or if your items in the categories have a certain template you can select by template: template=template-name
    1 point
  18. ...and among a million other reasons, it's responses like this that make Processwire incredible. There's a lot in there I can learn from. Thanks for sharing.
    1 point
×
×
  • Create New...