Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/25/2023 in all areas

  1. After 8 months in development we are excited to bring you ProcessWire 3.0.226 main/master. This version has a ton of great new features, improvements and optimizations, plus more than 100 issue fixes. This post takes an in-depth look at highlights from this great new version. While there's even more in this version than is covered fully here, we hope this gives you a good taste of what you'll find in 3.0.226! https://processwire.com/blog/posts/pw-3.0.226/
    14 points
  2. Hey PR community, I just wanted to introduce myself and ask some questions. I'm a marketing and creative professional with some front-end skills mostly acquired by working in proximity with real developers ~20 years and by using technical-ish page builders like Webflow and Oxygen (for WordPress) where understanding HTML/CSS was necessary to make cooler things. I own a small creative agency called Freehive. We're famous among a very few people for creating release videos for GNOME and Ubuntu Desktop, and more recently helping Thunderbird redesign their website. We use Free and Open Source Software for design, animation, etc. and I'm regularly trying to convince creatives to kick their Adobe/Autodesk addictions subscriptions. I helped create the Inkscape marketing team several years ago and actively contributed there until a recent (necessary but temporary) break. I love FOSS, I love tools anyone can pick up and make a better life with regardless of their financial means. When I was looking for a more secure, open, and elegant solution than WordPress, you can only imagine how delighted I was to discover ProcessWire. With that background out of the way, I've got some questions: Have you found it difficult to convince clients to use something other than WordPress? What do you tell them, if so? If you've worked in the WordPress ecosystem, what do you miss? What are your top three (or more) dev tools or must have modules for making ProcessWire life easier? It's a lot to ask, so I appreciate even partial responses. Thanks, @ryan for creating this magnificent tool and sharing it freely. I really hope I can make it work and to give back somehow.
    6 points
  3. Admin Style Chroma This module provides a user interface to control the colors and typography of the AdminThemeUIKit backend theme for ProcessWire 3.0. The requirements are: PHP >= 7.x ProcessWire >= 3.0.179 AdminThemeUikit >= 0.3.3 Less >= 4 InputfieldColor >= 1.1.6 Installation The module can be installed from the Modules Directory or from the zip file archive from the main branch. When you first install the module, you will be taken to the configuration page that consists of four panes: Chroma Scheme Colors Using the color selectors, you can select the first color - your main color - and a second color if you wish - your accent color. Only the first color is required. The default color scheme installed by the module is a grayscale dark mode theme. Your main color does not got modified and gets applied to principal interface elements. If you are currently using the rock.less style as your admin style, this color gets applied to the @rock-primary LESS variable. Your second color gets desaturated. Current Palette Results In the background, depending on your mixer type either one or both of your color selections will be calculated and applied to eight master colors. These colors are displayed here. Your first color choice is applied without any modifications to palette color 3. Your second color choice (when applicable) is desaturated and treated according to your mixer type selection and applied to palette color 6. In general, colors 1-4 are applied to interface elements and their hover states. Colors 5-8 are applied to backgrounds and muted states. In UIKit parlance: Primary color = @chroma-lum-sat-3 Secondary color = @chroma-kum-sat-1 Muted color = @chroma-lum-sat-7 Default color = @chroma-lum-sat-6 Contrast rules are them applied to these colors to get regular and strong labels that are used to assure correct contrast to applied. Please Be Aware: The accessibility contrast threshold of 43% (the LESS default) is applied, but it is still possible to select color combinations that will evade readability scores from Google Lighthouse. Below the current palette dots you will se sample swatches and their hover states can be activated. Chroma Scheme Options The selections made here will alter the LESS files imported into the final admin.css and will either calculate a second color from the first one your select or use the second color. Color Mixer Type There are several mixers included. I'm always interested in other viable additions. Future versions of this module will likely include an ability to add your own custom select options to the interface to reference your own LESS include files. Single : This mixer mode takes your first color, and desaturates it in order to get the second color needed to build the theme palette. Contrast : This mixer mode takes your first color, negates it and desaturates it in order to get the second color needed to build the theme palette. Duotone : This mixer mode takes your first color and uses it to build out the top half of the palette, and takes your second color, desaturates it slightly, and uses it to build out the bottom half of the palette. Cool Harmony : This mixer takes your first color and spins its hue counterclockwise on the color wheel to get the second color and uses it to build out your color palette. Warm Harmony : This mixer takes your first color and spins its hue clockwise on the color wheel to get the second color and uses it to build out your color palette. Luminance Direction Light to Dark (Dark Mode) : This mode sets the palette to run from light colors at 1 to dark colors at 8. When using duotone, the light to dark ordering applies to each 4-color block individually. When using single color mode, the secondary color is a darkened version of the main color. Dark to Light (Light Mode) : This mode sets the palette to run from dark colors at 1 to light colors at 8. When using duotone, the dark to light ordering applies to each 4-color block individually. When using single color mode, the secondary color is a lightened version of the main color. Vibrance Level While the secondary color is always somewhat desaturated, you may wish to dial down or dial up the saturation depending on the text contrast requirements of your color theme. Subdued : The most aggressive desaturation level. Standard : Reasonable desaturated for most applications. Vibrant : The least desaturated settings, though still slightly desaturated. Chroma Scheme Fonts The drop down selectors here will detect css stylesheets found in your ste/assets/fonts or site/templates directory. If you use RockFrontend to download your Google Fonts, it will detect these fonts as well. If you select "No Custom Font" for either the Header Font or the Body Text Font, the default AdminThemeUiKit font rules will apply. Add Google Fonts This feature makes use of a modified version of Bernhard Baumrock's method (found in RockFrontend) for procuring Google Font files and saving them on your server. After looking at his references on CSSTricks is was pretty clear that the header manipulation approach was going to be the best one. When first installed and run, the Admin Style Chroma module will download json lists of Google Font options and cache them in your site/assets directory. There is currently no method in place to check for new fonts, so if for some reason you are not seeing a Google Font you want to use, deleting this file should force the module to repopulate it: /site/assets/AdminStyleChroma/google_fonts.json The Google Fonts are downloaded by individual family and saved along with their CSS file in: /site/assets/fonts/{family}/{family}.css If you select font variants beneath the dropdowns, these values will be passed to the request. If you do not specify which font variants you want, Google will return the defaults for that font family. If you which to include special italic/oblique variants for each weight, set the option appropriately. If a variant does not exist for a given weight, Google will attempt to serve the closest weights available. If you make selections (or don't) and select a font that you have already downloaded before, the previous family files will be overwritten. PLEASE NOTE : If you download a lot of fonts, this process could take some time. Style Compatibility A lot of styles have already been corrected. A number of styles within the ProcessWire core that use plain css or scss have been overwritten via specificity. A 'chroma' class is also added to the body tag, which drives many of the newly inherited classes, but due to the design of some features of certain modules there are other classes defined outside of the heirs of this class. I'm not always happy with how warnings appear. Future versions will address these issues. I've included many rules to provide support for the following areas: Tab Wrappers Page lists and actions Radios, Checkboxes and Selection Colors Selections, Marked text Panels and widgets Image related popups Awesomeplete RepeaterMatrix TinyMCE Interface Tracy Debugger Page Hit Counter Release Note Changes Admin On Steroids Admin Helper Search Engine Color Spectrum Easy Repeater Sort Page View Statistics Nette Tests All changes here are entirely superficial quality of life style improvements. The functionality is not altered. Depending on your TinyMCE settings you may see these improvements but you may not. I've made changes that address quirks that I have personally seen. I am always open to adding rules for other modules where the styles are off or assume a white background. I hope one day we will have a proper discussion of less/css normalization for module authors, but even when that occurs it is hard to say how we will retrofit older modules, etc. For now, this is a patchwork process.
    3 points
  4. As a longtime photo enthousiastic i decided to show my work to the "world" What else could i do than use processwire? My Dutch site is viewable at: https://foto.markveldman.com Mark Veldman
    3 points
  5. Actually, the answer is much simpler. I had the same problem with another script. When I call the page with "url: '/ajax/captcha-verify'", the data gets deleted, with url: '/ajax/captcha-verify/' it works. Thanks to everybody!
    3 points
  6. A bit offtopic: Specifically in UIkit I've overcome most some of these issues adding the classes along the attributes of the components, for example if you have a uk-dropdown or uk-drop components, add the uk-drop class too. See how the uk-drop class is the one with the display:none property, hence the issue of seeing it when the js hasn't added the class to the component. .uk-drop { display: none; position: absolute; z-index: 1020; --uk-position-offset: 0px; --uk-position-viewport-offset: 0; box-sizing: border-box; width: 300px; } All assuming you load the CSS before the document.
    3 points
  7. Hi and welcome @ryangorley ? 1. give a read to: https://processwire.com/about/what/ and 2. refer to #1 3. the very first one tool you and the team need while working with ProcessWire is: https://adrianbj.github.io/TracyDebugger/#/ https://processwire.com/talk/forum/58-tracy-debugger/ ✨Suggestions: - keep an eye on @Robin S gems (modules) handy on every situation: https://github.com/Toutouwai - subscribe to weekly.pw - and do not hesitate to search and use the forum, even for "i will feel dumb" questions. Enjoy ?
    2 points
  8. Ah! That did the trick. Thank you! I now went from this: return "<div class='uk-navbar-dropdown'><ul class='uk-nav uk-navbar-dropdown-nav'>$output</ul></div>"; To this (also added the 'uk-drop' class as you mentioned). return "<div class='uk-navbar-dropdown uk-drop'><ul class='uk-nav uk-navbar-dropdown-nav'>$output</ul></div>"; Now I can use "defer" without having the flashy dropdown menus on page load. This is a trick I bet I want to try on some other UIkit components aswell, if they behave a little bit clunky.
    2 points
  9. I would like to add my 50cents here as well. I basically agree to what @Stefanowitsch mentioned above. I love to use RockFrontend for the following reasons: LATTE, LATTE, LATTE then AutoRefresh and thats it for me personally. I also like to keep all my modules as much as possible to the latest version. With RockFrontend this means, I get lots of new stuff, which might or might not affects my site (I always need to test this), but which I do not really need most of the time. Maybe it would make sense to split the module into two parts. RockBackend and RockFrontend where RockFrontend needs to have RockBackend as a dependent module somehow? I personally find it strange that a module which offers neatless integration with LATTE and auto compiles LESS files also provides scritps for fluid font sizes, animations, downloading fonts to local folders, etc. I know this is just my personal preference and the way I work, and others will have a different approach here and will use many features of what the module offers. And by no means I want to criticize Bernhard for the way he develops his module.
    2 points
  10. I added support for automatic WebP to JPG conversion via the WebP To JPG module. To make use of this update to Add Image URLs v0.3.0 and install/update to WebP To JPG v0.2.0.
    2 points
  11. Inertia Adapter ProcessWire Module Hello! Long time no see. I created this module so you can use Inertia.js (https://inertiajs.com/) with ProcessWire. Description Inertia allows you to create fully client-side rendered, single-page apps, without much of the complexity that comes with modern SPAs. It does this by leveraging existing server-side frameworks. Inertia isn’t a framework, nor is it a replacement to your existing server-side or client-side frameworks. Rather, it’s designed to work with them. Think of Inertia as glue that connects the two. Inertia comes with three official client-side adapters (React, Vue, and Svelte). This is an adapter for ProcessWire. Inertia replaces PHP views altogether by returning JavaScript components from controller actions. Those components can be built with your frontend framework of choice. Links - https://github.com/joyofpw/inertia - https://github.com/joyofpw/inertia-svelte-mix-pw - https://inertiajs.com/ Screenshots
    1 point
  12. Sure... I was just fixing up a little bit of repeatermatrix font color styling on the inputfield side. This is a dark mode duotone standard vibrance. Here's the same in light mode: Here's a contrast standard dark mode sample from another dummy site. So you can see how TinyMCE works in its one of its editing modes. I did set up one of them to respect dark/light mode. Haven't done them all because I like having the option to flip the script? Here's a lighter one. Still a little work to do obviously - there's text that need recoloring, and a few borders need cleanup. I'm going to just keep tweaking it until it is consistent. One thing I was thinking about this morning was setting a dark v light default alert background/text scheme. I know that if you violate a constraint you still get the default white background alert - so I'll probably roll out a change in the next couple of days to work that out.
    1 point
  13. Ah that is a classic mistake I also made in the past. Page paths always have to end with a backslash in ProcessWire (but that is adjustable in the template settings!). When you call up an URL you can leave the backslash - this will work - but in that case theres a redirect going on that leads to the data-loss when submitting form data.
    1 point
  14. That is awesome!!! Thank you
    1 point
  15. The "raw" ProcessWire API, is a bit more verbose but not really a show stopper. Also to be clear with API I mean the whole deal of classes involved in the admin or pages/fields like Field, Fieldtype, Inputfield, InpufieldForm, InputfieldWrapper, etc and hooks involved, not just the global $page, $pages, $input variables. Say with RockMigrations you'd do: $rm->migrate([ 'fields' => [ 'some_fifeld' => [ 'label' => 'Some Fields', 'type' => 'title' ] ]; ]) In "plain" PW API: if($fields->get('some_field')){ $field = new Field(); $field->name = "some_field"; $field->type = "FieldtypeTitle"; $field->label = "Some Field"; $field->save(); } And most of this doesn't really change much with any other field. But indeed since ProFields tend to elaborate on complex things to solve, they might involve a few more steps.
    1 point
  16. Looks cool! Could you attach full screenshots of admin pages styled this way? Just for fun)
    1 point
  17. Love this! Makes total sense. Although I did try to make AlpineJS part of my boilerplate and quickly gave up. Just easier for me to add a JS file and do my stuff with vanilla. Right now I just have a Vite thing, a js that imports and inits scripts from a file (like the one that Bernhard mentioned). Effects like my text reveal thing require adding the type of ready-made JS and CSS that I tend to avoid. However if it could be part of a library of stuff a developer can browse and easily add to their project, it might be a cool idea. Alpine might help with this.
    1 point
  18. It's not official documentation but the topic has been discussed here: The page and diagram that @teppo created and linked to is dead now but I've found it very informative so here's the diagram for posterity: It would be wonderful if @ryan or someone knowledgeable created an updated version of this.
    1 point
  19. $_POST is an associative array of variables passed to the current script via the HTTP POST method when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request. Not when using application/json. For json, you'd typically do something like this: $data = json_decode(file_get_contents('php://input'), true); AJAX is Javascript, and Javascript libraries often use the JSON method. I'm not sure if jQuery does, but I had the same issue when working with AngularJS in the past.
    1 point
  20. The new dev branch version 3.0.222 contains about 20 commits and 16 issue resolutions. In terms of new features, last week I mentioned some upgrades to WireHttp, and below are this week's additions: Multi-language month and day names The WireDateTime class (aka the $datetime API variable) has been updated to support multi-language month and day names. Now all month and days are translatable in the WireDateTime file (/wire/core/WireDateTime.php). So if you request any date in a format that uses month names or abbreviations, or day names or abbreviations, they now support multi-language, whether you requested it from the wireDate() function or the $datetime API variable. ProcessWire has long supported multi-language month and day names when using a PHP version prior to 8.1 and you've requested a strftime date format that uses them. But PHP 8.1 dropped the multi-language supporting strftime() function, without leaving a suitable replacement. PHP's IntlDateFormatter can't be relied upon since it's not always compiled with PHP. But as of PW 3.0.222, now we have a suitable replacement. Though it does require you to translate the 7 days and 12 months for file /wire/core/WireDateTime.php using ProcessWire's language translation tool. Note that unlike the previous strftime() solution, the new solution no longer requires you to use strftime() format codes and you can instead use regular date formats and they will be translated automatically. New conditional hooks that match by argument type Another new addition this week is support for conditional hooks that match by argument type. I think this is especially useful combined with ProcessWire's custom page class support. It enables you to make a hook apply only to methods containing arguments of a specific type. For instance, if you had a custom page class "ProductPage" for template "product" and you wanted to capture the "Pages::saved" event for pages of that type (ProductPage) you could do so like this: $wire->addHook('Pages::saved(<ProductPage>)', function($event) { $product = $event->arguments(0); /** @var ProductPage $product */ $event->message("ProductPage '$product->title' has been saved"); }); In addition to supporting class or interface names, you can also specify regular PHP types such as <array>, <string>, <int>, <object>, etc. For more details on this type of hook see the new Conditional hooks that match argument type section of the Hooks documentation. Thanks for reading and have a great weekend!
    1 point
  21. Page Query Boss Build complex nested queries containing multiple fields and pages and return an array or JSON. This is useful to fetch data for SPA and PWA. You can use the Module to transform a ProcessWire Page or PageArray – even RepeaterMatrixPageArrays – into an array or JSON. Queries can be nested and contain closures as callback functions. Some field-types are transformed automatically, like Pageimages or MapMarker. Installation Via ProcessWire Backend It is recommended to install the Module via the ProcessWire admin "Modules" > "Site" > "Add New" > "Add Module from Directory" using the PageQueryBoss class name. Manually Download the files from Github or the ProcessWire repository: https://modules.processwire.com/modules/page-query-builder/ Copy all of the files for this module into /site/modules/PageQueryBoss/ Go to “Modules > Refresh” in your admin, and then click “install” for the this module. Module Methods There are two main methods: Return query as JSON $page->pageQueryJson($query); Return query as Array $page->pageQueryArray($query); Building the query The query can contain key and value pairs, or only keys. It can be nested and contain closures for dynamic values. To illustrate a short example: // simple query: $query = [ 'height', 'floors', ]; $pages->find('template=skyscraper')->pageQueryJson($query); Queries can be nested, contain page names, template names or contain functions and ProcessWire selectors: // simple query: $query = [ 'height', 'floors', 'images', // < some fileds contain default sub-queries to return data 'files' => [ // but you can also overrdide these defaults: 'filename' 'ext', 'url', ], // Assuming there are child pages with the architec template, or a // field name with a page relation to architects 'architect' => [ // sub-query 'name', 'email' ], // queries can contain closure functions that return dynamic content 'querytime' => function($parent){ return "Query for $parent->title was built ".time(); } ]; $pages->find('template=skyscraper')->pageQueryJson($query); Keys: A single fieldname; height or floors or architects The Module can handle the following fields: Strings, Dates, Integer… any default one-dimensional value Page references Pageimages Pagefiles PageArray MapMarker FieldtypeFunctional A template name; skyscraper or city Name of a child page (page.child.name=pagename); my-page-name A ProcessWire selector; template=building, floors>=25 A new name for the returned index passed by a # delimiter: // the field skyscraper will be renamed to "building": $query = ["skyscraper`#building`"] Key value pars: Any of the keys above (1-5) with an new nested sub-query array: $query = [ 'skyscraper' => [ 'height', 'floors' ], 'architect' => [ 'title', 'email' ], ] A named key and a closure function to process and return a query. The closure gets the parent object as argument: $query = [ 'architecs' => function($parent) { $architects = $parent->find('template=architect'); return $architects->arrayQuery(['name', 'email']); // or return $architects->explode('name, email'); } ] Real life example: $query = [ 'title', 'subtitle', // naming the key invitation 'template=Invitation, limit=1#invitation' => [ 'title', 'subtitle', 'body', ], // returns global speakers and local ones... 'speakers' => function($page){ $speakers = $page->speaker_relation; $speakers = $speakers->prepend(wire('pages')->find('template=Speaker, global=1, sort=-id')); // build a query of the speakers with return $speakers->arrayQuery([ 'title#name', // rename title field to name 'subtitle#ministry', // rename subtitle field to ministry 'links' => [ 'linklabel#label', // rename linklabel field to minlabelistry 'link' ], ]); }, 'Program' => [ // Child Pages with template=Program 'title', 'summary', 'start' => function($parent){ // calculate the startdate from timetables return $parent->children->first->date; }, 'end' => function($parent){ // calculate the endate from timetables return $parent->children->last->date; }, 'Timetable' => [ 'date', // date 'timetable#entry'=> [ 'time#start', // time 'time_until#end', // time 'subtitle#description', // entry title ], ], ], // ProcessWire selector, selecting children > name result "location" 'template=Location, limit=1#location' => [ 'title#city', // summary title field to city 'body', 'country', 'venue', 'summary#address', // rename summary field to address 'link#tickets', // rename ticket link 'map', // Mapmarker field, automatically transformed 'images', 'infos#categories' => [ // repeater matrix! > rename to categories 'title#name', // rename title field to name 'entries' => [ // nested repeater matrix! 'title', 'body' ] ], ], ]; if ($input->urlSegment1 === 'json') { header('Content-type: application/json'); echo $page->pageQueryJson($query); exit(); } Module default settings The modules settings are public. They can be directly modified, for example: $modules->get('PageQueryBoss')->debug = true; $modules->get('PageQueryBoss')->defaults = []; // reset all defaults Default queries for fields: Some field-types or templates come with default selectors, like Pageimages etc. These are the default queries: // Access and modify default queries: $modules->get('PageQueryBoss')->defaults['queries'] … public $defaults = [ 'queries' => [ 'Pageimages' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus', ], 'Pagefiles' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'filesize', 'filesizeStr', 'hash', ], 'MapMarker' => [ 'lat', 'lng', 'zoom', 'address', ], 'User' => [ 'name', 'email', ], ], ]; These defaults will only be used if there is no nested sub-query for the respective type. If you query a field with complex data and do not provide a sub-query, it will be transformed accordingly: $page->pageQueryArry(['images']); // returns something like this 'images' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus'=> [ 'top', 'left', 'zoom', 'default', 'str', ] ]; You can always provide your own sub-query, so the defaults will not be used: $page->pageQueryArry([ 'images' => [ 'filename', 'description' ], ]); Overriding default queries: You can also override the defaults, for example $modules->get('PageQueryBoss')->defaults['queries']['Pageimages'] = [ 'basename', 'url', 'description', ]; Index of nested elements The index for nested elements can be adjusted. This is also done with defaults. There are 3 possibilities: Nested by name (default) Nested by ID Nested by numerical index Named index (default): This is the default setting. If you have a field that contains sub-items, the name will be the key in the results: // example $pagesByName = [ 'page-1-name' => [ 'title' => "Page one title", 'name' => 'page-1-name', ], 'page-2-name' => [ 'title' => "Page two title", 'name' => 'page-2-name', ] ] ID based index: If an object is listed in $defaults['index-id'] the id will be the key in the results. Currently, no items are listed as defaults for id-based index: // Set pages to get ID based index: $modules->get('PageQueryBoss')->defaults['index-id']['Page']; // Example return array: $pagesById = [ 123 => [ 'title' => "Page one title", 'name' => 123, ], 124 => [ 'title' => "Page two title", 'name' => 124, ] ] Number based index By default, a couple of fields are transformed automatically to contain numbered indexes: // objects or template names that should use numerical indexes for children instead of names $defaults['index-n'] => [ 'Pageimage', 'Pagefile', 'RepeaterMatrixPage', ]; // example $images = [ 0 => [ 'filename' => "image1.jpg", ], 1 => [ 'filename' => "image2.jpg", ] ] Tipp: When you remove the key 'Pageimage' from $defaults['index-n'], the index will again be name-based. Help-fill closures & tipps: These are few helpfill closure functions you might want to use or could help as a starting point for your own (let me know if you have your own): Get an overview of languages: $query = ['languages' => function($page){ $ar = []; $l=0; foreach (wire('languages') as $language) { // build the json url with segment 1 $ar[$l]['url']= $page->localHttpUrl($language).wire('input')->urlSegment1; $ar[$l]['name'] = $language->name == 'default' ? 'en' : $language->name; $ar[$l]['title'] = $language->getLanguageValue($language, 'title'); $ar[$l]['active'] = $language->id == wire('user')->language->id; $l++; } return $ar; }]; Get county info from ContinentsAndCountries Module Using the [ContinentsAndCountries Module](https://modules.processwire.com/modules/continents-and-countries/) you can extract iso code and names for countries: $query = ['country' => function($page){ $c = wire('modules')->get('ContinentsAndCountries')->findBy('countries', array('name', 'iso', 'code'),['code' =>$page->country]); return count($c) ? (array) $c[count($c)-1] : null; }]; Custom strings from a RepeaterTable for interface Using a RepeaterMatrix you can create template string for your frontend. This is usefull for buttons, labels etc. The following code uses a repeater with the name `strings` has a `key` and a `body` field, the returned array contains the `key` field as, you guess, keys and the `body` field as values: // build custom translations $query = ['strings' => function($page){ return array_column($page->get('strings')->each(['key', 'body']), 'body', 'key'); }]; Multilanguage with default language fallback Using the following setup you can handle multilanguage and return your default language if the requested language does not exist. The url is composed like so: `page/path/{language}/{content-type}` for example: `api/icf/zurich/conference/2019/de/json` // get contenttype and language (or default language if not exists) $lang = wire('languages')->get($input->urlSegment1); if(!$lang instanceof Nullpage){ $user->language = $lang; } else { $lang = $user->language; } // contenttype segment 2 or 1 if language not present $contenttype = $input->urlSegment2 ? $input->urlSegment2 : $input->urlSegment1; if ($contenttype === 'json') { header('Content-type: application/json'); echo $page->pageQueryJson($query); exit(); } Debug The module respects wire('config')->debug. It integrates with TracyDebug. You can override it like so: // turns on debug output no mather what: $modules->get('PageQueryBoss')->debug = true; Todos Make defaults configurable via Backend. How could that be done in style with the default queries? Module in alpha Stage: Subject to change This module is in alpha stage … Query behaviour (especially selecting child-templates, renaming, naming etc) could change
    1 point
  22. Quick update... Finally figured out to get React/NextJS to work with a basic (minimal field types to convert to JSON) PW site. Giving self a pat on the back when I discovered Svelte ? Svelte felt (I'm a poet & didn't know it ?) so much more like PW - JS, HTML & CSS with 'state management' and no shadow DOM. The only problem was routing. I'd spent far too long figuring out React/NextJS routing and Svelte offered no immediate solution. The old (like 2yrs) way of routing was called Sapper. Development on Sapper has ceased with all efforts now focussed on the new way, SvelteKit which is in pre-beta (? ). Anyhoo, went with SvelteKit and got it working. I've only scratched the surface on what's possible with React/NextJS and Svelte. Both offer Server Side Rendering (SSR) making the site SEO friendly & fast-loading. Given a choice, I'd choose Svelte every time. With both React/NextJS and Svelte using @Sebi's AppApi with customisation depending on the framework, I: created a home page that pulls the data from the PW home page created a 'slug' page that pulls the data from the PW page url and displays it in a component based on the PW page template as returned in the page JSON, and shows the correct route in the URL from a nav menu In both cases, the page layout is not a PW template but a conditional component file. Anyone else tried Svelte with PW? Your thoughts & comments welcome
    1 point
  23. I tested it too, and the problem occurs when the paragraph is longer than the truncate length, causing there to be no closing </p> tag present in the truncated string. There is an option for the fixUnclosedTags() method used by truncate, to close instead of remove unclosed tags... * Fix/close unclosed tags: * ------------------------ * When the remove option is false, it will attempt to close unclosed tags rather than * remove them. It doesn't know exactly where they should be closed, so it appends the * close tags to the end of the string. ...but the truncate method calls fixUnclosedTags() with remove = true and doesn't provide a way to do otherwise. I guess you could use WireTextTools::fixUnclosedTags() before calling $sanitizer->truncate but it would be nice to have the option built into the truncate method. Maybe an oversight by Ryan? Edit: request opened here: https://github.com/processwire/processwire-requests/issues/253 @bibsch, because your truncate length is short and will only contain a single paragraph you can achieve your objective by adding <p> tags around your truncated text: echo '<p>' . $sanitizer->truncate($child->body, 200) . '</p>';
    1 point
×
×
  • Create New...