Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/11/2021 in all areas

  1. @jploch You're mixing up storage and public API, which is not a good idea. JSON is a storage / transport format, it's always a string which contains a serialization of data. The purpose of JSON is to store or transmit data in different formats between systems – like your database, your server and the client's browser. JSON is also language-independent – you can decode a JSON-string in JavaScript and in PHP. But as soon as you do that, the result is that language's default representation of that JSON string. For PHP, this means you get either a stdClass object or arrays (depending on the flags you give to json_decode). So you need to ask two different questions: What is the best way to store my data, and what is the best way to present it to a user of your module? Data representation Of course you can just json_decode the JSON string and pass the result to the user of your module. But that's a bad idea: You have zero guarantees regarding the structure of your data. You won't notice if your data is missing a specific field, some field is an integer instead of a string, your items are indexed by page name instead of key or whatever else. This will cause errors that are very hard to track down. The user has no indication how your data is structured – to figure that out, I will either have to refer to the documentation for everything or have to dump stdClass objects and figure things out from there ... You can't have nice things like code completion, proper IDE support etc. Instead, you want to parse that unstructured data into a representation (usually, a set of classes) that guarantees a specific structure and has a proper public API for access and modification of the data. Using proper objects with type-hinting will also allow you to find any errors in the structure and abort the process at parse time with an appropriate error message (see Parse, don't validate for an in-depth explanation). For example, to represent your data, you might use classes like PageBuilderEntry and PageBuilderItem to represent a list of items with meta data (the breakpoint fields, in your example) and individual items, respectively. The you can provide utility methods for different use cases – for example, methods to get a list of items indexed by key or by any other field. If you want to build closer to ProcessWire, you can also use a class that extends WireArray to represent a list of items, this will give you many helpful methods (like getting an item by key) out of the box. For the items themselves, you might just reuse the page itself (if the IDs correspond to 'real' pages in your system) or extend the Page class. Data storage Separating the representation from the storage makes the specific structure you store your data in less important, since only your module will interact with it. Just build a static helper method to build the appropriate representation based on a JSON string (e.g. PageBuilderEntry::fromJSON) and a method to encode that representation back to JSON (PageBuilderEntry::toJSON). The fromJSON method is responsible for parsing the data and throwing the appropriate error when it's not in the expected format. That said, personally I usually prefer regular arrays instead of maps for storage, because it's easier to parse and massage into different formats. But again, it depends on how you want to represent the data.
    5 points
  2. @Robin S, They don't pay you enough. Just sayin' ?
    3 points
  3. Page::__construct() takes a Template object as an argument: /** * Create a new page in memory. * * @param Template $tpl Template object this page should use. * */ public function __construct(Template $tpl = null) { if(!is_null($tpl)) { $tpl->wire($this); $this->template = $tpl; } $this->useFuel(false); // prevent fuel from being in local scope $this->parentPrevious = null; $this->templatePrevious = null; $this->statusPrevious = null; } So I think the constructor in your child class should be: public function __construct(Template $tpl = null) { parent::__construct($tpl); $this->header = 'some text'; }
    2 points
  4. As long as the user has edit access for the template, you can use "Additional edit permissions and overrides" at Edit Template > Access:
    2 points
  5. Another quick and easy one ? Place this in /site/templates/admin.php before the require(...) statement: $this->warning('Attention: We have planned maintenance starting 2021/02/11 from 10:00 AM - log out before that date to prevent data loss.');
    2 points
  6. Shetland.org is a website run by Promote Shetland which inspires people to visit Shetland, encourages people to move to Shetland to live, work and study, and attracts people to invest in commercial activities in the isles. We (NB Communication) have run the Promote Shetland service on behalf of the Shetland Islands Council since 2017, and as part of the contract undertook a project to redevelop the existing Shetland.org website. In this showcase we’ll highlight a selection of modules we used and what they helped us achieve. Visit the site: www.shetland.org Pro Modules ProCache We use this on almost every site we build. Indispensable. The cache settings used are pretty simple – most templates are set to 1 week, with the entire cache being cleared on save. We use ProCache’s CDN functionality to serve assets from CloudFront via c.shetland.org. We also use the API provided by ProCache to compile (SCSS), minify and collate our styles and scripts via $procache->css() and $procache->js(). We then use the URLs returned to preload the assets, making the site even faster! ProFields: Repeater Matrix Again, we use this on almost every site we build. Another must have Pro module. This module allows us to create a really powerful page builder field (we call it ‘blocks’) that handles the majority of the content on the site. On a simple development, we just use two block types - Content and Images - the latter displaying as a gallery or a slideshow. On this site we have 13 different types, including ‘Quotes’, ‘Video’, ‘Accordion’, and ‘Links’. Additionally many of these are configurable in different ways, and some render in different ways depending on the template and context. Have a look at the links below for some examples: https://www.shetland.org/visit/do/outdoors/walk https://www.shetland.org/blog/how-shetland-inspires-me-artist-ruth-brownlee https://www.shetland.org/life/why/teach-shetland-school NB Modules We also used a number of modules we've authored: Instagram Basic Display API Used to retrieve the 6 latest images from instagram.com/promoteshetland. Markup Content Security Policy Used to implement a CSP for the site. Currently scoring a C on observatory.mozilla.org – not the best score possible but significantly better than all the other destination marketing websites I tested (all got an F but one which was a D-). Pageimage Srcset Used throughout to generate and serve images of different sizes via the srcset and sizes attributes. This module is really useful if you are looking to optimise the serving of images to improve page speed times/scores. Video markup for YouTube/Vimeo This module was developed specifically for use on this website, as we wanted more control over the rendering of the oEmbed data. In the example below, the video thumbnail is displayed with a text overlay – when clicked the video (YouTube embed) opens in a lightbox. And a big shout out to… Page Path History The previous site was also built by us in ProcessWire, but a number of years ago now. The new site has significant changes to the sitemap, but 1000+ blog posts were also migrated. Instead of an .htaccess file with thousands of 301 redirects, we were able to use the functionality provided by this module to implement redirects where required, and in the case of the blog posts which were migrated via an import script, implement the redirects via the API - $page->addUrl(). ... The above is just a fragment of the features present on this site, and the development just a part of a much larger project itself. We're really proud of what we've achieved, and we couldn't have done it without ProcessWire. Cheers, Chris (NB Communication)
    1 point
  7. It's too early to access page fields/properties in the constructor. There is a ___loaded() method that's called when the page is loaded and ready. So you could have this: public function ___loaded() { $this->header = $this->title; }
    1 point
  8. I don't mind about the sort order if you guys think changing it will be an improvement. Having "Main setup" in the middle seems a bit unusual but not a big deal.
    1 point
  9. @fruid Have you tried to hook ProcessPageAdd::executeTemplate or ProcessPageAdd::buildForm?
    1 point
  10. I just added some new features. – All blocks can be cloned now. Which makes adding content very fast – More options to control access of blocks individually. You can lock editing of blocks completely or disable features such as cloning, styling or content editing for certain roles I was also thinking about the best approach to copy blocks between PW installations or to share them with others. The easiest way I found was to export/import a page, with all the blocks you want added, using adrians migrator module. The export code together with the block template files could be shared with others or imported into existing installations. So this would be an option until we hopefully have something in the core to make migrations work better. An alternative would be to store everything as JSON (including the content) and using something similar to the Mystique Module to let the developer add fields based on config files. That also has the benefit of being able to have the files version controlled. The downside of using the JSON only approach would be inferior searchability of fields. Also making it work with every fieldtype would be a challenge. I'm interested how others feel about this.
    1 point
  11. Lol you're not alone, I struggle a bit sometimes too... To tell you the truth here was my train of thought: when trying to replicate your situation by adding several templates as authorized children, I came across the ProcessPageAdd module settings, and thought I might take a look at its code to see where it does the check to pull out the available templates. And then I finally stumbled upon this option I linked above... In your config.php file (in the /site/ folder), you can just add a line $config->pageAdd("noSuggestTemplates", true) So no need for a hook. Let me know how it goes.
    1 point
  12. I have builder system with PageTable input field, Text field is InputfieldText Field (Searchable) Properties field is Mystique Field (Limited search support) Current Mystique field version support search limited. Working with next version on my side and it will support searching.
    1 point
  13. I've never had your situation so I wanted to be sure first. I quickly had a look at the code and I found this "Disable suggestions" option in $config->pageAdd, maybe try this ?
    1 point
  14. Does the parent page need to accept multiple templates as children ? If not you can set this in the "Family" tab of your template to only allow for one template, and then it will be automatically selected upon page creation.
    1 point
  15. @szabesz - thanks for your thoughts on the settings. One problem with setting those checkboxes to use columns is this: https://github.com/processwire/processwire-issues/issues/1327 Regarding the quicklinks being in alphabetical order. I kinda agree with you, but I @Robin S thought the matching the order of the settings was better. I'd be willing to change, but given that this is his feature, I'd like his OK first. There are direct links to settings at the bottom left of each panel. I think that is probably enough, but I could consider adding them to the Panel Selector as well if you still think it would be helpful. Not sure about the scroll to top button - it feels a bit out of place in Tracy, but I'll think it over. I'll also have a think about the server type indicator frontend/backend changes - that seems like a good idea.
    1 point
  16. @jploch You can check my Mystique module
    1 point
  17. @MarkE There's currently no direct way to do this — the chart data is passed as a JSON blob, so no functions. I've been looking at setting up charts via JS files or JSON endpoints, but nothing concrete yet. I'll probably end up moving the chart panel to a chartkick.js implementation which would allow all of that.
    1 point
  18. This is the way. Performance is relative. Using a hook to check if a duplicate record exists will always be fast, or at the most have linear complexity. How many users do you expect to add each day? How many users / people entries in total do you have? If it's 10 million, then you'll have to start thinking about the performance of a uniqueness check, but if it's significantly less ... Besides performance, what other benefits do you hope to gain by using a unique index in SQL as opposed to a custom check on the interface-level (i.e. a ProcessWire hook)? The only thing I can think of is that uniqueness is guaranteed at database level, but is that going to matter to you? If you use the right hook, you can prevent duplicate entries from both the CMS interface and ProcessWire's API, so unless someone is going to manually insert records to your database through the command line, the result is identical. By the way, the unique setting for pages guarantees a globally unique page name, not uniqueness of an individual field. Just set the name to include the first name, last name and address (you can do that through the template settings or use a hook if you need more control) and use a hook to set new pages to unique. This will guarantee uniqueness for that combination of fields. Granted, it's only guaranteed on API level, not database level, but again, this might be absolutely enough for your use-case.
    1 point
  19. In my case to solve duplicate user name, I used a name page with this format: Y-m-d-page->id-userfname-userlname With this format, I can get both, User Account ID and Registration Date.
    1 point
  20. Hehe ?. Yes, it's the first and only thing I disable by default whenever I install Tracy.
    1 point
  21. I am willing to help with that. I also know the pains of npm, but also know (sometimes) how to tackle them.
    1 point
  22. Yep, it's Tracy - it's designed to give you a visual indicator as to whether you're working on a live, local, dev, staging etc version of the site. It is configurable to work with subdomains or TLDs. Take a look at the "Server Type Indicator" section in Tracy's settings. I find this really invaluable, but I know that @kongondo hates it ? Anyway, you can easily disable it if you want, but note that of course it's only visible to users with Tracy permissions, so visitors to the site won't see it.
    1 point
  23. @Soma Yeah this is my issue with Vue.JS - I use Vue.JS often for two way data-binding which is amazing to be able to easily update content and do visual changes to the site based on those updates. For example adding something to a basket. It's much easier with Vue than jQuery or JavaScript. My issue with Vue is exactly that. You can use it just on a component basis or you can use it to render your entire UI. To me it just doesn't make sense to use it to render an entire UI with a website. A web app sure, but a website it's often overkill and introduces that exact problem. You can introduce server side rendering of Vue with Nuxt but then it just seems like another layer of 'over complication'. I personally stopped using Vue for websites unless I absolutely needed two way binding. It just didn't make sense and the extra complication of implementing it such as having to convert everything from ProcessWire into a JSON feed. EDIT: Noticed this post still gets likes, so what's changed since then? AlpineJS. AlpineJS is a solution to this exact problem, worth a look for anyone wanting to do some cool UI stuff without including all of Vue features and overhead.
    1 point
  24. The most flexible version would probably be a monolog (or compatible) implementation, just because how ubiquitous it's in the php community and all it's adapters to various logging backends.
    1 point
×
×
  • Create New...