Jump to content

Search the Community

Showing results for tags 'Module'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Welcome to ProcessWire
    • News & Announcements
    • Showcase
    • Wishlist & Roadmap
  • Community Support
    • Getting Started
    • Tutorials
    • FAQs
    • General Support
    • API & Templates
    • Modules/Plugins
    • Themes and Profiles
    • Multi-Language Support
    • Security
    • Jobs
  • Off Topic
    • Pub
    • Dev Talk

Product Groups

  • Form Builder
  • ProFields
  • ProCache
  • ProMailer
  • Login Register Pro
  • ProDrafts
  • ListerPro
  • ProDevTools
  • Likes
  • Custom Development

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

  1. 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.
  2. Field Initial Value For most field types, allows the definition of an initial value that is automatically set when pages are created. The initial value can be set in template context if you want a different initial value in different templates. Example for a "Countries" Page Reference field using AsmSelect: Example with explanatory notes in a CKEditor field: Differences from "Default value" The core allows setting a "Default value" for certain field types. The "Initial value" setting added by this module is different from the "Default value" setting in the following ways: The "Default value" is a setting that applies only to the inputfield, meaning that the value is shown in the inputfield by default but is not stored until you save the page. By contrast, the "Initial value" is automatically saved to the page when the page is first created. Related to point 1, when a page is created via the API rather than in the ProcessWire admin the "Initial value" is saved to the page but the "Default value" is not. The "Default value" has no effect when a field is not "required", but the "Initial value" is set for both required and not required fields. Related to point 3, a user can empty a field that had an "Initial value" applied but a field with a "Default value" set cannot be emptied. The "Initial value" setting is available for more field types than "Default value". Supported field types The following field types are supported, along with any types that extend them: FieldtypeText (includes types that extend it such as Textarea, CKEditor, URL, etc.) FieldtypeDatetime FieldtypeInteger FieldtypeDecimal FieldtypeFloat FieldtypePage (with all core inputfield types) FieldtypeCheckbox FieldtypeOptions (with all core inputfield types) FieldtypeToggle FieldtypeSelector FieldtypeMultiplier (ProField) FieldtypeCombo (ProField, only supported when File and Image subfields are not used) FieldtypeStars (third-party module) If you want to try field types beyond this you can define additional types in the module config, but your mileage may vary. Unsupported field types It's not possible to set an initial value for these field types, along with any types that extend them: FieldtypeFile (and FieldtypeImage) FieldtypeRepeater (includes types that extend it such as Repeater Matrix and Fieldset Page) FieldtypePageTable FieldtypeTable (ProField) Notes Seeing as the initial value is defined in the field config it has no idea of the current page - for the purposes of rendering the initial value inputfield the home page is supplied as a dummy page. This probably isn't an issue in most cases but it might have an effect for some Page Reference fields if they use the current page to limit the selectable pages. https://github.com/Toutouwai/FieldInitialValue https://processwire.com/modules/field-initial-value/
  3. Hello, I was originally going to include this as part of my forthcoming AdminStyleChroma module but decided to roll it out as its own module. https://github.com/solonmedia/ImageColorThief Please check out the readme for a deeper explanation - but the short version here for now: This module adds two new methods to the Pageimage class, allowing you to extract the main dominant color or a palette of prevalent colors from an image. You can use the entire image to evaluate color dominance, or you can use a select swatch from the image based on inset rectangles from the edges, blocks at each corner, or a swatch centered on the focus point if you choose to use it. You can also select the granularity of the quantization to get more accurate color results. This is not an eyedropper algorithm - the colors are close approximates. Great if you have color schemes you'd like to coordinate with the headliner or seasonal images, or if you'd like to be able to sort a gallery of images by dominant color, etc. Looks real nice, for example if you are running a ken burns style image fade background and the images are sorted by a channel, etc. How to sort them? Ugh that's something I haven't tackled - yet: https://www.alanzucconi.com/2015/09/30/colour-sorting/ It works on JPG, GIF, PNG and WEBP images. It outputs RGB, HEX, RGB Integer, raw Array with R, G, B elements or an object. Once I've got myself registered and whatnot I'll submit it to the Modules Directory. Installs from zip for now: https://github.com/solonmedia/ImageColorThief/archive/refs/heads/main.zip I'd consider it Beta - the underlying libraries are pretty stable but I'd like to run a few more tests on input. Let me know if you have any questions/thoughts.
  4. Session Info Lists information about active sessions in a similar way to SessionHandlerDB, but for file-based sessions. Only install the module if you are not already using SessionHandlerDB. Installation 1. If you want to be able to see the pages that are being viewed by active sessions then set... $config->sessionHistory = 1; ...in /site/config.php If you have already set $config->sessionHistory to a higher number then you can leave it unchanged: 1 is the minimum needed for use in the Session Info module. 2. Install the Session Info module. A helper module named "Session Extras" will be automatically installed also. 3. If you want to be able to see the IP address and/or user agent for active sessions then visit the module config page for Session Extras and tick the relevant checkboxes. 4. You can now view information about active sessions at Access > Sessions. Screenshots With $config->sessionHistory set to 1 or higher: Additional information is listed when IP address and user agent tracking are enabled in Session Extras: https://github.com/Toutouwai/ProcessSessionInfo https://processwire.com/modules/process-session-info/
  5. Page List Auto Expand Automatically expands the next adjacent page when moving a page in Page List. Usage As you are moving a page in Page List, if you position the yellow move placeholder above a Page List item for a configurable period of time (default is 1000 milliseconds) then that item will expand, allowing the moving page to be dropped as child page. Configuration In the module config you can set the delay before the Page List item adjacent to the move placeholder will be automatically expanded. Restricting the module to certain roles If you want to restrict the module functionality to only certain roles then create a new permission named page-list-auto-expand. If that permission exists then a user's role must have that permission or the module will not have an effect in Page List. https://github.com/Toutouwai/PageListAutoExpand https://processwire.com/modules/page-list-auto-expand/
  6. Hi @kongondo I'm unable to select a file form media manager and I get this error, this error only appears when I try to select file via assistedURL field. can you help with this one? PW-3.0.165 MediaManagerImageEditor.js:77 Uncaught TypeError: Cannot read properties of undefined (reading 'getSelection') at insertLinkMediaManager (MediaManagerImageEditor.js:77:29) at HTMLButtonElement.<anonymous> (MediaManagerImageEditor.js:135:4) at HTMLButtonElement.dispatch (JqueryCore.js?v=183:2:38053) at HTMLButtonElement.u (JqueryCore.js?v=183:2:33916)
  7. Hi @kongondo, we have detected a problem using MediaManager with the newly introduced richtext editor TinyMCE. When selecting an item from MediaManager via the "Insert Link" dialog, it will not be stored. At the javascript console is written the following message: Uncaught TypeError: window.parent.CKEDITOR is undefined Is this an issue concerning to you, or for @ryan? Thank you and best regards, Thomas from XPORT.
  8. Template Access Log is a straightforward module that logs changes made to template level access settings: the useRoles option, or applicable roles and/or role-specific permissions. This module is primarily intended for use cases where an audit log is needed, and (at least for now) it just logs data to a log file template_access_log.txt and provides no admin view (apart from what can be found from the logs section in admin). Data is logged as JSON: 2023-03-18 18:42:05 admin https://example.com/processwire/setup/template/save {"template":"basic-page","template_id":29,"use_roles":1,"permissions":{"view":[37,1061,1062,1125],"edit":[1062],"add":[1061,1062],"create":[]},"permissions_changed":{"edit":[-1061]}} This is something that I needed for some projects, so thought I'd share it here in case someone else has use for it as well. I may add more features later, but at the moment it's already doing pretty much everything it needs to for my use case(s) 🙂 GitHub: https://github.com/teppokoivula/TemplateAccessLog Packagist: https://packagist.org/packages/teppokoivula/template-access-log
  9. WebP to JPG Converts WebP images to JPG format on upload. This allows the converted image to be used in ProcessWire image fields, seeing as WebP is not supported as a source image format. Config You can set the quality (0 – 100) to be used for the JPG conversion in the module config. Usage You must set your image fields to allow the webp file extension, otherwise the upload of WebP images will be blocked before this module has a chance to convert the images to JPG format. https://github.com/Toutouwai/WebpToJpg https://processwire.com/modules/webp-to-jpg/
  10. Hi all, Media Manager Next/013 Sorry I haven't posted here in a while. I am currently working on the next version of Media Manager. It will part be refactoring and part be some new (some requested) features. I have been having some very helpful conversations with a number of you. Below are the current plans for the next version. Any other thoughts and/or ideas I should consider? It is a bit of work so I might have to stretch this into several updates (versions). Thanks. New Features Upload from external sources (Amazon, Google, etc.). Point media to external resource (e.g. to a video in YT, Vimeo, etc.). Independently set media title on upload Improve/extend media filter/profiles to MM Inputfields (possibly pick and apply a profile from a list) (thanks @gebeer) PDF thumb preview (thanks @gebeer) Upload and replace media (for single media MM inputfields). API (thanks @MrSnoozles) Any other thoughts.....? Refactor Remove dependency on JqueryFileUpload Remove dependency on jQuery -> use htmx and alpine JS instead. Easier to maintain for me as well as more flexibility. Improved preview of media and their properties. Better preview of media before upload. Redesigned GUI - Intuitive (like GDrive(?)), do away with media menus (use filters instead), need oMedia is just media. Remove/reduce use of modals. Allow grouping of media (link an album) <- not yet confirmed if will be implemented Implement hookable methods to allow easier developer control for those who need advanced/custom control of their MM. A number of reported bug fixes as well. ETA? I cannot give a firm date about this, sorry.
  11. Replace Home An action for the Admin Actions module for ProcessWire CMS/CMF. The action replaces the template and content of the home page with that of a selected page. Sometimes there is a need to develop a new home page while keeping the existing home page in place until the new version is ready and approved. Then you want to apply the new home page, but this is not so easy to do in ProcessWire since home is a special page that cannot simply be replaced by another page. What the action does Removes all the fields from the home template, which simultaneously deletes all the content from the home page. Adds all the fields from the selected source page template and applies any template-specific overrides. Sets the home page field values to match the source page. Updates all file and image URLs in any textareas so they point to the home page files rather than the original source page. What the action doesn't do The action does not modify the home template file. You will probably want to update the home template file immediately after running the action (e.g. copy/paste the code of the source page template file). The action does not automatically delete the source page – that can be done manually after you have confirmed that the action was successfull. Warning This action is destructive! It deletes content/files/images from the existing home page. In addition to the automatic Admin Actions database backup you should create a backup of /site/assets/files/ before running this action, and consider also making a manual database backup for extra safety. Usage Install the Replace Home module. Visit the Admin Actions config screen and enable the "Replace Home" action for the roles who are allowed to use it. Create file system and database backups – see the warning section above. Navigate to Admin Actions > Replace Home, select the source page whose template and content will replace the home page, then execute the action. Update the home template file if needed. Screenshot https://github.com/Toutouwai/AdminActionsReplaceHome https://processwire.com/modules/admin-actions-replace-home/
  12. I am proud to announce my very first module: GooglePlaceDetails. I was in the need to include some google place reviews for a clients website. It turned out that no such review widget was available for ProcessWire. So I made my own solution which i want to share with you. Google Place Details for ProcessWire Modules Directory: https://processwire.com/modules/google-place-details/ Github: https://github.com/StefanThumann/GooglePlaceDetails What it does Google Place Details offers the possibility to send requests to the Google Maps API to receive information about a certain place. A typical use case would be to display the reviews of a place on your website. But you can receive any other information that the API offers. Before you start You need three things: A Google API Key The Place ID A project with a billing account activated You can set up all of those by using Googles quick start widget here: https://developers.google.com/maps/third-party-platforms/quick-start-widget-users How to install Copy this directory to /site/modules In your admin, go to Modules > Refresh, then Modules > New Click the "Install" button next to the Google Place Details module Fill out the API Key and Place ID fields in the module settings and you are ready to go. Module settings and field descriptions API Key This field is required and must contain your generated Google API key. Place ID This field is required. You can put the ID of any place into this field. Fields to include in request Specify a comma-separated list of place data types to return. Leave empty to load all default fields. For an overview of the available fields see: https://developers.google.com/maps/documentation/places/web-service/details Review Sorting Chose your sorting criteria. "Most relevant" is used by default. Preview Place Details If checked the place details can be previewed for debugging/development purpose on module page submit. Usage example Load the module in a page context: $module = $modules->get('GooglePlaceDetails'); Call a function to load data $module->getPlaceDetails(); This function fetches the data in realtime, on every page request and returns a php array containing the full response from the Google server. See the frontend example at the end of this document to see how to extract data from the array in a working example. Place details answer example The place details answer will be in JSON format and looks like this (depending of the fields you included in your request) { "html_attributions": [], "result": { "name": "Google Workplace 6", "rating": 4, "reviews": [ { "author_name": "Luke Archibald", "author_url": "https://www.google.com/maps/contrib/113389359827989670652/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a-/AOh14GhGGmTmvtD34HiRgwHdXVJUTzVbxpsk5_JnNKM5MA=s128-c0x00000000-cc-rp-mo", "rating": 1, "relative_time_description": "a week ago", "text": "Called regarding paid advertising google pages to the top of its site of a scam furniture website misleading and taking peoples money without ever sending a product - explained the situation, explained I'd spoken to an ombudsman regarding it. Listed ticket numbers etc.\n\nThey left the advertisement running.", "time": 1652286798, }, { "author_name": "Tevita Taufoou", "author_url": "https://www.google.com/maps/contrib/105937236918123663309/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a/AATXAJwZANdRSSg96QeZG--6BazG5uv_BJMIvpZGqwSz=s128-c0x00000000-cc-rp-mo", "rating": 1, "relative_time_description": "6 months ago", "text": "I need help. Google Australia is taking my money. Money I don't have any I am having trouble sorting this issue out", "time": 1637215605, }, { "author_name": "Jordy Baker", "author_url": "https://www.google.com/maps/contrib/102582237417399865640/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a/AATXAJwgg1tM4aVA4nJCMjlfJtHtFZuxF475Vb6tT74S=s128-c0x00000000-cc-rp-mo", "rating": 1, "relative_time_description": "4 months ago", "text": "I have literally never been here in my life, I am 17 and they are taking money I don't have for no reason.\n\nThis is not ok. I have rent to pay and my own expenses to deal with and now this.", "time": 1641389490, }, { "author_name": "Prem Rathod", "author_url": "https://www.google.com/maps/contrib/115981614018592114142/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a/AATXAJyEQpqs4YvPPzMPG2dnnRTFPC4jxJfn8YXnm2gz=s128-c0x00000000-cc-rp-mo", "rating": 1, "relative_time_description": "4 months ago", "text": "Terrible service. all reviews are fake and irrelevant. This is about reviewing google as business not the building/staff etc.", "time": 1640159655, }, { "author_name": "Husuni Hamza", "author_url": "https://www.google.com/maps/contrib/102167316656574288776/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a/AATXAJwRkyvoSlgd06ahkF9XI9D39o6Zc_Oycm5EKuRg=s128-c0x00000000-cc-rp-mo", "rating": 5, "relative_time_description": "7 months ago", "text": "Nice site. Please I want to work with you. Am Alhassan Haruna, from Ghana. Contact me +233553851616", "time": 1633197305, }, ], "url": "https://maps.google.com/?cid=10281119596374313554", "user_ratings_total": 939, "website": "http://google.com/", }, "status": "OK", } Usage in frontend example To display the reviews of a place you can do it like this (very basic markup!). I encourage every user to build their own markup of the reviews, fitting their design. <?php // 1. Connect to module $module = $modules->get('GooglePlaceDetails'); // 2. Save the details array to a variable $details = $module->getPlaceDetails(); // 3. Extract the data you want to iterate over $reviews = $details['result']['reviews']; // For debug purpose dump the array to inspect the data // TRACY DEBUGGER MODULE REQUIRED // dump($reviews); <? foreach ($reviews as $review) { ?> <div> <img src="<?=$review["profile_photo_url"]?>"/> <h4><?=$review["author_name"]?></h4> <? for ($i = 1; $i <= ($review['rating']); $i++) { ?> &#9733; <? } ?> <p><?=$review["text"]?></p> </div> <? } ?> ?> Here is a more advanced and nicer looking version (UIKit 3 Framework Markup is used) <div class="uk-container"> <div uk-slider> <div class="uk-position-relative"> <div class="uk-slider-container"> <ul class="uk-slider-items uk-child-width-1-2@s uk-child-width-1-3@m uk-grid uk-height-medium"> <? foreach ($reviews as $review) { ?> <li> <div class="uk-card uk-card-default uk-card-body"> <div> <img src="<?=$review["profile_photo_url"]?>" class="uk-responsive-width" style="height: 30px;" /> <span class="uk-text-middle"><?=$review["author_name"]?></span> </div> <div class="uk-margin"> <? for ($i = 1; $i <= ($review['rating']); $i++) { ?> &#9733; <? } ?> <? for ($i = 1; $i <= 5 - ($review['rating']); $i++) { ?> &#9734; <? } ?> </div> <div uk-overflow-auto="selContainer: .uk-slider-items; selContent: .uk-card"> <p><?=$review["text"]?></p> </div> </div> </li> <? } ?> </ul> </div> <a class="uk-position-center-left-out uk-position-small" href="#" uk-slidenav-previous uk-slider-item="previous"></a> <a class="uk-position-center-right-out uk-position-small" href="#" uk-slidenav-next uk-slider-item="next"></a> </div> </div> </div> If you are already using UIKit 3 and just want to get a quick result I put the code example above in a function that can can be called like this: <? $module = $modules->get('GooglePlaceDetails'); echo $module->getUIKitMarkupExample(); ?> The template file which is used for the markup lies inside the module directory. Adjust it to your needs.
  13. This isn't the first star rating module for ProcessWire, but I wanted some particular config options and to have the inputfield be usable within FormBuilder. FieldtypeStars The inputfield of FieldtypeStars uses a star rating interface to set a float value. The fieldtype extends FieldtypeFloat. The inputfield has no external dependencies such as jQuery or Font Awesome and can be used in FormBuilder. Config Using InputfieldStars in FormBuilder In order to add a Stars field to a FormBuilder form you must first enable "Stars" in the "Allowed Input Types" field in the FormBuilder module config. https://github.com/Toutouwai/FieldtypeStars https://processwire.com/modules/fieldtype-stars/
  14. Since InputfieldTinyMCE appears to make huge steps towards becoming a stable replacement for CKEditor and TinyMCE comes with a native autocomplete API, I just had to try my hands at migrating the autocomplete module I had built for InputfieldCKEditor. Lo and behold, it went even easier than I had hoped. So here - mind you, still very alpha - is my autocomplete module for the new TinyMCE input field. Since I may still introduce breaking changes while things become stable, it will only be available at GitHub for now. Autocompleter for InputfieldTinyMCE What does it do? Autocompleters work like the mention plugin in this forum. You type a "trigger" character (or characters) followed by some letters, and a list of possible results pops up, from which you can choose. InlineCompleteTinyMCE comes with three different autocompleters (called "actions" in the context of this module): Pages: you can configure a selector, just like when you search for pages in the ProcessWire backend. You can search for title, name or any field you would like. Like every action, it allows you to specify templates for the label and the HTML/text to insert. Users: this is the equivalent to the form mention. Type an "@" sign followed by the start of a user name, and it inserts a link to that user. If you have added an image field to the user template, you can display that in the selection popup too. Hanna Code: just type the opening tag ("[[" by default) for your Hanna code and any letter, and the module will look for all codes starting with those letters. You can easily implement your own action modules too. Just inherit from InlineCompleteTinyMCEAction and add the code for a few methods. Enabling Actions For every installed action, you will find a checkbox on the "Input" tab when you configure a field. Configuration for Actions Once you have enabled the action, more configuration options become visible. The exact options depend on the action itself, but you usually have a label template and a value template. You can use placeholders in both. Actions in Action This is what it looks like when used: Compatiblity The module has been tested with InputfieldTinyMCE v6.0.6 both in standalone and inline mode. Lazy loading the standalone editor is also supported. Outlook There's still a bit work waiting for me, from cleaning up some code, over making the Pages action support multiple autocompleters with different triggers and selectors, to adding a lot of documentation. Nevertheless, I'd be happy to get some feedback.
  15. Github: https://github.com/thetuningspoon/AdminPreSaveValidation This module prevents admin editors from saving changes to a page that has one or more invalid fields. It uses an ajax call to check for errors and javascript to populate the page edit form with any error messages that were returned. This way the user can correct the issues and resubmit the form without invalid data getting saved to the database or the editor losing changes. I've wanted a way to implement this common workflow in ProcessWire for some time now and this relatively simple ajax-based approach makes it possible without getting too much in the way of how ProcessWire normally works. For example, all of the post-save actions (Save + Exit, Save + View, etc.) still work as usual. The only downside is that a successful save will take a bit longer as it involves two sequential http requests (the initial ajax request that checks for errors and the normal page submit after no errors are returned). This module has also been tested successfully with repeaters and other nested inputs. By hooking after Inputfield::processInput, you can add your own custom validations to inputfields and this module will pick up on and display them as well. /* * Example of hook that adds an error to an inputfield. This will add an error to every input. */ $this->wire()->addHookAfter("Inputfield::processInput", function(HookEvent $event) { $event->object->error('Invalid input!'); }); I hope others will find this module useful!
  16. This might be a somewhat niche module but I had a need for it and maybe others will also find it a useful development helper. Lister To Clipboard Easily copy a selector for the current Lister filters or selected results to the clipboard. For superusers only. Why? Lister or Lister Pro is handy for finding pages according to certain page attributes or field values and you can see the matched pages in a results list. Sometimes I want to run code on some or all the Lister results. Lister Pro allows results to be processed through Page Action modules but there are a couple of downsides to this: To execute custom code you would have to create a custom Page Action module and this may not be worth the trouble for a one-off operation. If you want to process only selected individual pages you can only select items from one page of the results. If you navigate to a different page within the paginated results the selection is lost. Lister To Clipboard gives you an easy way to copy a selector for the current Lister filters or a selection within the results so you can paste it into the Tracy Debugger Console or use it elsewhere in your code. Usage In Lister (Find) or in a Lister Pro instance, create filters to match the pages you want to target. If you want to select individual pages within the results, click an empty area of the cell within the first column (i.e. don't click directly on the page title). The cell will get a green background to indicate that it is selected. If there is more than one page of results you can move around the pagination to select more pages. Below the Lister results there is a blue box showing a selector string that will find the pages shown in your Lister results (or your selection within those results) when used in $pages->find(). Click the copy icon to copy the selector to the clipboard, then you can paste it into the Tracy Debugger Console or wherever you want to use it. https://github.com/Toutouwai/ListerToClipboard https://processwire.com/modules/lister-to-clipboard/
  17. I'm working on a one-page, vanilla javascript and php (PW API) shopping checkout module that integrates PayPal server side. Here's version 1.0 https://github.com/dtjngl/kiosk Looking forward to your feedback! DISCLAIMER this is a BETA version at best, it's my first "real" module I'm writing for ProcessWire (and first module I'm writing at all) so please don't eat me alive. I'm aware that it needs a lot of work, but at this point, but it's functional. I'm also aware that it is not very customisable at this point (it's mostly customised for one specific use case), but I promise I will work on that. My main objective is to get more seasoned developers' mentoring, feedback, advice, warnings – and and of course, if you want to look into or help develop it further – pull requests. Please point out any potential dangers you see or anything that raises a red flag for you. I'm learning so much from that. Though the module is held in german, you can translate almost all strings that are in the php files via PW's translate functionality. I cannot help with the strings in the javascript yet, but will do so soon (using a json file that lives on the file system probably). I started working on this module because many checkout systems out there are either overkill and too complicated, didn't fulfil my needs or come with a premium fee that is not worth it. Also, austrian law (and other countries' jurisdiction) demand a different flow than what PayPal's Express checkout offers. So this version makes calls to PayPal on the server. WHAT IT CONTAINS - OnePage checkout system with 4 steps: cart, address(es) form, payment method (paypal and deferred), order overview - "minicart" (the cart-summary in the page's header) - buy button (to add items to the cart) - a dashboard (with admin template) for an overview of all placed orders uses server session storage and browser localstorage REQUIRED WireMail SMTP UIKIT (for best behaviour, will be optional soon) vanilla Javascript (no jQuery required) PHP (DUHDOY!) ProcessWire Version (not sure, but works with version 3.0.200) if you want it in english you need a multi-language installation PayPal Business Account (Live or Sandbox to test with) HOW TO INSTALL 1. Put the folder "Kiosk" in your ProcessWire site's modules folder 2. Install the module Kiosk, this will… - create fields for the order template - create a template for the orders placed - create a template for the orders' parent page - create a parent page "Custom Orders" for all orders under /admin/page/ (you can rename the page, not the template) - create a template "kiosk_checkout" for the checkout page - create a page "Checkout" for the checkout, child to "Home" (you can move the page, you can rename the page, not the template) - install module ProcessKiosk along with it - ProcessKiosk create a page under /admin/ (visible in the module upon creation). Here you will see a table with all the orders placed. 3. check the Kiosk module's settings page (navigate via the module's overview page) and enter details to your best knowledge. Some are not "required" but they actually are. 4. Put the below code (in essence) on "kiosk_checkout.php": if ($config->ajax) { $kiosk->handleAJAX($input); return $this->halt(); } else { $kiosk->handleStaticContent($input); echo $kiosk->renderCheckoutSteps(); } 5. put this line on a page that loads everywhere, preferably on init.php: $kiosk = $modules->get('Kiosk') 6. put this line where you want the "minicart" and toggling cart preview (provided the site runs UIKIT) to be, probably in a header that renders on each page: echo $kiosk->renderMiniCart(); 7. put this line just above you closing tag: echo $kiosk->addScripts(); HOW DOES THIS THE ORDERING WORK? 1. Add items to the cart or update quantity when viewing the cart, continue with "weiter". 2. Enter your address, if your billing address differs, uncheck the "gleiche Rechnungsadresse" and enter the billing address, checked or unchecked, both forms will be sent to the server but handled accordingly, continue with "weiter" 3. Select a payment method, continue with "weiter" 4. formdata object (containing cart items, address(es), payment method) will be sent via AJAX to the server and stored in the server session variable 5.1. if payment method is deferred - AJAX response contains the order summary markup that will render in step4 - don't forget to check " ich habe die Datenschutzerklärung sowie die AGB zur Kenntnis genommen und akzeptiere diese." (privacy policy and terms and conditions) - click on "Zahlungspflichtig bestellen" will send another AJAX request to the server thus submitting the order (continue to WHAT HAPPENS WHEN AN ORDER IS PLACED?) 5.2. if it's paypal, a bit more is happening - server sends a cURL request to paypal containing client ID and secret - response will send a token - server sends that token along with the purchase unit (created from our placed order) in another cURL request to paypal - response will send an "approve"-URL - AJAX response contains that URL - user is redirected to paypal to approve the order - user is redirected to the "checkout" page along with a token and PayerID as GET parameters - token (not needed actually) and PayerID are stored in the server session - with the PayerID in the session variable and the "status" of the paypal approved order in the localstorage the checkout process will head on to step 4: order summary - don't forget to check " ich habe die Datenschutzerklärung sowie die AGB zur Kenntnis genommen und akzeptiere diese." (privacy policy and terms and conditions) - clicking on "Zahlungspflichtig bestellen" will send another AJAX request to the server - second AJAX request will send PayPalAccessToken, PayPalPayerId and PayPalRequestId in another cURL to PayPal which will trigger the payment - response will… continue to WHAT HAPPENS WHEN AN ORDER IS PLACED? WHAT HAPPENS WHEN AN ORDER IS PLACED? an order-page with all the order's details (plus order number from the kiosk's number circle) is created under /admin/page/custom_orders/ (you can find it in the Kiosk Dashboard) number circle is iterated email markup is created using the module's default email template, you can add a path to a custom template in the module's settings email is sent to the site master and the user (check the module's settings for email addresses etc.) order in server session is reset to an empty array paypal session in server session is reset to an empty array localstorage of the browser is deleted user is redirected to a custom url (defined in the module's settings) HOW ARE PRICES HANDLED? prices allow for a stack price functionality. This means that prices and shipping depend on the quantity of items purchased. You can enter different prices and shipping costs for different quantities. If a user's amount of a selected item reaches the specified stack price, the item price and the shipping costs change. HOW ARE PRODUCTS ADDED TO THE CART? a product should be a page object to keep things simple. That page needs an "images" array field (that very name). Below you can see what a product would need. These values are added to the button's data attributes. // This is how you make a product… $product = new WireArray(); $product->id = $page->id; $product->title = $page->title; $product->source = $page->parent->name; $product->url = $page->url; $product->images = $page->images; $product->product_width = 150 // for proportional item image calculation in the cart $product->taxrate = 10 // or what ever the tax rate $product->stack_prices = array( array( "qu" => 1, "sp" => 19.99, "sh" => 5 ), array( "qu" => 10, "sp" => 14.99, "sh" => 0 ), ); $product->stack_prices = htmlspecialchars(json_encode($product->stack_prices)); // then render the "add to cart" button $kiosk->renderBuyButton($product); UPDATE version 1.1: installing kiosk.module will also create a repeater field "kiosk_product_stack_prices" (including 3 subfields as described above) that handles the stack_prices array of arrays (as described above) so you can use the GUI. create a field "kiosk_product_tax_rate" create a field "kiosk_product_width " create a field "images" if there is none in your system. create a template "kiosk_product" with all these mentioned fields use this template for your products (or the fields thereon at least and add to your template of choice) and you should be good to go. CAUTION! If you uninstall kiosk.module it will delete all pages with template "kiosk_product", that's because I'm still figuring out how to detach the fields and fieldgroups without deleting the template. Also, if you're coming from version 1.0 and want to upgrade, please uninstall it in 1.0 first and only then get the new repo (v1.1) to install again. Class kiosk now provides the following hookable methods: ___renderBuyButton(Page $product, (string) 'add to cart') pass a product (preferably with template kiosk_product) and it returns a buybutton with the price for 1 item. This method now accepts the button's label (string) as a second argument. Method is hookable. ___getSpecificStackPrice(Page $product, (int) 5) // 5 is just an example pass a product (preferably with template kiosk_product) and an amount, it returns the price for that amount of items. Method is hookable. ___getSinglePrice(Page $product) pass a product (preferably with template kiosk_product) and it returns the price for 1 item. Method is hookable. So, use template "kiosk_product" for your products, edit the product page to add details, and then do echo $kiosk->renderBuyButton($product, (string) 'add to cart'); to render an "add to cart" button.
  18. Find Merge Adds a Pages::findMerge() method that allows multiple PageFinder selectors to be merged into an efficient paginated set of results. This can be useful when you need more sophisticated sorting of results than what would be possible using only the sort value in a single $pages->find(). Details $results = $pages->findMerge($selectors, $options); $selectors is required and must be an array of selectors. Each selector can be in string format or array format. The findMerge() method will loop over the selectors in the order supplied, adding matching pages to the final results. $options is an optional associative array of options. limit (int) Limit for pagination. start (int) Manually override the start value rather than have it be automatically calculated from the current page number. excludeExisting (bool) Whether or not to exclude pages in each selector that have already been matched by a previous selector. Default is true. keepFirst (bool) When excludeExisting is false then a page might match more than one selector in the supplied array. But each page can only appear once in the results and if keepFirst is true then the page will appear in its earliest position in the results, whereas if keepFirst is false it will appear in its latest position in the results. Default is true. As a shortcut you can supply an integer as the second argument and it will be treated as the limit for pagination. Basic usage For most use cases only a limit will be needed for the $options argument. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $results = $pages->findMerge($selectors, 10); if($results->count) { echo "<p>Showing results {$results->getPaginationString()}</p>"; echo "<ul>"; foreach($results as $result) { echo "<li><a href='$result->url'>$result->title</a></li>"; } echo "</ul>"; echo $results->renderPager(); } Advanced usage The following notes are only relevant to rare cases and most users can safely skip this section. In the demo example the colour page Yellow will potentially match both the 1st selector and the 4th selector. Because of this the excludeExisting and keepFirst options will have an effect on the results. excludeExisting option false Note that the 4th selector asks for 3 colour pages (limit=3). By default excludeExisting is true, which means that when the 4th selector is processed it is interpreted as saying "find 3 colour pages in reverse alphabetical order that have not already been matched in an earlier selector". We can see that there are 3 pages in the results from that selector: Violet, Red, Orange. But if excludeExisting is set to false then the results are different. The matches of the 1st selector (Yellow, Yellow Warbler) are not excluded from consideration by the 4th selector (the 4th selector matches will be Yellow, Violet, Red), and because each page can only appear once in the results this means that the 4th selector ends up only adding 2 more pages to the results. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $options = [ 'limit' => 10, 'excludeExisting' => false, ]; $results = $pages->findMerge($selectors, $options); keepFirst option false As described above, the Yellow page potentially matches both the 1st and 4th selector. By default Yellow will appear in its earliest position within the results, i.e. the position resulting from it being matched by the 1st selector. But if keepFirst is set to false (and excludeExisting is false) then it will appear in its latest position within the results, i.e. the position resulting from it being matched by the 4th selector. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $options = [ 'limit' => 10, 'excludeExisting' => false, 'keepFirst' => false, ]; $results = $pages->findMerge($selectors, $options); keepFirst has no effect when excludeExisting is true. https://github.com/Toutouwai/FindMerge https://processwire.com/modules/find-merge/
  19. This module is an optional (and still somewhat experimental) add-on for SearchEngine. It adds support for indexing file contents, replacing earlier SearchEngine PDF indexer module. Features SearchEngine by itself will only store the name, description, tags, and custom field values for file/image fields. This module, on the other hand, attempts to extract human-readable text from the file itself. As for file types, at least in theory this module supports any filetype that can be reasonably converted to text. It has built-in support (mostly via third party libraries) for... office documents (.doc, .docx, .rtf, .odf), pdf documents (.pdf), spreadsheets (.xls, .xlsx, .ods, .csv) and plain text (.txt). The module also ships with a FileIndexer base class and exposes the SearchEngineFileIndexer::addFileIndexer() method for introducing indexers for file types that are not yet supported. Links GitHub: https://github.com/teppokoivula/SearchEngineFileIndexer Composer: composer require teppokoivula/search-engine-file-indexer Modules directory: https://processwire.com/modules/search-engine-file-indexer/ Getting started install and configure SearchEngine (version 0.34.0 or later), install SearchEngine File Indexer, install third party dependencies — if you installed SearchEngineFileIndexer via Composer you should already have these available, otherwise you'll need to run "composer install" in the SearchEngineFileIndexer module directory, choose which file indexers you'd like to enable. The rest should happen automagically behind the scenes. Additional notes The important thing to note here is that we're going to rely on third party libraries to handle parsing (most) files, and things can still go wrong, so please consider this a beta release. It did work in my early tests, but there's little guarantee that it will work in real life use cases. Just to be safe it is recommended to back up your site before installing and enabling this module. Another thing to keep in mind is that indexing files can be resource intensive and take plenty of time. As such, this module provides some settings for limiting files by size etc. Regardless, this is something that likely needs further consideration in the future; some future version of this module, or an additional add-on module, may e.g. add support for indexing pages/files "lazily" in the background.
  20. Module allow you to load events from event files. Visit Github page or module directory for usage
  21. The Twig renderer for Wireframe has been around a while already, it just didn't have a support forum thread of its own, so here we go. This optional add-on module lets one author layouts, views, partials, and component views using Twig instead of PHP. By design you can have view files that are either Twig or PHP — with this module enabled Wireframe will initially look for a .twig file, but if that doesn't exist, it'll fall back to a regular .php file instead. GitHub repository: https://github.com/wireframe-framework/WireframeRendererTwig Composer installation: composer require wireframe-framework/wireframe-twig-renderer Here's a small sample of what Twig looks like: {% if page.numChildren(true) %} <ul class="menu"> {% for child in page.children %} <li> <a href="{{ child.url }}"> {{ child.title }} </a> </li> {% endfor %} </ul> {% endif %} You can read more about Twig from https://twig.symfony.com/doc/. Twig syntax in specific is covered in Twig for Template Designers. For more details about Wireframe renderers and how they are enabled and used, check out https://wireframe-framework.com/docs/view/renderers/.
  22. Following recent discussion about the Latte templating language, I figured I'd give it a try too and put together a Latte renderer for Wireframe: GitHub repository at https://github.com/wireframe-framework/WireframeRendererLatte Composer installation: composer require wireframe-framework/wireframe-renderer-latte In case anyone wants to try this, it would be interesting to hear your thoughts. I'm honestly not sure if I'll be using it much myself, and I built the module without any real Latte experience under my belt, so it's possible that it does things in surprising ways. Let me know if you run into any issues ? Syntax wise, Latte doesn't differ much from regular PHP templates — you just write your PHP code within {curly brackets}, and it gets automatically escaped (with what they call context-aware escaping). They have this thing called n:attributes though, which is actually quite nice shortcut, especially if you happen to dislike if..else and foreach: <ul n:if="$page->numChildren(true)" class="menu"> <li n:foreach="$page->children as $child"> <a n:tag-if="!$child->hide_from_menu" href="{$child->url}"> {$item->title} </a> </li> </ul> You can read more about Latte from https://latte.nette.org/en/. For more details about Wireframe renderers and how they are enabled and used, check out https://wireframe-framework.com/docs/view/renderers/.
  23. Modules directory: https://processwire.com/modules/page-render-find-replace/ GitHub: https://github.com/teppokoivula/PageRenderFindReplace This module applies replacement patterns defined via TextformatterFindReplace globally to page rendering. All the heavy lifting is done by TextformatterFindReplace (thanks, Ryan!) so this module is just a wrapper around said module plus a bunch of config settings — a few options for selecting matching pages, an option to log replacements as they happen, etc. Long story short, on recent projects I've been running into issues with temporary (development) domain creeping into URLs here and there. While not a major issue, this is annoying and takes some time to correct. Originally I was thinking of building a module that would handle text replacements and log them so that they can be manually fixed later, but TextformatterFindReplace already handles the replacement part quite nicely, so I figured I'd just make use of it, apply replacements to rendered page content instead of individual fields (works better for my use cases, where content is often rather dynamic), and add some logging. Hope someone will find this useful. Please note, though, that this module is not well tested yet so there may be bugs etc. ?
  24. I looked at my HTML output today and all this chaotic whitespace triggered my OCD. This module simply hooks into Page::render and removes whitespaces from frontend HTML with a simple regex replace. I mostly put this together for cosmetics. I like my View source neat and tidy. This is not well tested yet, please open an issue if you run into problems. GitHub: https://github.com/timohausmann/MinifyPageRender
  25. I created a simple translation module for a project we're currently working on and I thought I would share it in case it's useful for anyone else as it's a request we've come across a few times recently. It's a basic page translation module using Google Translate to replace their now retired embeddable page translation widget. The module outputs a simple, un-styled, dropdown language selector that routes the visitor to a translated version of the current page via translate.google.com. From there you can then navigate the whole site in the your language of choice. There's also a method to output a single language-specific translation URL for any supported language using the language ISO code. Download, usage and supported language list available on my Github here: https://github.com/mrjcgoodwin/MarkupGoogleTranslate Caveat 1: Google seem to be trying to encourage use of their Google Translation API, so the continued working of this module is completely at their mercy - I can imagine they may discourage this usage at some point, but who knows! Caveat 2: I haven't yet deciphered what all the parameters are used for in the constructed Google Translate URL. It's possible there may be some sites/scenarios where the URL doesn't work. Feel free to report if you find any issues.
×
×
  • Create New...