Jump to content


Popular Content

Showing content with the highest reputation on 06/14/2019 in all areas

  1. 11 points
    ProcessWire 3.0.133 adds a useful new $page->meta() method for a new type of page-specific persistent data storage, adds the ability for users to create their own bookmarks in Lister, and has a handy and time saving update for the asmSelect input type. Read on for all the details, examples and screenshots— https://processwire.com/blog/posts/pw-3.0.133/
  2. 4 points
    Repeaters are a PageArray (or i think a class that inherits from it, called RepeaterPageArray), so you have all the methods from a WireArray such as: https://processwire.com/api/ref/wire-array/get/ https://processwire.com/api/ref/wire-array/find/ $page->repeater_field->get('FieldA=2')->FieldC
  3. 3 points
    I know from a trusted source that some of you use Laragon as their prefered Windows DEV solution. Due to a recent conversation I noticed that there might be a nice little feature some of you may not know about. Laragon offers the Quick app option with some tools already predefined. In order to have ProcessWire there as well you just have to add one (two with a comment) line to your Laragon configuration. # ProcessWire ProcessWire=composer create-project processwire/processwire %s Just in case you want to start your next project a little bit faster.
  4. 2 points
    Repeater Images Adds options to modify Repeater fields to make them convenient for "page-per-image" usage. Using a page-per-image approach allows for additional fields to be associated with each image, to record things such as photographer, date, license, links, etc. When Repeater Images is enabled for a Repeater field the module changes the appearance of the Repeater inputfield to be similar (but not identical) to an Images field. The collapsed view shows a thumbnail for each Repeater item, and items can be expanded for field editing. Screencast Installation Install the Repeater Images module. Setup Create an image field to use in the Repeater field. Recommended settings for the image field are "Maximum files allowed" set to 1 and "Formatted value" set to "Single item (null if empty)". Create a Repeater field. Add the image field to the Repeater. If you want additional fields in the Repeater create and add these also. Repeater Images configuration Tick the "Activate Repeater Images for this Repeater field" checkbox. In the "Image field within Repeater" dropdown select the single image field. You must save the Repeater field settings to see any newly added Image fields in the dropdown. Adjust the image thumbnail height if you want (unlike the core Images field there is no slider to change thumbnail height within Page Edit). Note: the depth option for Repeater fields is not compatible with the Repeater Images module. Image uploads feature There is a checkbox to activate image uploads. This feature allows users to quickly and easily add images to the Repeater Images field by uploading them to an adjacent "upload" field. To use this feature you must add the image field selected in the Repeater Images config to the template of the page containing the Repeater Images field - immediately above or below the Repeater Images field would be a good position. It's recommended to set the label for this field in template context to "Upload images" or similar, and set the visibility of the field to "Closed" so that it takes up less room when it's not being used. Note that when you drag images to a closed Images field it will automatically open. You don't need to worry about the "Maximum files allowed" setting because the Repeater Images module overrides this for the upload field. New Repeater items will be created from the images uploaded to the upload field when the page is saved. The user can add descriptions and tags to the images while they are still in the upload field and these will be retained in the Repeater items. Images are automatically deleted from the upload field when the page is saved. Tips The "Use accordion mode?" option in the Repeater field settings is useful for keeping the inputfield compact, with only one image item open for editing at a time. The "Repeater item labels" setting determines what is shown in the thumbnail overlay on hover. Example for an image field named "image": {image.basename} ({image.width}x{image.height}) https://github.com/Toutouwai/RepeaterImages https://modules.processwire.com/modules/repeater-images/
  5. 2 points
    Glad to hear that it's working 🙂 Process modules make execute*() methods available as individual URLs. If you want everything on one page, you can either put it all within the default execute() method, OR you can split your code into multiple methods and use them within the execute() method to render the final output (just don't name them with the execute-prefix, if you don't want them to be accessible in their own URLs.) It's a bit complicated so perhaps not the best example for a beginner, but if you take a look at the ProcessChangelog module execute() method, you'll see a number of render-prefixed method calls. That's not an "official Process module thing", but rather my own convention – it's simply one approach to split otherwise unbearably long execute method into smaller, more manageable pieces 🙂
  6. 2 points
    @thibaultvdb I think that by default on XAMPP your ProcessWire installation is in a subdir, and I bet that the module is giving you as api endpoint something like : /subdir/api instead of the /api endpoint. You should ask your friends to help you to setup your localhost environment to use a domain like http://mylocalwebsite.local To get started, you can follow the second answer here : https://stackoverflow.com/questions/16229126/using-domain-name-instead-of-localhost-in-with-https-in-xampp or follow this tutorial to use AcrylicDNS (the best solution IMO, do not be afraid, it's really easy to setup) : https://www.ottorask.com/blog/automated-apache-virtual-hosts-on-windows/ Good luck.
  7. 2 points
    So, I saved your code at /site/modules/CustomAdminPage.module, installed the module, and opened /processwire/customadminketan/table/ on my site.. and it works just fine 🙂 Are you sure that if you install the code above as a module, it definitely doesn't work for you? In that case it looks like we might need some additional info. First of all, which version of ProcessWire are you using, and what kind of a setup do you have (Apache or something else, Windows or Linux, are you developing locally or an a server, etc.) Does everything else in the admin seem to work as expected?
  8. 2 points
    I'm not really sure, why this would need to be bundled with FormBuilder. The attached module is a totally self contained module, which downloads the list from the given github url. It automatically tries to update once a day and uses the etag/if-none-match headers to determine if the list itself changed, to prevent sending of the list if there wasn't a change. The list and the etag are stored using WireCache in the db. There's public api to fetch the list and check if a domain is in the list. To use it in FormBuilder hooks should be the answer. EmailSchreck.module
  9. 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
  10. 1 point
    This article goes through many different techniques: https://css-tricks.com/deployment/ My approach is using rsync inside a bash script: https://css-tricks.com/deployment/#article-header-id-9 @wbmnfktr This is for you: https://css-tricks.com/deployment/#article-header-id-5
  11. 1 point
    If I understand right you need to use a repeating fieldtype that contains a Page Reference field and a text field for the unique code. You could use any repeating type such as Repeater, PageTable or ProFields Table, but I think ProFields Table would be the optimal interface. You can use some custom JS in Page Edit to disable options in the Page Reference field that have already been selected in another row of the table - just shout if you need advice for doing that.
  12. 1 point
    Oh... kay... now I understand and get almost the whole idea here. This might be too good to be true but maybe your client already has a CSV, XML or something similar with each and every possible configuration... you could import and use. With such a foundation/starting point you could even take a lot of stress on the client-side.
  13. 1 point
    $page->meta() is great, I will use it in the coming version of https://modules.processwire.com/modules/elasticsearch-feeder/
  14. 1 point
    Hey there! I've been using this module on several sites and it's great! I did notice, however, that it didn't seem to compress as much as the comparable plugin for WordPress. After doing some digging, I realized it's because it's set to retain exif data. For small images, this can increase size considerably, up to double (what would normally compress down to 40KB might be ~80KB with exif maintained). In my site installations, I'm just manually changing line 48 in AutoSmush.module from const WEBSERVICE = 'http://api.resmush.it/ws.php?exif=true&img='; to const WEBSERVICE = 'http://api.resmush.it/ws.php?img='; Would it be possible to add this as an option in the plugin?
  15. 1 point
    Well, I was really dumb here. All it took was me taking a break and coming back with some fresh eyes. After another failed attempt to get it working, I decided to bdump $rawTags and $tags and then it hit me. $rawTags bdump: (which were the select values posted by the form): "1102,1103,1104,1105" $tags bdump (what BitPoet wrote me): array(1) 0 => "1102,1103,1104,1105" I was essentially passing an array with 1 item with all the ids. After using $tagsArray = explode(',', $rawTags); I get: array(4) 0=>"1102" 1=>"1103" 2=>"1104" 3=>"1105" and then it succesfully works with ->add(array($tagsArray)); I appreciate everyone's help with this and patience. I can finally put this to bed.
  16. 1 point
    Maybe they renamed it for whatever reason. Try to add the line to your configuration. I guess it should work in your version as well.
  17. 1 point
    You could try thuis module! At least with png, jpg most surely it works, not sure about bmp.
  18. 1 point
  19. 1 point
    Well... you can't really compare any other ProcessWire site with ProCache to your site. So... let's go another way here to find out if ProCache is even necessary in your case. Are there more than 100 visitors per hour? Are there heavy or large peaks of visitors? Do you have to query lots and lots of data on each page load? Then ProCache is probably a good choice. You could also use and try template cache and wire cache, which are both quite good actually, and precompile and minify every CSS and JS before using it. With those two tools can easily optimize a ProcessWire site to a certain level and boost performance/speed even without ProCache. ProCache is an awesome tool but even with it enabled you can build slow sites. And the other way around of course.
  20. 1 point
    My apologies Teppo Im new to programming /processwire/customadminketan/table/ this works fine. I wanted everything one page
  21. 1 point
    If I understand your question correctly, as long as you use relative URLs instead of hardcoded absolute URLs, this shouldn't be a problem.
  22. 1 point
    Yes I develop site locally and moved it online. Thanks! 🙂
  23. 1 point
    I just wrote that before posting it here. It didn‘t exist a few hours ago 🙂
  24. 1 point
    Well- I live in California and I heard about the CCPA (California Consumer Privacy Act) and had to look it up. When I found the rules it put in place I remembered why- the requirements for entities having to comply with it are well outside of most companies. (Sharing the details here for anyone who stumbles upon this thread). Businesses that earn $25,000,000 or more a year in revenue Businesses that annually buy, receive, sell or share personal information of 50,000 or more consumers, households or devices for commercial purposes Business that derive 50% or more of its annual revenue from selling consumer personal information Basically- Google, Facebook, Twitter, etc. are located here in California and this was targeting them. Apart from that politicians in America and the states within it basically dilute legal measures or do nothing at all. We're lucky in California we even got that. I also had to look up the EU-US privacy law and from what I understand that was basically the U.S. telling the EU that their privacy laws do not protect any American citizen in the EU (surprise). You're totally right about American companies operating with respect to actual EU citizens though.
  25. 1 point
    www.kentvitrini.com - It is a City Portal of Corlu (Turkey) , our hometown. After using TYPO3 CMS for more than 10 years for our projects, this is our first PW project. With PW less effort, less stress but much more fun. I am impressed. For Mobile Chrome Users : The site is a PWA (Progressive Web App), so it can be downloaded to the homescreen of the phone for future visits. As it is in turkish let me describe it: It has 3 main data groups - "Haberler" are News - "Firma Rehberi" is a Company Directory - "Etkinlik" are Events As there will be more and more information on the site a Live Search will help the visitors to find everything they need. For trying type "corlu" as search word, after 3 letters the search will be loading results. The Top Menu is "Mega Menu" enabled. Looks pretty good on hover On top (under the main menu) there is mix of all content. It looks like a billboard. Below are "Featured Companies" in random order, so the order of the companies changes with every load of the page. Below (Left) News Below (Left) nearest Events. And below (Sidebar) A summery of all content, Weather, pharmacy on duty. We will add Classified ads and "Who is Who" sections in near future.
  26. 1 point
    @thibaultvdb It's a bit difficult to help from here. One thing you could try is to go through the code in Router.php and return or exit early to find out until where the code runs. The main functions are "go()" and "handle()". Another idea is to compare php settings between your hosted and local environment with "phpinfo()". If you can isolate the issue it's much easier to help.
  27. 1 point
  28. 1 point
    Welcome to the forums @e0f 🙂 When you use a datetime string (e.g. 2019-06-08) in a $pages->find() selector, the string gets converted to a timestamp behind the scenes via strtotime(). And if you only supply a date without any hours/minutes/seconds to strtotime() then 00:00:00 (midnight) is assumed. This means that in your selector you are actually searching for pages created between 2019-06-08 00:00:00 and 2019-06-10 00:00:00, so you will not find any events created after 00:00:00 on 10 June. So you can fix this by including a time in the second datetime string: $result = $pages->find("template=test, id>1, sort=myFieldName, sort=-created, status=unpublished, created>='2019-06-08', created<='2019-06-10 23:59:59'"); Also, you don't need parentheses around this portion of the selector.
  29. 1 point
    Hey everyone searching for this topic — if you're using Let's Encrypt with URL validation, don't forget to replace the part blocking dotfiles location ~ /\. { deny all; } With block denying everything BUT .well-known location ~ /\.(?!well-known).* { deny all; }
  30. 1 point
    I ran into issues with a slow server using this method, where wireHttp would already resolve a result while RestApi was still running. So with help from my co-worker @harmvandeven we came up with a more stable version, with some more redundancy: <?php /* api.php, a simple PW template to fill the gap between the RestApi and ProCache modules v2 @author: @eelkenet, with help from @harmvandeven & @ryan 1. Create a template called 'api' and set it up using the following settings: - Allow URL segments - Allow guests to view the page - Set the Content-Type to application/json - Make sure to NOT Prepend or Append any files 2. Add a page using this template and allow ProCache to run its magic */ $timeout = 600; $maxAttempts = 10; // Pre-check for unwanted symbols if (strpos($input->urlSegmentStr(), '.') !== false) { throw new Wire404Exception(); } // Build request URL $endpoint = $modules->get("RestApi")->endpoint; $url = $input->scheme() . "://" . $config->httpHost . "/" . $endpoint ."/" . $input->urlSegmentStr(); $http = new WireHttp(); // Set a high timeout, to deal with a slow server $http->setTimeout($timeout); // Get the HTTP status of the page, to make sure it exists in the first place $status = $http->status($url); // If the page exists, or possibly redirects to valid content if ($status >= 200 && $status < 400) { $result = false; $attempt = 0; // If the result isn't a string, something went wrong while(gettype($result) !== "string" && $attempt++ < $maxAttempts) { $result = $http->get($url); if ($attempt > 1) wire()->log->message("Loading content at $url, attempt $attempt: " . gettype($result)); } // Double check if the data is a string.. if (gettype($result) === "string"){ // .. And check if it can be decoded, if so: return the data and thus cache it if (json_decode($result) !== NULL) return $result; // If it cannot be decoded: throw exception (don't cache it) throw new WireException("Found the data at $url, but it could not be decoded. Please check your API output!"); } // Throw exception if data could not be loaded in time (don't cache it) throw new WireException("Found the data at $url, but could not load it in time, after $attempt attempts. Result has type: " . gettype($result)); } // Throw generic exception if the requested page was not found or there was another error throw new WireException("Failed to load the content at: $url, with HTTP status: " . $status);
  31. 1 point
    For the last couple months, I've been working on a module that does exactly this. It's not a site profile, it's not a theme. I don't know what term would accurately describe it, but its a ProcessWire module that's an opinionated, update-able starting point, oriented towards developers, and brings in a bunch of boilerplate like: an installer that will create fields, templates, pages, hannacodes; it runs through a thorough check before doing anything that may result in an error (module installation errors are aggravating; i'm testing it very thoroughly) the installer will rename your 'templates' dir to something temporary, and then copy a starting 'templates' folder that's prepped for the module (you should only do this on dev) if you try to add it to an existing site with a bunch of data, it will work as long as there are not collisions in some fields and templates; if there are, the module won't install and tell you what you need to change around to allow it to install establishes some new $config variables ('env', 'disableTemplateCache', a few others) built with UIkit 3 in mind, but not hardcoded to it a menu builder based on Repeaters with its own Process Module has its own seo+og+twitter+sitemap metadata fields and uses Profields FieldGroup since that is the best module for handling such a grouping has it's own templates inside the module which can be used, or overridden in /site/templates/; this includes blog sitemap.xml maintenance search in addition to template files being able to be overridden, partial files can be overridden too! some module configuration fields (site_name, maintenance, etc.) the module has documentation and other statistics built into it for easy reference takes full advantage of setting() and markup regions; applies attributes like UIkit 'uk-grid' and other data attributes without "touching" the html; keeps the module flexible and easily allows you to rip out UIkit and swap it for another CSS framework (Bootstrap 4); you'll never need to touch edit the _main.php file because of how regions has been set up has it's on RepeaterMatrix fields with boilerplate matrix-types (headline, text, slideshow, etc. etc.); if the user makes new custom matrix types and a later version of my module brings in a new matrix-type, it will update the RepeaterMatrix field and merge it correctly (tricky to do!); the matrix types use many of the same base fields, thereby allowing you to switch from one matrix type to another without data being destroyed (this was only possible as of 2 weeks ago with the new matrix update) to avoid creating a bunch of 1-off fields for the matrix field for block configuration, it uses the new and quite amazing Mystique fieldtype in a unique way (this was tricky to do); this module is critical to establishing a page-builder that is clean (this was only possible as of April 2019 since the module is brand new) brings in PW's debugger to the frontend (brings in jQuery UI); can be disabled all field and template names don't use any prefixes; this would allow you to dump the module one day in the future if you don't like it, without having a bunch of field and template names that sound too specific to the module Laravel Mix based asset compiler pre-configured with UIkit works with FormBuilder and other modules I often use; works and may require certain Pro modules; eliminates the need for any modules that do blogging, menu building, sitemap, maintenance or seo since this module does it using native ProcessWire login/logout/account/register templates it may include a 'collection' generator for common things like events, products, people, properties, along with some templates for those. don't like the templates my module provides? then just create your own template file in /site/templates/the-template-file.php which will override /site/modules/my-module-name/templates/the-template-file.php Right now I just started building a few sites with it (spent the last 2 months developing it) which will hammer it out further. I will release it late summer, early fall.
  32. 1 point
    v0.2.1 released. This is a fairly major update in that there has been quite a bit of refactoring. Please be alert for and report any issues. ProcessWire >= v3.0.0 is now required. This release adds a new hookable HannaCodeDialog::buildForm() method that lets you build the dialog form in the hook rather than setting inputfield options as pseudo-attributes in the Hanna Code tag settings. From the readme... Build entire dialog form in a hook You can hook after HannaCodeDialog::buildForm to add inputfields to the dialog form. You can define options for the inputfields when you add them. Using a hook like this can be useful if you prefer to configure inputfield type/options/descriptions/notes in your IDE rather than as extra attributes in the Hanna tag settings. It's also useful if you want to use inputfield settings such as showIf. When you add the inputfields you must set both the name and the id of the inputfield to match the attribute name. You only need to set an inputfield value in the hook if you want to force the value - otherwise the current values from the tag are automatically applied. To use this hook you only have to define the essential attributes (the "fields" for the tag) in the Hanna Code settings and then all the other inputfield settings can be set in the hook. Example buildForm() hook The Hanna Code attributes defined for tag "meal" (a default value is defined for "vegetables"): vegetables=Carrot meat cooking_style comments The hook code in /site/ready.php: $wire->addHookAfter('HannaCodeDialog::buildForm', function(HookEvent $event) { // The Hanna tag that is being opened in the dialog $tag_name = $event->arguments(0); // Other arguments if you need them /* @var Page $edited_page */ $edited_page = $event->arguments(1); // The page open in Page Edit $current_attributes = $event->arguments(2); // The current attribute values $default_attributes = $event->arguments(3); // The default attribute values // The form rendered in the dialog /* @var InputfieldForm $form */ $form = $event->return; if($tag_name === 'meal') { $modules = $event->wire('modules'); /* @var InputfieldCheckboxes $f */ $f = $modules->InputfieldCheckboxes; $f->name = 'vegetables'; // Set name to match attribute $f->id = 'vegetables'; // Set id to match attribute $f->label = 'Vegetables'; $f->description = 'Please select some vegetables.'; $f->notes = "If you don't eat your vegetables you can't have any pudding."; $f->addOptions(['Carrot', 'Cabbage', 'Celery'], false); $form->add($f); /* @var InputfieldRadios $f */ $f = $modules->InputfieldRadios; $f->name = 'meat'; $f->id = 'meat'; $f->label = 'Meat'; $f->addOptions(['Pork', 'Beef', 'Chicken', 'Lamb'], false); $form->add($f); /* @var InputfieldSelect $f */ $f = $modules->InputfieldSelect; $f->name = 'cooking_style'; $f->id = 'cooking_style'; $f->label = 'How would you like it cooked?'; $f->addOptions(['Fried', 'Boiled', 'Baked'], false); $form->add($f); /* @var InputfieldText $f */ $f = $modules->InputfieldText; $f->name = 'comments'; $f->id = 'comments'; $f->label = 'Comments for the chef'; $f->showIf = 'cooking_style=Fried'; $form->add($f); } });
  33. 1 point
    There's also a nice roadmap of tabulator: https://trello.com/b/rPZ0Yavc/tabulator-roadmap Looking really nice so far!
  • Create New...