Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/13/2019 in all areas

  1. Hey folks! Took a couple of late nights, but managed to turn this old gist of mine into a proper module. The name is SearchEngine, and currently it provides support for indexing page contents (into a hidden textarea field created automatically), and also includes a helper feature ("Finder") for querying said contents. No fancy features like stemming here yet, but something along those lines might be added later if it seems useful (and if I find a decent implementation to integrate). Though the API and selector engine make it really easy to create site search pages, I pretty much always end up duplicating the same features from site to site. Also – since it takes a bit of extra time – it's tempting to skip over some accessibility related things, and leave features like text highlighting out. Overall I think it makes sense to bundle all that into a module, which can then be reused over and over again ? Note: markup generation is not yet built into the module, which is why the examples below use PageArray::render() method to produce a simple list of results. This will be added later on, as a part of the same module or a separate Markup module. There's also no fancy JS API or anything like that (yet). This is an early release, so be kind – I got the find feature working last night (or perhaps this morning), and some final tweaks and updates were made just an hour ago ? GitHub repository: https://github.com/teppokoivula/SearchEngine Modules directory: https://modules.processwire.com/modules/search-engine/ Demo: https://wireframe-framework.com/search/ Usage Install SearchEngine module. Note: the module will automatically create an index field install time, so be sure to define a custom field (via site config) before installation if you don't want it to be called "search_index". You can change the field name later as well, but you'll have to update the "index_field" option in site config or module settings (in Admin) after renaming it. Add the site search index field to templates you want to make searchable. Use selectors to query values in site search index. Note: you can use any operator for your selectors, you will likely find the '=' and '%=' operators most useful here. You can read more about selector operators from ProcessWire's documentation. Options By default the module will create a search index field called 'search_index' and store values from Page fields title, headline, summary, and body to said index field when a page is saved. You can modify this behaviour (field name and/or indexed page fields) either via the Module config screen in the PocessWire Admin, or by defining $config->SearchEngine array in your site config file or other applicable location: $config->SearchEngine = [ 'index_field' => 'search_index', 'indexed_fields' => [ 'title', 'headline', 'summary', 'body', ], 'prefixes' => [ 'link' => 'link:', ], 'find_args' => [ 'limit' => 25, 'sort' => 'sort', 'operator' => '%=', 'query_param' => null, 'selector_extra' => '', ], ]; You can access the search index field just like any other ProcessWire field with selectors: if ($q = $sanitizer->selectorValue($input->get->q)) { $results = $pages->find('search_index%=' . $query_string . ', limit=25'); echo $results->render(); echo $results->renderPager(); } Alternatively you can delegate the find operation to the SearchEngine module: $query = $modules->get('SearchEngine')->find($input->get->q); echo $query->resultsString; // alias for $query->results->render() echo $query->pager; // alias for $query->results->renderPager() Requirements ProcessWire >= 3.0.112 PHP >= 7.1.0 Note: later versions of the module may require Composer, or alternatively some additional features may require installing via Composer. This is still under consideration – so far there's nothing here that would really depend on it, but advanced features like stemming most likely would. Installing It's the usual thing: download or clone the SearchEngine directory into your /site/modules/ directory and install via Admin. Alternatively you can install SearchEngine with Composer by executing composer require teppokoivula/search-engine in your site directory.
    11 points
  2. I've been in Minnesota all week for a family reunion and only a few minutes at the computer every day, so I don't have a core update or anything worthwhile to write about this week. But now I'm headed back home so will be back to a regular schedule next week. Hope that you have a great weekend!
    8 points
  3. When your blog content is growing to some thousands of pages and you have comments scattered here and there, sometimes you start wondering if placing comments below each post is the best approach. Of course this totally depends on your project and contents. In my case I came to the conclusion I could provide a better user experience switching to a Forum-like solution, where discussions were organized by macro subjects and not below each individual post. Of course there are many products and services providing fully featured forum solutions, but getting only few comments per day I was reluctant to setup a dedicated forum and to deal with users' profiles. A nice thing of the comments system is that users do not need to create account and password, but simply use their email address. And here we are ... why not to setup a very basic Forum-like solution using PW Comments? But please do not get too excited… we will just use comments in a way that looks-like-a-forum. I think this solution makes sense if you have a limited number of comments per day spread on some topics. If you need to deal with high discussions traffic with several users ... do it with a fully featured forum solution !! To implement this Forum-like solution we will take benefits of (1) PW pages/templates flexibility (why you should be here otherwise…), (2) core module FieldtypeComments, (3) Uikit 3 Site/Blog Profile, (4) some of the tutorials I recently released about PW Comments (listed at the end). OK, let's start. Login into the Admin panel, select Setup, and then Fields. Let's create a checkbox field named "sticky" that we can use to keep some forum subjects on top of the communities. Now let's move to Setup, Template. We will create a new template with name "communities'. In addition to "title" field, we will add also "body" and "sidebarRight" fields (already available in the profile): Then we create a template, that we will use for individual communities, with name "community". In addition to "title" field, we will add "date", "body", "images", "comments" fields (already available in the profile) and the "sticky" field we have just created. If you wish, as I did, you can also associate some category fields. If you use Multi-Language is a good idea to use the field "date", as ,differently from createdStr, it will automatically return a locale-formatted date as you defined in the field. Now that we have created the templates, we need to customize them. Reopen the "communities" template. In the Family tab: allow the template to have children, allow only one page with this template, select "community" as only allowed template for CHILDREN. Then in the URLs tab: select allow page numbers. This will return a paginated list of communities. We reopen the "community" template. In the Family tab: do not allow the template to have children, allow to create new pages, select "communities" as only allowed template for PARENT. Now in the URLs tab: select allow page numbers. This will be necessary to create paginated comments. Let's go to the page-tree, under Home we will create a new page named "Community" using the templates "communities" (note the final s), this will be the page listing all the communities. Under the Community page, we will create the individual communities. Give the pages the name you wish and use the template "community" (note w/o the final s). It may be good creating one with the name "New Forum Requests" checking its "sticky" field so that it remains on top. As to implement this Forum-like solution, the comments pagination is a must, at this stage you will have to implement it as described in this tutorial: Now we are ready for coding (very little!) the php templates. We need to associate php files to the two templates we have created. In site/templates create two new php files communities.php and community.php. Open the template blog.php and copy its content to communities.php, then repeat the same operation copying the content of template blog-post.php to community.php. Great! We are few steps away from our Forum-like solution. Modify communities.php as follows: ... echo ukHeading1(page()->title, 'divider'); echo page()->body . '<br><hr>'; //>>>>> ADD THIS LINE //$posts = page()->children('limit=10'); //echo ukBlogPosts($posts); $posts = page()->children('sort=-sticky, sort=title, limit=10'); //>>>>> ADD THIS LINE echo ukBlogPosts($posts, ['moreText' => '', 'moreIcon' => '']); //>>>>> ADD THIS LINE ... Then modify community.php as follows: // blog post content echo ukBlogPost(page()); // comments if($page->hasField('comments')) { //>>>>> ADD THIS LINE $comments = page()->comments; // comment list if(count($comments)) { //echo ukHeading3("Comments", "icon=comments"); echo ukComments($comments->find("sort=-created"), ['paginate' => true]); //>>>>> ADD THIS LINE - READ PAGINATION TUTORIAL (NEEDED) echo '<hr>'; } // comment form $gdpr = __('I agree with the processing of my personal data. I have read and accept the Privacy Policy.'); //>>>>> ADD THIS LINE - READ GDPR TUTORIAL (OPTIONAL) echo ukHeading3(__('Join the discussion'), "icon=comment"); echo ukCommentForm($comments, ['labels' => ['gdpr' => $gdpr]]); //>>>>> ADD THIS LINE - READ GDPR TUTORIAL (OPTIONAL) } //>>>>> ADD THIS LINE Very good (hope so...). Now let's see the result. When browsing to the Community page we will get the list of the communities. In my example I decided to keep sticky the one where users can submit suggestions for new forum subjects. Selecting one of the communities we have created, we are going to see (1) a description of the community, (2) a paginated list of comments, (3) and the comment form at the bottom. Please note that in this picture pagination is kept with a limit of three items just to fit the image … It makes sense to have 10-15-20 comments per page depending on your preferences. And we are done, here it is. If you wish you can implement some additional features as described in the tutorials below. Not mandatory but probably makes good sense to enable the honeypot field as described in this tutorial as anti-spam measure: If you have the "pleasure" to deal with GDPR matters, here is described how to add a privacy checkbox to your comment form: and finally if you wish your Forum-like solution to be Multi-Language here it is what to do: I hope you enjoyed and wish you a nice week-end ! PS: it's a couple of tutorials I miss the emoj … hope they will come back in this forum soon !!
    6 points
  4. Dashboard Tasks MD COLLABS, MaxDev Collaboration & Sharing Tool is a simple management task module; a plugin runs on Processwire CMF Framework. Available here at https://github.com/sjahrazad/DashboardTasks This module allows you to track interactions in your team through your Email application; furthermore, you can collaborate and share your task instantly from the web site. This module modified from Kongondo Dashboard Notes at https://processwire.com/talk/topic/20980-dashboard-notes/ Install 1. Place the module files in /site/modules/DashboardTasks/ 2. In your admin, click Modules > Check for new modules 3. There are two modules, the main module is DashboardTasks, and the other one DashboardDocs is an optional module in case you want the users to attach files to their task. 4. Install DashboardDocs to use both modules, or install DashboardTasks only without the document attachment. User Roles There are three roles for this module, task-user (co-worker), task-owner (task creator) and task-manager. Demo Users The installer created five demo users, task-manager, task-owner and three task-coworkers. For the first time log-in user, before using the module, a task manager role required to configure the Global Settings. user name: task-manager, password: task-manager, email: task-manager@yourdomainname user name: task-owner password: task-owner, email: task-owner@yourdomainname user name: task-coworker1 password: task-coworker1, email: task-coworker1@yourdomainname user name: task-coworker2 password: task-coworker2, email: task-coworker2@yourdomainname user name: task-coworker3 password: task-coworker3, email: task-coworker3@yourdomainname Change those emails with your test emails. Task Types There are three types available for the new task creation. First, is the Notes type. Use this type if you want to share your notes or collaborate the ideas to your members. The second type is the core of this module, a Task Scheduler type with start date and due date of the task. If you click the Required Job Acceptance from your task settings, then this task type will become an enquiry or job offer task type. The third type is the Reports or Private Notes type. Use this type for your private record or might be you share it to the selected members in your team. Usage Scenario You can use this module for numerous tasks management purposes, from just a shared idea up to enquiry request type. Email or SMS is the primary interface for the user in this module. The user can decide either respond to that email request and log in to the system or just read it in their mailbox. If there is no action required from the recipient, then it is not compulsory to log in to the system as well. Responses to the submitted task also will be sent out to the task creator email as well. For example, your company use a Call Centre service to capture your customer's enquiries, where the messages will be sent out to your contractors or service providers. In this case, your role here is the Task Manager, the call centre agent's role become the Task Owner, someone who created the task and your contractors or service providers are the Task Users. Once a contractor received the request and accepted the enquiry's offer, this contractor assigned as the job provider for that task. The other scenario usage, for example, you're a property manager who will process your tenant request for fault enquiry to your tradesperson group. Or, a lecturer who wants to arrange a research group with some students.. the list goes on ... CSS CSS Grid doesn't work in some old browsers. You need to adjust the CSS under Less folder if you want to use this module for old browsers. <details> tag is not working in IE or Edge browser. SMS If you want the output sent to SMS and Email, you have to add your SMS Provider API to the ProcessDashboardTasks.module. And add your mobile users' array to the SaveTask and SaveTaskReply function.
    4 points
  5. While working on optimizing Comments field for my blog, I noticed it could have been useful to have a GDPR checkbox in the form, to get privacy acceptance before a comment is submitted. At the beginning I though to inject the checkbox processing the rendered comment form, but as I already modified FieldtypeComments to create a Language field, I decided to continue on that road to add the GDPR checkbox. We will not modify the original FieldtypeComments in wire/modules/Fieldtype/FieldtypeComments, but copy it to site/modules/FieldtypeComments. Please refer to the initial part of this tutorial for the detailed steps to duplicate the module and make PW aware of which module version to use. Now that FieldtypeComments is duplicated, we can proceed with the necessary modifications. Inside the module there are 14 files, but do not worry ... only ContactForm.php and (optionally) comments.css will have to be modified. First we will modify the $options class property of ContactForm.php to add a new 'gdpr' label. Later we will use this option to pass the label's text associated with the checkbox. protected $options = array( … 'labels' => array( 'cite' => '', // Your Name 'email' => '', // Your E-Mail 'website' => '',// Website 'stars' => '', // Your Rating 'text' => '', // Comments 'submit' => '', // Submit 'starsRequired' => '', // Please select a star rating 'gdpr' => '', // >>>>> ADD THIS LINE ), As a second step it will be necessary to create the markup of the checkbox and of its label. We will do that by modifying function renderFormNormal() in ContactForm.php. Uikit 3 Site/Blog Profile is indirectly calling this function, so for my purpose it was enough. In case your application is using threaded comments, it will be necessary to modify also renderFormThread(). "\n\t\t<textarea name='text' class='required' required='required' id='{$id}_text' rows='$attrs[rows]' cols='$attrs[cols]'>$inputValues[text]</textarea>" . ... "\n\t</p>" . "\n\t<p class='CommentFormGdpr {$id}_gdpr'>" . //>>>>> ADD THIS BLOCK - START "\n\t\t<input class='uk-checkbox' type='checkbox' name='gdpr' value='checked' required='required'>" . "\n\t\t<label for='{$id}_gdpr'>$labels[gdpr]</label>" . "\n\t</p>" . //>>>>> ADD THIS BLOCK - END $this->renderNotifyOptions() . ... The last ContactForm.php modification will include our checkbox in processInput() to block comments submissions if GDPR checkbox is not filled. Please note this will operate in case you do not place "required" in the <input> directive. ... $errors = array(); foreach(array('cite', 'email', 'website', 'stars', 'text', 'gdpr') as $key) { //>>>>> ADD 'gdpr' in the array ... Now let's see how to call the modified form. If you are using Uikit 3 Site/Blog Profile you will have simply to modify the template file where ukCommentForm() is called (example: blog-post.php template). There we will prepare our checkbox message and pass it to ukCommentForm() as an argument option. echo ukHeading3(__('Join the discussion'), "icon=comment"); $gdpr = __('I agree with the processing of my personal data. I have read and accept the Privacy Policy.'); echo ukCommentForm($comments, ['labels' => ['gdpr' => $gdpr]]); However, if you are using comments in multiple template files, it makes more sense to directly modify ukCommentForm() presetting the new options inside the function body: $defaults = array( 'headline' => '', 'successMessage' => __('Thank you, your comment has been posted.'), 'pendingMessage' => __('Your comment has been submitted and will appear once approved by the moderator.'), 'errorMessage' => __('Your comment was not saved due to one or more errors.') . ' ' . __('Please check that you have completed all fields before submitting again.'), // >>>>> SEE THE HONEYPOT TUTORIAL 'requireHoneypotField' => 'email2', //>>>> ADD THESE FOUR LINES 'labels' => array( 'gdpr' => __('I agree with the processing of my personal data. I have read and accept the Privacy Policy.'), ), ); Before testing, we will modify the file comments.css adding these two directives (that's purely optional): .CommentFormGdpr input[type=checkbox] { background-color: white; } .CommentFormGdpr label { padding-left: 10px } Now let's test our form. Once it is filled with our data and comment it will look like this: If the user is pressing the submit button without accepting the GDPR checkbox, the comment will not be submitted and an error is displayed (in case you have used "required" in <input> you get this tooltip box, otherwise you will get an alert message): Now we accept the box After acceptance and submission, the comment form will be successfully sent. The standard success message is shown and the form is again displayed empty (with just cite and email pre-filled) ready for a next comment submission. Again I hope you will find some useful hint with that.
    4 points
  6. Was afraid someone would ask that ? No, not really a good example. I've been testing the module at wireframe-framework.com and just now added a couple of lines of code to get a very crude results list up: https://wireframe-framework.com/?q=composer. The thing is that I don't have a clean implementation for a results list (or a search form etc.) built into the module yet – that's something I'm going to add next. I've got some sites on the way that all need this feature ?
    2 points
  7. Thx, that was one part of the problem, but the actual problem was that I had the setLabel() method called in the render() method of the inputfield and that obviously didn't work on ajax fields. It worked in my ProcessModule because the label there was set manually (and it worked in your example because you also set a label in the field settings, thx for the video!). The latest version now fixes all those problems and I think this version is already quite useful. Next week I'll continue my work on RockTabulator which will be based on RockMarkup and if that all works well and does not need any further changes I'll officially release RockMarkup. Have a great weekend everybody ? Edit: This is a perfect example why I started building this module: In theory it's always easy to create custom markup anywhere in the admin by using hooks or creating little custom modules. But after time you change things, move fields or set them to AJAX and things break... The goal of this new module is that you don't have to take care about all that. Just paste some code and get reliable results ?
    2 points
  8. Yeah, I am eager to use ProCache. After having built some fairly complex caching functionality with Nginx/Openresty/Lua for a high traffic, public facing site, it would be nice just to let the framework take care of most of the heavy lifting. Most of my work now is for internal CRUD and content management, but as soon as we get an opportunity to build something public facing with PW, we'll whip out the credit card ?
    2 points
  9. Now I haven't done any development for a number of months now, just kinda lost the mojo. Maybe it'll return, maybe not, but I still like to check out the forum once in awhile. I used repeater matrix a lot on one site. I think it's not only useful, but essential. If you have a page that has a lot of content in the form of title > paragraph > image > paragraph > quote > image > paragraph etc... good luck with doing that in either a huge single text field or multiple fields all cobbled together in a specific order that's awkward to change. I can't say I used the other included goodies as much, but repeater is worth its weight in gold, plus buying it supports an amazing project.
    2 points
  10. I just want to share my findings from today when I wanted to create one million pages quickly: First, via Tracy Console: ini_set('max_execution_time', 150); $last = $pages->findOne("parent=/data,include=all,sort=-id"); $last = (int)$last->title ?: 0; for($i=$last+1;$i<$last+1000;$i++) { // create page $p = new Page(); $p->template = 'basic-page'; $p->parent = '/data'; $p->title = $i; $p->save(); l("saved page $i"); $pages->uncacheAll(); gc_collect_cycles(); } d('done'); It started at 23 pages per second: And at the end of the 150 seconds it was already down at 4 pages per second: Testing without logging: Memory usage also increased proportionally. Finally running a PHP script from the command line that bootstrapped PW worked well: <?php namespace ProcessWire; $time_pre = microtime(true); include("../../../index.php"); // bootstrap ProcessWire $last = $pages->findOne("parent=/data,sort=-id"); $i = (int)(string)$last->title ?: 0; // multilang quickfix convert to string // foreach($pages->find('parent=/data') as $p) { // $p->delete(); // echo "deleted $p\n"; // } // return; $i++; $num = 0; while($i <= 1000000) { // create page $p = new Page(); $p->template = 'basic-page'; $p->parent = '/data'; $p->title = $i; $p->save(); $pages->uncacheAll(); gc_collect_cycles(); $num++; echo "done: $num ($i)\n"; $i++; } function convert($size) { $unit=array('b','kb','mb','gb','tb','pb'); return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i]; } $time_post = microtime(true); $t = $time_post - $time_pre; $m = memory_get_usage(); echo "created $num pages in " . round($t, 3) . "s, " . round($t/$num, 3) . "s per page, used " . convert($m) . " memory\n"; Benefits: quick runs in the background and does not lock the site direct feedback via echo without creating huge log files cancel via ctrl+c any time easy persistant saving of your scripts
    2 points
  11. Finally deleted all those pages using transactions: <?php namespace ProcessWire; include "index.php"; $dePages = wire('pages')->find("parent=/einstellungen/berufi/"); echo $dePages->count()."\n"; $i=0; try { $database->beginTransaction(); foreach ($dePages as $dePage){ echo $i++. " ".$dePage['title']."\n"; $dePage->delete(); } $database->commit(); } catch(\Exception $e) { $database->rollBack(); } Script took 7 Minutes to run , the actual query execution took about 7-10 seconds at the end of the script. I guess Transactions are helpfull at deleting pages too . What i did not try was to trash them first.
    2 points
  12. A module helping you to manage SEO related tasks like a boss! Automatically generates and maintains a XML sitemap from your pages. Includes a Fieldtype and Inputfield to manage sitemap settings and meta data for pages (Title, Description, Canonical URL, Opengraph, Twitter, Structured Data etc.) Multi language support for the sitemap and meta data. Configure default values for meta data on template level and let pages inherit or overwrite them individually. Map existing fields to meta data, reducing the need to duplicate content. Live preview for content editors how the entered meta data appears on Google. Live preview for content editors how the entered Opengraph data looks like when sharing a page with Facebook. Check out the README on GitHub for more details, including usage instructions. The module is currently released as beta and needs testing! Please report any issues on GitHub or in this forum thread, if you find time to give it a try ? Examples Here is an example of rendered meta data you will get from a single SeoMaestro field: <title>Sed dictum eros quis massa semper rutrum. | acme.com</title> <meta name="description" content="Si lobortis singularis genitus ibidem saluto. Dolore ad nunc, mos accumsan paratus duis suscipit luptatum facilisis macto uxor iaceo quadrum. Demoveo, appellatio elit neque ad commodo ea. Wisi, iaceo, tincidunt at commoveo rusticus et, ludus."> <meta name="keywords" content="Foo,Bar"> <link rel="canonical" href="https://acme.com/en/about/"> <meta property="og:title" content="Sed dictum eros quis massa semper rutrum."> <meta property="og:description" content="Si lobortis singularis genitus ibidem saluto. Dolore ad nunc, mos accumsan paratus duis suscipit luptatum facilisis macto uxor iaceo quadrum. Demoveo, appellatio elit neque ad commodo ea. Wisi, iaceo, tincidunt at commoveo rusticus et, ludus."> <meta property="og:image" content="https://acme.com/site/assets/files/1001/og-image.jpg"> <meta property="og:image:type" content="image/jpg"> <meta property="og:image:width" content="1600"> <meta property="og:image:height" content="1200"> <meta property="og:image:alt" content="Lorem Ipsum"> <meta property="og:type" content="website"> <meta property="og:url" content="https://acme.com/en/about/"> <meta property="og:locale" content="en_EN"> <meta name="twitter:card" content="summary"> <meta name="twitter:creator" content="@schtifu"> <meta name="twitter:site" content="@schtifu"> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "About", "item": "https://acme.com/en/about/" } ] } </script> <meta name="generator" content="ProcessWire"> <link rel="alternate" href="https://acme.com/en/about/" hreflang="en"> <link rel="alternate" href="https://acme.com/en/about/" hreflang="x-default"> <link rel="alternate" href="https://acme.com/de/ueber/" hreflang="de"> <link rel="alternate" href="https://acme.com/fi/tietoja/" hreflang="fi"> And some screenshots of the UI:
    1 point
  13. Hey folks! I'm happy to finally introduce a project I've been working on for quite a while now: it's called Wireframe, and it is an output framework for ProcessWire. Note that I'm posting this in the module development area, maily because this project is still in rather early stage. I've built a couple of sites with it myself, and parts of the codebase have been powering some pretty big and complex sites for many years now, but this should still be considered a soft launch ? -- Long story short, Wireframe is a module that provides the "backbone" for building sites (and apps) with ProcessWire using an MVC (or perhaps MVVM... one of those three or four letter acronyms anyway) inspired methodology. You could say that it's an output strategy, but I prefer the term "output framework", since in my mind the word "strategy" means something less tangible. A way of doing things, rather than a tool that actually does things. Wireframe (the module) provides a basic implementation for some familiar MVC concepts, such as Controllers and a View layer – the latter of which consists of layouts, partials, and template-specific views. There's no "model" layer, since in this context ProcessWire is the model. As a module Wireframe is actually quite simple – not even nearly the biggest one I've built – but there's still quite a bit of stuff to "get", so I've put together a demo & documentation site for it at https://wireframe-framework.com/. In addition to the core module, I'm also working on a couple of site profiles based on it. My current idea is actually to keep the module very light-weight, and implement most of the "opinionated" stuff in site profiles and/or companion modules. For an example MarkupMenu (which I released a while ago) was developed as one of those "companion modules" when I needed a menu module to use on the site profiles. Currently there are two public site profiles based on Wireframe: site-wireframe-docs is the demo&docs site mentioned above, just with placeholder content replaced with placeholder content. It's not a particularly complex site, but I believe it's still a pretty nice way to dig into the Wireframe module. site-wireframe-boilerplate is a boilerplate (or starter) site profile based on the docs site. This is still very much a work in progress, but essentially I'm trying to build a flexible yet full-featured starter profile you can just grab and start building upon. There will be a proper build process for resources, it will include most of the basic features one tends to need from site to site, etc. -- Requirements and getting started: Wireframe can be installed just like any ProcessWire module. Just clone or download it to your site/modules/ directory and install. It doesn't, though, do a whole lot of stuff on itself – please check out the documentation site for a step-by-step guide on setting up the directory structure, adding the "bootstrap file", etc. You may find it easier to install one of the site profiles mentioned above, but note that this process involves the use of Composer. In the case of the site profiles you can install ProcessWire as usual and download or clone the site profile directory into your setup, but after that you should run "composer install" to get all the dependencies – including the Wireframe module – in place. Hard requirements for Wireframe are ProcessWire 3.0.112 and PHP 7.1+. The codebase is authored with current PHP versions in mind, and while running it on 7.0 may be possible, anything below that definitely won't work. A feature I added just today to the Wireframe module is that in case ProcessWire has write access to your site/templates/ directory, you can use the module settings screen to create the expected directories automatically. Currently that's all, and the module won't – for an example – create Controllers or layouts for you, so you should check out the site profiles for examples on these. (I'm probably going to include some additional helper features in the near future.) -- This project is loosely based on an earlier project called pw-mvc, i.e. the main concepts (such as Controllers and the View layer) are very similar. That being said, Wireframe is a major upgrade in terms of both functionality and architecture: namespaces and autoloader support are now baked in, the codebase requires PHP 7, Controllers are classes extending \Wireframe\Controller (instead of regular "flat" PHP files), implementation based on a module instead of a collection of drop-in files, etc. While Wireframe is indeed still in a relatively early stage (0.3.0 was launched today, in case version numbers matter) for the most part I'm happy with the way it works, and likely won't change it too drastically anytime soon – so feel free to give it a try, and if you do, please let me know how it went. I will continue building upon this project, and I am also constantly working on various side projects, such as the site profiles and a few unannounced helper modules. I should probably add that while Wireframe is not hard to use, it is more geared towards those interested in "software development" type methodology. With future updates to the module, the site profiles, and the docs I hope to lower the learning curve, but certain level of "developer focus" will remain. Although of course the optimal outcome would be if I could use this project to lure more folks towards that end of the spectrum... ? -- Please let me know what you think – and thanks in advance!
    1 point
  14. You're on a roll! Thanks for all these tutorials, and a very good weekend to you, too! ???
    1 point
  15. Thanks a lot to Kongondo and Szabesz for this module. I have a small project on a university website, where they required quite simple task management for their internal research team. They want all actions triggered through emails and SMS because it is not easy to expect the team always log in to their website. I did a quick development based on this module and will share and post it in a new thread.
    1 point
  16. Nice enhancement to the file filtering in the File Editor panel thanks to @tpr that lets you arrow key up and down through results and Enter to open.
    1 point
  17. I'm close to releasing my new module called RockMarkup which will be similar to @kongondo's and @kixe's markup modules. The module is already on github and ready to play with: https://github.com/BernhardBaumrock/RockMarkup Unfortunately I have a bug that I can't seem to find. When a field is placed in a template and visibility is set to "closed + AJAX load" the field does not work at all: Would be great to get some help with this one! URL for installation of the module: https://github.com/BernhardBaumrock/RockMarkup/archive/master.zip
    1 point
  18. Absolutely true! Thx for sharing! ? Are there any live examples of you module?
    1 point
  19. Yeah, coming from several applications written from scratch, with codeigniter, and to a lesser extent, wordpress, workflow with Processwire has been tough for me personally, but I am adapting. I've sort of settled into a pattern where after having deployed the initial production application, I try to do as much non-destructive work as possible on this instance. If something may be destructive, then I'll clone the codebase and hit the same database and work on this. If and when everything looks good, I'll just point the DNS to this instance. You can read up on multi-instancing. The reason for the above approach is because with the app I'm working on, the DB is too big to be slinging back and forth to a development machine. Having said all this, while I'm working on production and staging instances, I've also got a half dozen R&D instances on my dev machine than are pretty darn close in structure to production. This all probably sounds nebulous and I hope it helps. And I would certainly keep search-engine'ing things like "processwire development staging production"
    1 point
  20. Check this: https://mediamanager.kongondo.com/
    1 point
  21. Just adding my 2 cents as an encouragement for anyone considering buying pro modules. I am NOT a developer, but have very gladly worked with developers from this wonderful forum. I have bought 5 pro modules so far, also ones I do not use on any of my sites. All of my sites use procache, form builder and repeater matrix. Anybody out there who does not use procache, you are leaving money on the table by not speeding up your site. I try to make a living from my sites, and mostly succeed, and increased speed of my sites so far always translated to more sales, so procache is a must in my book. I bought promailer but do not use it, also prodevtools which I don't even understand what it does, but if Ryan makes it, and I can even slightly understand what it does, I'll just buy as my means of showing appreciation for this incredible piece of art we call processwire, which makes me money every day. I also bought padloper which I do not use, but I bought because I like the idea of a good shopping cart being developed for PW. Sorry for the rant, but I love this thing called Processwire!
    1 point
  22. Just submitted a pull-request. I figured out that if the output is wrapped into a div it‘s getting loaded properly. Please don‘t ask why ? /edit: Thanks for sharing your module!
    1 point
  23. Hi @neonwired, guest and superuser are default roles. Documentation says: "The guest role is automatically given to all anonymous site users. You should not give this role any access other than page-view permission." You can find further details here. If you wish to assign specific permissions you can easily create custom roles. Just as an example for a blog website, you may create visitor, author, editor roles and assign them their specific permissions.
    1 point
  24. Did you notice that one of those modules is not officially stated as compatible with PW3? You should always post module-specific questions in their dedicated support forums, instead of creating a new thread (the blue button on the official module page at the left) At quick glance, I noticed you are not supplying the page field for your Photoswipe gallery. It should be: echo $pwpswp->renderGallery($page->nicePictures); // or whatever you've called your images-field... I have never used any of those two modules. But a potential "gotcha" with outputting files in a template is if you're allowing just one single file or multiple. If you expect an array of items, use $page->fieldName->first()->url (in case of the video file). Depending on your field-settings, you can use one method or another, i.e. if it's set to 1 file only, you can use $page->fieldName->url etc. Do you get errors? If you're in debug mode, you should see errors appearing. Also look at the browser console for JS errors. Finally, if you use Tracy Debugger, you should get hints and more extensive debugging infos.
    1 point
  25. Just be aware that if you have Tracy calls inside your script (d(), etc), these also contribute to the total memory usage :-). In my test cases (some unrelated work), the amount used by Tracy can be significant.
    1 point
  26. Just wanted to share the simplest language switcher possible if you only have two languages: <a href="<?= $page->localUrl($languages->findOther()->first()) ?>">DE/EN</a> ??
    1 point
×
×
  • Create New...