Jump to content


Popular Content

Showing content with the highest reputation since 10/20/2019 in all areas

  1. 27 points
    This version on the dev branch contains 26 commits (relative to 3.0.142) and is focused primarily in resolving reported issues, and we managed to cover 18 of them in this version. Thanks for the reports and help in our GitHub issues repo. This version represents about 2 weeks of work, and ProcessWire Weekly #284 has good coverage of those that occurred last week. More details about this week's updates can be also be found in the dev branch commit log. There are also some other minor additions and improvements in 3.0.143 as well. My favorite are the improvements to our logs system. It now collapses identical log entries that occur near each other. That means a single recurring log entry (like an error message) won't repeat indefinitely in the log and take up a lot of space. Now it just adds a counter to one log entry and updates the timestamp, rather than duplicating the entire log entry... Much more efficient. When you view a log in Setup > Logs, it identifies these collapsed log entries for you. In addition, the output in the "errors" and "exceptions" logs now have improved readability, isolating error messages and filenames from stack traces. Lastly, the ajax navigation in Setup > Logs now shows logs in newest-to-oldest (modification date) rather than alphabetical, which I find a lot more useful. The log at the top of the list is always the one most recently updated. For core updates in coming weeks, I'm primarily focused on preparing the current dev branch to merge to the master branch, as it's been awhile since the last merge and the master branch is itching for a new version. Most of you reading this already run on the dev branch, but there are many out there that also stick to the master branch, and with all the new stuff on the dev branch, I'd like to get our master up-to-date with this as well. Thanks for reading, have a great weekend!
  2. 16 points
    ProcessWire 3.0.144 and 3.0.145 add improved field template context override settings and include a new Inputfields API, along with numerous other issue fixes, optimizations and improvements to the core. This blog post is a continuation (and more in-depth version) of last week's post on 3.0.144 that was in the forum— https://processwire.com/blog/posts/pw-3.0.145/
  3. 5 points
    The Inputfields JS API is really cool, thanks @ryan! What do you think about adding a feature so that some (all??) of these JS functions could be triggered via URL query string parameters? As per my request here it would be neat to be able to create links (e.g. modal) to a form that automatically show/hide/highlight/etc particular fields.
  4. 4 points
    It's not related to ProcessWire. That's the good news. The bad news are: I don't know the answer. 😉 Some say it's related to your hosting provider, some say it's related to a CDN. I found two similar issues out there in the wild: https://wordpress.org/support/topic/unusual-stuff-in-the-url/ https://community.cloudflare.com/t/website-css-not-loading-loads-with-development-mode-on/128163 So... if there is no CDN involved, try to look into your hosting and maybe even ask their support team. Last but not least: Welcome to the forums. 🙂
  5. 4 points
    Ok, my bad. Still, reporting post serves a completely different purpose. Hopefully this will be picked up by someone that can address the issue, but the best is to post the issue on github. You would have to create an account there, and of course that's up to you, but you don't need to use git to do it, only fill a form on the site.
  6. 4 points
    Hi @bernhard, @rjgamer Thanks for the comments - I share some of the frustration you are voicing - but I'm only able to handle issues on the processwire-issues and processwire-requests repos. I don't have admin rights on the main processwire code repo so I can't take any action on PRs, even if I wanted to. Perhaps we could invite @horst to also comment here as he is the only member of the community who I feel has been successful at having bulk code submissions adopted into Processwire.
  7. 3 points
    ProcessWire / Fullcalendar solution including comfortable planning app in the backend: https://vdt-icsa.de/program/ https://2018.tonmeistertagung.com/en/program/
  8. 3 points
    Sadly, the rider of this new horse is dumber than a truck-load of doorstops. So I found another way to accomplish what I was looking for. In my opinion, it's hacky, as I still don't know the answers to my op questions, but it will work for now. The $_FILES['input_file_fieldname']['tmp_name'] works as the parameter to New WireUpload(). The result is a randomly created name saved in both the PageImages and file system. Using Soma's rename procedure to provide the original uploaded file's name corrects that anomaly. The result is an uploaded image with the correct (human readable) name. Anyone want to buy a horse? Only ridden once. Includes a new stick. Cheap.
  9. 3 points
    I think it should be: $page->fixtures->find("team_a=$teamA,team_b=$teamB");
  10. 3 points
    The simple solution is to create a new text field "full_name" and add it to your template. Set the visibility to "Hidden (not shown in the editor)". In /site/ready.php: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if($page->template == 'your_template') { $page->full_name = $page->first_name . ' ' . $page->last_name; } }); You'll need to save all the pages once to populate the full_name field - if there are a lot then use the API to loop over the pages and save them. Now you can search the full_name field.
  11. 3 points
    The sad truth is that ryan seems to ignore them 😞 I've mentioned that several times but all of my questions where handled like pull requests: ignored. Maybe @netcarver can tell us something more about that topic, as he is taking care about the pw-issues repo. Thx for that btw! 🙂
  12. 3 points
    Thanks - from what I can tell, the backup is being created successfully - it's just not linked to. The new version just committed now returns this with the restore link included and the error color changed to match the PW uikit color and also make links white and underlined so they are visible. You mentioned above that the restore didn't work though, so please test the new version and let me know.
  13. 3 points
    Fieldset (open) (a field) and the Minimal Fieldset module is what I use for things like this.
  14. 2 points
    Hi @Peejay, did you run the Additional steps / Install Snipcart products package in SnipWire module settings? This step installs product templates, files, fields and some demo pages required to build a Snipcart product catalogue. This additional step is needed to prevent unintended deletion of your Snipcart products catalogue when main module is uninstalled. In the current alpha version this isn't yet checked by SnipWire. If you did already run the additional step with an earlier SnipWire version there will be fields missing which were added in a later version. So you will need to re-run this step. The missing resources(fields, templates, pages, ...) will then be installed. Existing ones won't be touched! To re-run this step, you will need to edit/remove a key in database directly: DB table: "modules" -> find entry with class "SnipWire" -> edit the "data" field and remove the Json key: "product_package":true (be sure to leave a valid Json string - you will need to also remove the corresponding comma : {"api_key":"YOUR_LIVE_API_KEY","api_key_test":"ODQzZTc1MjktZGQxNy00YmUzLWFkMWYtZDE3MDQ2YTk1ODNjNjM2ODE3NTg5NzUyNDQxOTc0","api_key_secret":"YOUR_LIVE_API_KEY_SECRET","api_key_secret_test":"","snipcart_environment":"0","single_page_shop":"","single_page_shop_page":1,"credit_cards":["visa","mastercard","amex"],"currencies":["eur","usd"],"show_cart_automatically":1,"shipping_same_as_billing":1,"show_continue_shopping":1,"split_firstname_and_lastname":1,"snipcart_debug":1,"snipcart_css_path":"https:\/\/cdn.snipcart.com\/themes\/2.0\/base\/snipcart.min.css","snipcart_css_integrity":"","snipcart_js_path":"https:\/\/cdn.snipcart.com\/scripts\/2.0\/snipcart.js","snipcart_js_integrity":"","include_jquery":"","jquery_js_path":"https:\/\/code.jquery.com\/jquery-3.3.1.min.js","jquery_js_integrity":"sha256-FgpCb\/KJQlLNfOu91ta32o\/NMZxltwRo8QtmkMRdAu8=","excluded_templates":["promailer-email","promailer-subscribe"],"cart_image_width":65,"cart_image_height":65,"cart_image_quality":70,"cart_image_hidpi":1,"cart_image_hidpiQuality":50,"cart_image_cropping":1,"data_item_name_field":"title","uninstall":"","submit_save_module":"Submit","taxes_included":1,"webhooks_endpoint":"\/webhooks\/snipcart","include_snipcart_css":1,"taxes":"[{\"name\":\"20% VAT\",\"numberForInvoice\":\"\",\"rate\":\"0.20\",\"appliesOnShipping\":[]},{\"name\":\"10% VAT\",\"numberForInvoice\":\"\",\"rate\":\"0.10\",\"appliesOnShipping\":[]},{\"name\":\"10% VAT (Shipping)\",\"numberForInvoice\":\"\",\"rate\":\"0.10\",\"appliesOnShipping\":[\"1\"]}]","snipwire_debug":1,"data_item_categories_field":"snipcart_item_categories","product_package":true} After the key is removed, visit the SnipCart module settings again and re-run the product package installer! In the release version of SnipCart, this will be handled automatically. On each update it will check if there are new fields or other resources to be installed. Hope this helps! p.s. You could also completely uninstall the SnipCart module and then reinstall - this should also activate the product package installer link! -- Martin
  15. 2 points
    Have you looked at the $session documentation? If so is there a specific problem you're having?
  16. 2 points
    I need to take a look at that, but unfortunately, I'm not hopeful that I'll find enough time this week. Next week should be a bit less crazy though. I haven't found the time to update to the latest FB release, but it looks like soon will be a good time to do so 🙂 Stay tuned.
  17. 2 points
    Google 'professor messer' and check out a course on Udemy, a course by Chris Bryant for CCNA video bootcamp.
  18. 2 points
    If anyone hasn't seen it, https://www.11ty.io is pretty amazing for static sites, it gets a lot of things right in my opinion. Much less opinionated than other static generators, allows swapping template languages on the fly throughout or on a page by page basis, and the systems for page data are super powerful and flexible. I just build a startup marketing site with it, a few of the cool things I did were: read filesystem and parse image files to create a globally accessible images object with width, height, ratio data for use with mixins to ouput lazyload containers; parse a csv file to build a really complicated pricing table... no more client requests to change wording on x row, they just edit a google doc I set up for them, I download and drop in the assets folder, rebuild and done!
  19. 2 points
    Here is a more detailed answer with the steps you have to take: Download the ProcessWire Zip (or use one of the other install methods) Unzip the file in your web root and rename it to the name how your project should be named Open Laragon control panel Click "reload" button for Apache This automatically creates a virtual host with the name of your folder like "processwire.dev" (I don't remember what is the default domain of Laragon, because I changed it to .localhost) You can then navigate in your browser to this URL You will see the ProcessWire installer and just have to follow the steps
  20. 2 points
    Hello, thanks for sharing, for everyone who came here like me and the proposal did not work for some reason, I invite you to read the instructions here: It is also important that they use the following web.config file (which contains minor corrections to the code initially shared by @nikola). I hope it helps you with something like me. Regards!
  21. 1 point
    If you're serious about performance and don't have http2 available, you can optimize a lot with resource hints and service workers + cache API.
  22. 1 point
  23. 1 point
    lol, i see amigo, I just didn't want to have to go re-invent the wheel, ya know? I'm liking this little gem https://fullcalendar.io/ Just gotta figure out the best way to implement it 😉
  24. 1 point
  25. 1 point
    Do not use FieldtypeInteger for Phonenumbers, because the Mysql Datatype is INT and therefore the value is limited to 4 bytes strings (32bit). You can use FieldtypeInteger only for numbers within the range from -2147483647 to 2147483647. Use builtin FieldtypeText or FieldtypePhone (3d Party Module) for Phonenumbers. The value of FieldtypePhone must be an instance of Phone (WireData derived object) otherwise it will be set to blank value. From the code: /** * If value not of instance Phone return empty instance */
  26. 1 point
    Hi! It was a cache problem. I leave this topic for any similar issues.
  27. 1 point
    You're welcome. JL2 (when I get there 🙈) will give some more control here. This case would be covered by subscribe/{path} --> @[1495]/{path}, and then there'd either be a {query} wildcard or an option on the jumplink itself to automatically carry it over.
  28. 1 point
    You're a legend - thank you - works perfectly!
  29. 1 point
    @Kiwi Chris Just looked at one of my sites and this is what I put in ready.php // lets non superusers view unpublished and hidden pages in listers // https://processwire.com/talk/topic/9346-not-all-specified-templates-are-editable-only-includehidden-is-allowed/?do=findComment&comment=143068 $this->wire()->addHookBefore('ProcessPageLister::getSelector', function($event) { $event->object->allowIncludeAll = true; }); Does this solve your problems?
  30. 1 point
    Worth noting: https://processwire.com/talk/topic/19912-future-of-padloper-new-project-lead-announcement/ TL;DR: https://processwire.com/talk/topic/19912-future-of-padloper-new-project-lead-announcement/?do=findComment&comment=187487
  31. 1 point
    No solution, but I guess there is definitely something broken. I'm getting error messages like the following on multiple servers of mine: Fatal error: Method SeoMaestro\PageFieldValue::__toString() must not throw an exception, caught ErrorException: chdir(): open_basedir restriction in effect. File(/var/www/php-fcgi-scripts/web366) is not within the allowed path(s) Somebody mentioned that earlier in this thread, but no solution was proposed (the error went away automagically in that case).
  32. 1 point
    I have found a solution and thought I would share it for the benefit of others. It may not be the most efficient or elegant solution but it is working. After some trial and error the solutions suggested in topic 7659, especially by formulate, began to make sense. In the tagging.php template file is the following code: $fullList = $pages->find("$searchTxt=$thisTag"); // this select all pages where page field "Tags" contains a page with title of our tag $tagList = $pages->find("$searchTxt=$thisTag, limit=10"); // this selects the same as above but limits the rsults for pagination $session->taggedPages=(string)$fullList; // save the result of the first search for use in the portfolio template In the portfiolio.php template file the following gets the prev / next pages from the tag search: $fullList=$pages->find("id=" .$session->taggedPages); $next = $page->next($fullList); $prev = $page->prev($fullList); This means that going to the prev / next page is not limited to those paginated on the tagging page. I hope that makes sense and helps someone else.
  33. 1 point
    Thank you @ceberlin for the link. I just looked into the article and will take a look at the tools they provide and how they work - hopefully this week. Those can easily be set in the texts you already show in the banner. That's how I do it most of the time.
  34. 1 point
    Insane! Great, thank you. I submitted a pull request on github, because in my installation the created label was empty.
  35. 1 point
    One simple way to do this client side with normal fields would be to add an "Active languages" field to each Repeater Matrix type, and use that as a language activation switch. For example: Create a Page Reference field "active_languages" with the template "language" as selectable pages and the input field type set to checkboxes. Then add that field to each repeater matrix type. Finally, in the code that renders the matrix item, use something like this (code untested): // assuming the matrix field name is "sections" foreach ($page->sections as $section) { $if ($section->matches("active_language={$user->language->id}") { // render the field } } Now the editor can check which languages they want the section to be displayed in. Obviously you can also invert the logic and use the checkboxes to hide the section in a specific language. Of course, having this built in would simplify things a lot 🙂
  36. 1 point
    Hey, I've tried a search but couldn't find anything about this precisely. Is there any explicit setting to add images to the start of an image field rather than the end on upload? I'm assuming I'll need to figure this out with hooks. Please ignore. Noob mistake asking a question from a client, they weren't drag dropping and I had a brain spasm.
  37. 1 point
    If you allow the user to select one or more products, you can use a select field to present the options to the user. Of course it depends on the number of available products. If there are a large number of products, you may want to separate them by category. The select field's options allow for values that you require.
  38. 1 point
    Thank you very much @Robin S, I have been able to fix the issue! 🙂
  39. 1 point
    Thanks @wbmnfktr good suggestion. I did already try this though, logged into the cms on Firefox and with an incognito windo open in Chrome to view the front end site. Thanks
  40. 1 point
    ProCache does that and is worth every cent: https://processwire.com/store/pro-cache/#procache-css-and-js-minification-and-merge https://modules.processwire.com/modules/pro-cache/
  41. 1 point
    Thank you very much for sharing, I have been trying to implement the option of "replying" in the comments for several weeks, I am quite close with the help provided by a user from this community. Do you know if this option is available for this uiKIT profile?
  42. 1 point
    Thank you, Pixrael! That got me to the solution! $loadLogo = $getKV->exhibitor_logo; $logoresize = $loadLogo->pim2Load('ig')->canvas(1600,895,array(0, 0, 0, 0),'c',0)->setOutputFormat("png")->pimSave()->httpUrl; $exlogo = $logoresize; $filename = $getKV->name . "_instagram.png"; $background = "https://domain.com/site/templates/images/Exhibitor-Graphic-BG-Platinum.jpg"; $logo = file_get_contents("$exlogo"); $bg = file_get_contents("$background"); $im = new \Imagick(); $im->readImageBlob($bg); $im2 = new \Imagick(); $im2->readImageBlob($logo); $im->compositeImage($im2, \Imagick::COMPOSITE_ATOP, 100, 350); $im->setImageFormat("png24"); $im->scaleImage(1024, 1024, true); $im->writeImage("../downloads/$filename"); $im->clear(); $im->destroy(); $file = "https://domain.com/site/downloads/$filename"; echo "<img src='$file' alt='$getKV->name' />"; Now I just need to bring in the code to start with a different background graphic based on the order history in Padloper. In THEORY, I'm almost there! 😅 Thanks so much for your help!
  43. 1 point
    We recently rebuilt the Architekturführer Köln (architectural guide Cologne) as a mobile-first JavaScript web app, powered by VueJS in the frontend and ProcessWire in the backend. Concept, design and implementation by schwarzdesign! The Architekturführer Köln is a guidebook and now a web application about architectural highlights in Cologne, Germany. It contains detailled information about around 100 objects (architectural landmarks) in Cologne. The web app offers multiple ways to search through all available objects, including: An interactive live map A list of object near the user's location Filtering based on architect, district and category Favourites saved by the user The frontend is written entirely in JavaScript, with the data coming from a ProcessWire-powered API-first backend. Frontend The app is built with the Vue framework and compiled with Webpack 4. As a learning exercise and for greater customizability we opted to not use Vue CLI, and instead wrote our own Webpack config with individually defined dependencies. The site is a SPA (Single Page Application), which means all internal links are intercepted by the Vue app and the corresponding routes (pages) are generated by the framework directly in the browser, using data retrieved from the API. It's also a PWA (Progressive Web App), the main feature of which is that you can install it to your home screen on your phone and launch it from there like a regular app. It also includes a service worker which catches requests to the API and returns cached responses when the network is not available. The Architekturführer is supposed to be taken with you on a walk through the city, and will keep working even if you are completely offline. Notable mentions from the tech stack: Vue Vue Router for the SPA functionality VueX for state management and storage / caching of the data returned through the API Leaflet (with Mapbox tiles) for the interactive maps Webpack 4 for compilation of the app into a single distributable Babel for transpilation of ES6+ SASS & PostCSS with Autoprefixer as a convenience for SASS in SFCs Google Workbox to generate the service worker instead of writing lots of boilerplate code Bootstrap 4 is barely used here, but we still included it's reboot and grid system Backend The ProcessWire backend is API-only, there are no server-side rendered templates, which means the only PHP template is the one used for the API. For this API, we used a single content type (template) with a couple of pre-defined endpoints (url segments); most importantly we built entdpoints to get a list of all objects (either including the full data, or only the data necessary to show teaser tiles), as well as individual objects and taxonomies. The API template which acts as a controller contains all the necessary switches and selectors to serve the correct response in <100 lines of code. Since we wanted some flexibility regarding the format in which different fields were transmitted over the api, we wrote a function to extract arbitrary page fields from ProcessWire pages and return them as serializable standard objects. There's also a function that takes a Pageimage object, creates multiple variants in different sizes and returns an object containing their base path and an array of variants (identified by their basename and width). We use that one to generate responsive images in the frontend. Check out the code for both functions in this gist. We used native ProcessWire data wherever possible, so as to not duplicate that work in the frontend app. For example: Page names from the backend translate to URLs in the frontend in the form of route parameters for the Vue Router Page IDs from ProcessWire are included in the API responses, we use those to identify objects across the app, for example to store the user's favourites, and as render keys for object lists Taxonomies have their own API endpoints, and objects contain their taxonomies only as IDs (in the same way ProcessWire uses Page References) Finally, the raw JSON data is cached using the cache API and this handy trick by @LostKobrakai to store raw JSON strings over the cache API. Screenshots
  44. 1 point
    GraphQL requests are slow for sure, but 6 seconds is a bit too much. In my cases it usually took around 200-300ms. Not sure what's causing it to be so slow on your end.
  45. 1 point
    Please test your query in a Graphiql. Insert your query in the Graphiql and confirm that the "product_single.list" is an array of nulls. Now remove every field inside the list and leave "id" and confirm that the list now contains objects with single "id" property in it. If that was successful then keep adding your "product_single" fields one by one. Whenever you see that the list is an array of "null"s, it means that exact field is causing this issue.
  46. 1 point
    Unfortunately I haven't had much time in optimization for this module. I'm very busy so can't promise any timelines when this will happen. The only thing you can do now is to keep your graphql schema as small as possible by unchecking all the unwanted fields and templates in the module config page. There is supposed to be a way to cache the schema (https://github.com/youshido-php/GraphQL/pull/37) I was planning to look into it. But never had a time for it and thus is not implemented in this module yet.
  47. 1 point
    There is not need for different endpoint for users with different roles. The module does not have any authentication/authorization logic on it's own. The users that will be able to authenticate with this module are the same users in your ProcessWire installation. When I mentioned implementing authentication, I was talking about logging in via GraphQL api, like via AJAX. In reality it will be the same $session->login('username', 'password'), nothing more. No, no. Of course not. I am sorry for the confusion here. Legal templates mean legal for the api. It does not mean it will make it available to the public. Like I mentioned earlier the module checks if the requesting user has permissions to view, edit, create and etc. If say you select user template as legal. It does not mean it will be public. It means it is available via api to those who are authorized to view it, authorized via ProcessWire's access control system. I personally don't think there is even a need for the legal templates option. But it is helpful if you have too many templates and selecting only few can reduce the schema size and make api faster. I think there is a bit confusion about this. I want emphasize that this module does not make any data public, nor does it anything private. That is not the module's concern. The module's job is to make your data available in a JSON format, in addition providing the ability to consume that JSON data via GraphQL api. If the user does not have permissions to view a certain page according to ProcessWire's access control system then he won't be able to fetch it. The same goes for fields. When implemented the user will be able to access only those fields that he is authorized via ProcessWire's access control. But I will add an option for legal fields also, because that also could help reduce the initial schema size.
  48. 1 point
    sure, here are some examples, i have these in a file called schema_helpers.php, which is in my shared functions folder: 1.) function siteSchema() { $page = wire('page'); $schema = array( "@context" => "http://schema.org", "@type" => "Website", "url" => wire('pages')->get(1)->httpUrl, "name" => $page->title, "description" => '', "potentialAction" => array( "@type" => "SearchAction", "target" => wire('pages')->get(1000)->httpUrl . "?q={search_term}", "query-input" => "required name=search_term" ), "about" => array( "@type" => "Thing", "name" => "A very interesting THING", "description" => "Website about a very interesting THING" ) ); if($page->summary) { $schema['description'] = $page->summary; } else { unset($schema['description']); } return '<script type="application/ld+json">' . json_encode($schema) . '</script>'; } 2.) News function jsonldNews($item, $settings) { $image = $item->image ?: getFallbackImage($item); if(!$image) return; $out = ''; $jsonld = array(); $jsonld["@context"] = "http://schema.org/"; $jsonld["@type"] = "NewsArticle"; $jsonld["name"] = $item->title; $jsonld["headline"] = $item->title; $jsonld["url"] = $item->httpUrl; $jsonld["mainEntityOfPage"] = array( '@type' => "WebPage", '@id' => $item->httpUrl ); $jsonld["description"] = $item->summary; $jsonld["datePublished"] = date(DATE_ISO8601, $item->published); $jsonld["dateModified"] = date(DATE_ISO8601, $item->modified); $jsonld["dateline"] = date(DATE_ISO8601, strtotime($item->news_date)); $jsonld["wordCount"] = str_word_count($item->body); $jsonld['author'] = $settings['author']; $jsonld['publisher'] = $settings['entity']; $jsonld['articleBody'] = $item->body; $jsonld['articleSection'] = $item->categories_select->first()->title; // Publisher $pubLogo = wire('pages')->get(3525)->image; if($pubLogo) { $pubLogo = $pubLogo->height(60); $jsonld['publisher'] = array( '@type' =>'Organization', 'name' => 'A Publisher', 'url' => 'https://publisher.org/', 'logo' => array ( '@type' => 'ImageObject', 'url' => $pubLogo->httpUrl, 'height' => $pubLogo->height, 'width' => $pubLogo->width ) ); } // News Items may have a featured image $image = $image->width(696); $jsonld['image'] = array( "@type" => "ImageObject", 'url' => $image->httpUrl, 'height'=> $image->height, 'width' => $image->width ); $out .= '<script type="application/ld+json">' . json_encode($jsonld) . '</script>'; return $out; } 3.) Event function jsonldEvent($event) { if(!$event->event_location_select) return; if($event->template == 'event-child') { // inherit unset fields needed $event->event_link = $event->event_link ? : $event->parent->event_link; $event->body = $event->body ? : $event->parent->body; $event->event_location_select = $event->event_location_select ? : $event->parent->event_location_select; $event->price = $event->price ? : $event->parent->price; $event->currency_code = $event->currency_code ? : $event->parent->currency_code; $event->link = $event->link ? : $event->parent->link; } $out = ''; foreach($event->event_date_m as $ed) { $jsonld = array(); $date8601 = date(DATE_ISO8601, strtotime($ed)); $jsonld["@context"] = "http://schema.org/"; $jsonld["@type"] = "MusicEvent"; $jsonld["name"] = $event->title; $jsonld["url"] = $event->event_link; $jsonld["description"] = $event->body; $jsonld["startDate"] = $date8601; if($event->event_location_select) { $state = $event->event_location_select->state ? $event->event_location_select->state->title : $event->event_location_select->address_state; $jsonld["location"] = array( "@type" => "Place", "name" => $event->event_location_select->title, "url" => $event->event_location_select->link, "address" => array( "@type" => "PostalAddress", "streetAddress" => $event->event_location_select->address_street, "addressLocality" => $event->event_location_select->address_city, "addressRegion" => $state, "postalCode" => $event->event_location_select->address_zip, "addressCountry" => $event->event_location_select->country->title ) ); } if($event->price && $event->currency_code && $event->link) { $jsonld["offers"] = array( "@type" => "Offer", "description" => "Tickets", "price" => $event->price, "priceCurrency" => $event->currency_code, "url" => $event->link ); } $out .= '<script type="application/ld+json">' . json_encode($jsonld) . '</script>'; } return $out; } Also - I don't think you need to use JSON_PRETTY_PRINT
  49. 1 point
    Quickly toggle your checkboxes with extra action buttons via AJAX. The module adds functionality to InputfieldCheckbox so you can toggle the checkbox fields in the extra action buttons intruduced in ProcessWire 2.6.5 via AJAX. Github Page Download Link Requirements This module works only for ProcessWire versions later than 2.6.5. How to Install 1. Copy the files to /site/modules/ProcessQuickToggle/ 2. In your admin, go to Modules > Refresh for new modules. 3. Click the "Install" button next to "Process Quick Toggle". Usage Go to any checkbox field you want to enable quick toggle feature for. Setup > Fields > my_checkbox_field. There in the Input tab you should see an Enable Quick Toggle field. After you check it you will see some fields that you can fill based on your needs. Then save the field. Now there should be an extra button for every page that has this field in the Pages tree. Features Supports template contexts. Supports core FontAwesome icons. Any kind of feedback is appreciated.
  50. 1 point
    Categories are really a perfect use case for pages rather than options. But to answer your question, this should do it: $options = $fieldtypes->get('FieldtypeOptions')->getOptions('categories'); foreach($options as $option) { echo $option->title; } This also works: $field = $fields->get('categories'); $options = $field->type->getOptions($field); If you are going to be using the selections for anything, use the $option->id property, rather than the title, just in case you later go back and change the title or something.
  • Create New...