Leaderboard
Popular Content
Showing content with the highest reputation on 09/26/2017 in all areas
-
If a client is dead-set on WordPress, it's worth communicating to them that every developer has their own go-to approach with the system, to the point where I would say it's not even "WordPress" anymore. So even if another developer were to take over it, it's still foreign territory to an extent, followed up with continuously saying "why the hell did the previous developer do things in X way instead of Y?" and a lack of productivity. Just check out all the starter themes, mega themes (ugh... ... ... ugh), and different approaches to custom fields. It's pretty terrible. For me, ProcessWire + UIkit solves like 95% of my challenges, and solves them WELL.6 points
-
@alxndre You may install the following testmodule and then go to admin > setup > logs > AutoLoadTest and watch the log growing4 points
-
4 points
-
possibly, read on... If you are comparing 'the' UI side by side, the problem is that there is no 'the' ui, because the page tree is the default UI, however when i build a site, my clients log into an admin that shows a dashboard (like wordpress), with lots of shortcuts to common areas, as well as content creation (like 'New Blog Post'). Some of these clients have never seen the page tree. ListerPro is a little bit like the wordpress listing of pages (albeit without hierarchical indents), but 'on steroids' – instantly filter to any page by title, use the filters or lister actions, edit inline, and ... bob's your uncle.4 points
-
don't forget to sell yourself (and not the system that you are using) find out what your client is looking for and then tell them what you can offer. if they are looking for a quick & cheap wordpress website (they can have good reasons for that), maybe you are not the right person for the job... (and maybe its also better for you to create one great PW site with a great client than 2 cheap websites with 2 not-so-great clients) think of the following 2 approaches and how the client may feel or what the client may hear: or this one: how would you feel? what would you think? maybe in situation one you would feel bad and confused because there is somebody telling you that something that most of the others are using is a bad choice? in situation two you can see instantly how the client reacts: does he want that quick&dirty way? does he want to be like everybody else? same situation but maybe totally different feelings for your client if he asks you for your reasons you know that he is interested (or at least curious). he knows that you are not the quick&dirty guy and he should not feel offended or over-instructed (telling him if he decides like 80% of all others he will regret - actually, when i read that, that sounds really strange and i totally understand my clients ). thanks for all the other input. i'll try to remember some points for future talks. especially yours @Jonathan Lahijani @DaveP thanks for that example. totally valid points too. especially for us as developers. but think of that in context of my first quote. that may create the total opposite message in your clients head: ah, this guy is a nerd. he speaks a language i don't understand and talks about things most other website owners obviously don't care about...3 points
-
One fun way of demonstrating a real difference between PW and WP is to run the average WP site (preferably one chosen by the (prospective) client) and an equivalent PW site (probably from the showcase) through a tool like YSlow. WP sites often have all these plugins, often including multiple different versions of jQuery etc etc. I just tried it on a WP site I know of and got this Yep, 28 external javascript files and 23 external stylesheets. That's, what, 40-odd unnecessary requests? Doing the same thing on a similar looking site from the showcase wasn't perfect - 6 js and 3 CSS (AIOM, anyone?), but it's actually a really obvious way of explaining even to a layperson that one way is very obviously better than the other - file conflicts, bandwidth, load time etc.3 points
-
Use Page Reference & Repeater fields. Seriously. They're immensely powerful if you know how to utilize them. There's a blog post that explains how you might use Page Reference fields for toggling states and attributes, but you can also use them for ordering things, as it saves the order of the pages you referenced too. What you should do: Create 3 dummy templates, "home-block", "container", and "block-type". You can use tags in Advanced tab and put "-home" to hide them away. Create the following pages /processwire (your admin root page) +---tools/ (template: container) (hide this page) +-home-blocks/ (template: container) | + hero (template: home-block) | + what-we-do | + our-work | + testimonials | ... other blocks | +-block-types/ (template: container) + full-width (template: block-type) + half ... other types Create a Page reference field, set its inputfield to select, limit to single item and only pages with "home-block" template under /tools/home-blocks Create another page field, this time set its inputfield to Checkboxes and limit it to "block-types" under /home/block-types Create a repeater homeLayout and add these two page fields to it Add the repeater field to home template. Add any block you want using the repeater in any order and add any property you want to any container. Using this blog post as your guide, loop over the repeater items and find which block has been selected, render your block (you can put your block codes under templates/block and render them individually with $files->render()) with the options in the order your client/you selected3 points
-
Be warned, this is a bit of a ramble but interested to hear other points of view. It's not a 'I hate wordpress' post at all, we all know each project needs tools, and they are chosen depending on the project. https://www.cmscritic.com/processwire-vs-wordpress/ So, I've as looking at this old post yesterday and see a few of the regulars here getting involved I installed wordpress yesterday and have spent the best part of this morning getting to grips with some basic stuff. Anyway, I'm thumbing through the twentyseventeen theme and I can't help but be extremely confused by the whole thing. My mind is blown how overly complex it seems to display what is a big header image, with some posts under it and a sidebar. There's a 567 line functions file that does something or other. Is it a case of the theme has to support a zillion different things a user "might" do, when the processwire approach is to theme the site with exactly the requirements of a given project? Of course I don't have a lot of experience with custom themes in wordpress but I'm thinking it would take a good year or so (at least for me) to get proficient at this. Why am I doing this? Purely because (a) it's so popular and I can't avoid the possible work opportunities and (b) I have doubts that convincing people to use processwire is going to work. Mainly because I can't answer the question "who will take care of my site when you're gone". This is a legit question for a business owner and I feel this is also a big problem for a system that has a far lower userbase and (c) I'm love trying out different CMSs. i compared the UI side by side: What I liked about the above is that this is showing all 'Pages', and is listed as such. The above however also list 'Pages', because everything in processwire is a page. I think that 'Add new' should immediately popup on hover though like the way wordpress does. I can't much any point going to '/page/add/'. I also think 'Tree' should be removed entirely (when AOS module is used with 'Always show sidebar items'). The 'Page' link at the top goes to the same page and what does 'Tree' mean to a user? Off topic, but I find the Reno module awkward to use compared to the default admin theme. The accordian in the left menu requires a lot more clicking than the default theme hover/dropdown combo. However, Reno becomes a lot more useful with AOS and looks great. The actual editing process interested me as I remember wordpress being really easy to do this: This time though after using PW for a year is that there is too much distraction here. My eye wanders over to the right. The worst bit here is having to select a parent page every time you create a child page, that would pain me somewhat. I want to be able to select a parent and directly create a child (like Drupal or PW). I almost missed the 'Featured image' bit down there to the right (although it can be dragged up). Now this is nice. Very clear, a user will just move down the page, editing as they go. No need to worry about 'Parent' or 'Order' options (in WP). Another thing I notice as there doesn't seem to be any relationship to wordpress pages and posts. You can change the URL to posts to display on 'site.com/posts/my-post' but there is no 'posts' parent page. I find this quite confusing. Global categories can be set ( with a bunch of code https://stackoverflow.com/questions/16802751/multiple-custom-post-types-one-set-of-categories ) so your custom post types can use a single list of categories across the whole site. however, the categories are stored under 'Posts' in the admin bar to the left. So, in effect, they're global but don't LOOK global. Another +1 for my confusion. Custom fields (acf: repeater and repeater matrix, aka 'Flexible content field'... are only in pro version), custom post types (cpt), security (wordfence), user management (roles/permissions). I need plugins for all of those. There are plugins that do really simple stuff that cold be done in a few lines in PW. Although widgets look cool with the drag and drop, I'm not sure I'd actually want a client adding extra stuff all over the place on their site in sidebars etc. Setting image sizes, controlling image uploads are things I would expect in a CMS, not requiring extra functions to achieve. I mentioned earlier and this one is a killer for me, I hate this. I found a system that I'm productive with, it totally clicks with my brain, I can use any frameworks, any themes, make one from scratch, whatever, yet: (b) I have doubts that convincing people to use processwire is going to work. Mainly because I can't answer the question "who will take care of my site when you're gone". This is a legit question for a business owner and I feel this is also a big problem for a system that has a far lower userbase. So how do other people on the forum approach the above point? Currently looking at:2 points
-
Every request will create an entry, even ajax request in the background. So if you look at the log, it will poll it all couple seconds creating a new entry. Otherwise it's called once for every request, unless you have multiple instances. You shouldn't do something in the init other than setting properties, hooks or something. No resource heavy stuff if not needed.2 points
-
Hei, I found some time to reproduce your issue. The logfile (BE > Logs > Simplecontactform-log) contains the reason what's going wrong: > [FAILURE] Number of fields does not match. This means that the number of submitted fields does not match the number of fields which are present in the form. Looking further it turned out that $this->input->post does not contain the checkbox field (if it wasn't checked). It's a standard browser behaviour that the value of a checkbox is only sent if the checkbox was checked. This means I have to exclude this fieldtype when comparing number of fields / counting fields. coming soon... Edit: Just published a new release / version 1.0.5. Please update.2 points
-
Whether this module is in the core of ProcessWire or isn't is not too important to me. What I am very grateful for is that @ryan has addressed the functionality himself and produced what seems to be a solid solution. What we have now is a Login/Registration solution written and supported by @ryan. We are definitely better off than we were just a few weeks ago. We hope that the support is long-term and that there will be further enhancements to this module in the coming years. Front-end Login/Registration is, to me, a very important capability. @ryan has produced the basic scaffolding (his module) and hopefully others will add to or enhance the functionality of what's been produced.2 points
-
Hey @blynx, It is voluntary to make this module only compatible with PHP 7 ? I wanted to give a try to your module for a website I am building right now - using PHP 5.6 - but calling the module with : $pwpswp = $modules->get('MarkupProcesswirePhotoswipe'); $gallery = $pwpswp->renderGallery($page->gallery, ['theme' => 'masonry']); give me the following error (due to scalar type arguments) : Anyway, already loving it, thanks for making this module. I am using it with InstagramFeed, IsotopeJS and InfiniteScroll in a custom theme - Masonry - based on the Plain one :2 points
-
2 points
-
Nice! I don't think I'd use this though as I wasn't keen on the distraction of the wordpress sidebar. However, I think some clients might like this. That's interesting. I'm not so sure about the unlimited businesses without a website but you're more experienced than me so I def appreciate the input. You know that, I know that, the client may be a bit more skeptical. I actually think it rather generous of me to actually care how their project does 5 years down the line. I've had plumbers that come in, bodge it up and don't give a rats a** what happens in the future. But I digress After spending all day with wordpress, I think I've decided that my best bet is to shelve that idea for now and focus on: a) why I like processwire b) why a customer would like processwire c) security/ease of theming/speed/migration ease (without renaming absolute URLs with SQL *shudder*) d) the API and ease of use for future functionality e) the high level of base functionality without the need for any plugins at all i.e. not comparing to other CMSs at all, simply being able to point out the key points on why this system would be suitable (and more). It does seem like trying to sell ice to an eskimo though. I'll learn.2 points
-
I wasn't sure about replying because you are giving wordpress a lot of attention here. But reading your a) and b) I have my 5 cts worth it: That's what I thought also years ago until I learned otherwise. Bumping into a client who wants it done in wordpress: trying to convince a client doesn't work. I spent no longer than 5 minutes opening the door to processwire, then I leave my card and move on. There are unlimited small offices and businesses out there who still don't have a website. Not true. Have a look at the api of processwire. Any experienced coder will pick up the api of processwire in no time. Processwire is decoupled so nothing to learn on the front. Just pick any framework or code your own css. And that is exactly what I tell my clients: If I am not around anymore all you have to do is to find an experienced coder and your website will go on. Heck, I bet an experienced coder will pick up the api of processwire faster than wordpress.2 points
-
New website for the Camel cigarette brand. When you enter you will see an legal smoking age alert in Spanish, please click on the lower right option "Soy mayor de edad, me registraré luego" (Legal age confirmation) https://camel.com.do Modules used: ProCache Croppable Image 3 Form Builder Login for Facebook ProDrafts Profiler Pro ProcessWire API Explorer Tracy Debugger ListerPro Redirects2 points
-
Hi everyone, This is the new official thread for the module that was previewed some time ago here: https://processwire.com/talk/topic/14117-module-settings-import-export/ Big thanks to @Robin S for help testing and feature suggestions! http://modules.processwire.com/modules/module-settings-import-export/ https://github.com/adrianbj/ModuleSettingsImportExport Module features Ability to copy and paste settings from one PW install to another Optional automatic backup of module settings on uninstall and ability to restore settings if you reinstall the module Backup current settings at any time Restore backed up settings at any time Import option checks module name and version number and warns if importing settings from a different version As always, let me know if you find any problems or have any suggestions!1 point
-
Hi everyone, I'm proud to share my first fieldtype module and I think it's a quite handy one It helps you to create all kinds of table/matrix inputs very quickly and easily. You have loads of options for customizing your field via plain javascript. See the handsontable docs for that Please consider this module ALPHA until i got some more time to test it. Any help would be highly appreciated Numbers are for example always tricky. Different locale settings, different types, rounding errors and so on... Download: https://gitlab.com/baumrock/FieldtypeHandsontable Result: Installation/Configuration: Just install the Fieldtype, add a field to your template and set the handsontable options in the fields details. If you have InputfieldAceExtended installed you will also have code highlighting for your code: Get data: If you retrieve the data from the API with outputformatting ON you have some helper methods available: getData() + getRows() get all data of the field getRow($row) get one special row, eg getRow(1) or getRow("2017") getCols() get all data but by columns not by rows getCol($col) get one special column, eg getCol(1) or getCol("mycolumnheader") You can also access rowHeaders and colHeaders directly (see examples) Simple Example: Caution: the examples below are outdated! see this post:1 point
-
Hej, A module which helps including Photoswipe and brings some modules for rendering gallery markup. Feedback highly appreciated (Also pull requests are appreciated ? - have a new Job now and don't work a lot with ProcessWire anymore, yet, feel free to contact me here or on GitHub, Im'm still "online"!) Modules directory: http://modules.processwire.com/modules/markup-processwire-photoswipe .zip download: https://github.com/blynx/MarkupProcesswirePhotoswipe/archive/master.zip You can add a photoswipe enabled thumbnail gallery / lightbox to your site like this. Just pass an image field to the renderGallery method: <?php $pwpswp = $modules->get('Pwpswp'); echo $pwpswp->renderGallery($page->nicePictures); Options are provided like so: <?php $galleryOptions = [ 'imageResizerOptions' => [ 'size' => '500x500' 'quality' => 70, 'upscaling' => false, 'cropping' => false ], 'loresResizerOptions' => [ 'size' => '500x500' 'quality' => 20, 'upscaling' => false, 'cropping' => false ], 'pswpOptions' => (object) [ 'shareEl' => false, 'indexIndicatorSep' => ' von ', 'closeOnScroll' => false ] ]; echo $pswp->renderGallery($page->images, $galleryOptions); More info about all that is in the readme: https://github.com/blynx/MarkupProcesswirePhotoswipe What do you think? Any ideas, bugs, critique, requests? cheers Steffen1 point
-
As a web developer I always want to improve the search results of my websites in popular search engines. Because of that I find the topic of structured data very interesting and want to learn more about them. Recently I tried out a few of the ways how to provide more information to a website and want to share my solutions. Most of the structured data can be included directly in the markup or as JSON-LD at the end of your document (right before the closing body tag). I prefer the last one, because I don't like to have bloated HTML markup. Breadcrumbs Breadcrumbs are an alternative way to show the your page hierarchy inside search results, instead of showing just the plain URL. Just like the breadcrumbs on a website. Following the example, I ended up with this code: <?php if(strlen($page->parents()) > 0) { ?> <!-- Breadcrumbs --> <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "BreadcrumbList", "itemListElement": [ <?php $positionCounter = 1; $separator = ','; foreach($page->parents() as $parent) { if($parent->id == $page->parents()->last()->id) { $separator = ''; } echo ' { "@type": "ListItem", "position": "' . $positionCounter . '", "item": { "@id": "' . $parent->httpUrl . '", "name": "' . $parent->title . '" } }' . $separator . ' '; $positionCounter++; } ?> ] } </script> <?php } ?> First I am checking if the page has parents, then I follow the follow the markup of the example. I save the position of each parent in the variable positionCounter and increase its amount after each loop. As a last step I tried to end the JSON objects by not include the separating comma after the last object. This is why I am using the separator variable. Site name and sitelinks searchbox Using JSON-LD you can provide an alternative site name and a sitelinks searchbox inside the search results (Inception ). <!-- WebSite --> <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "WebSite", "name" : "Your site name", "alternateName" : "Your alternative site name", "url": "<?= $pages->get(1)->httpUrl ?>", "potentialAction": { "@type": "SearchAction", "target": "<?= $pages->get(1)->httpUrl ?>search/?q={search_term_string}", "query-input": "required name=search_term_string" } } </script> I am not 100% sure, if the sitelinks searchbox works this way. Maybe someone who made this work before could confirm it, that would help me out. Organization For organizations you could provide a logo and links to your social profiles. <!-- Organization --> <script type="application/ld+json"> { "@context": "http://schema.org", "@type" : "Organization", "name" : "Your organization name", "url" : "<?= $pages->get(1)->httpUrl ?>", "logo": "<?= $pages->get(1)->httpUrl ?>site/templates/images/logo.png", "sameAs" : [ "https://www.facebook.com/your-organization-url", "https://www.instagram.com/your-organization-url/" // All your social profiles ] } </script> This one I think is self explanatory. Article If you have an blog or a news site you could enhance your articles with structured data with an thumbnail and author. <?php if($page->template == "post") { ?> <!-- Article --> <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "NewsArticle", "mainEntityOfPage": { "@type": "WebPage", "@id": "<?= $page->httpUrl ?>" }, "headline": "<?= $page->title ?>", "image": { "@type": "ImageObject", "url": "<?= $page->thumbnail->httpUrl ?>", // Image field in template "height": <?= $page->thumbnail->height ?>, "width": <?= $page->thumbnail->width ?> }, "datePublished": "<?= date('c', $page->created) ?>", "dateModified": "<?= date('c', $page->modified) ?>", "author": { "@type": "Person", "name": "<?= $page->createdUser->first_name . ' ' . $page->createdUser->last_name ?>" // Text fields added to core module ProcessProfile }, "publisher": { "@type": "Organization", "name": "Your organization name", "logo": { "@type": "ImageObject", "url": "<?= $pages->get(1)->httpUrl ?>site/templates/images/logo.png", "width": 244, // Width of your logo "height": 36 // Height of your logo } }, "description": "<?= $page->summary ?>" // Text field in template } </script> <?php } ?> Here I am enabling structured data for the template called post. I also have the text fields first_name and last_name added to the core module ProcessProfile, the image field thumbnail and the text field summary added to the template. Just a small note: I know you could use $config->httpHost instead of $pages->get(1)->httpUrl, but I found the second one more flexibel for changing environments where you have for example HTTPS enabled. Those are the structured data I have in use so far. I hope I haven't made a mistake, at least the testing tool doesn't complain. But if you find something, please let me know. I love how easy it is with ProcessWire to get all the information from various pages and use them in this context. As mentioned above, I am nowhere an expert with structured data, but maybe some of you would like to provide also some examples in this thread. Regards, Andreas1 point
-
This module provides a solution for keeping various site settings in one place (titles, slogans, api keys, emails, addresses, etc.). Features - Admin can create unlimited number of settings - Settings can be grouped - Admin can set setting label, notes, property name, field width and type - Settings can be of type text, checkbox, radios, select, email, url, integer How to use In module configuration create as many settings as needed. Customize their label, type, width and provide a name you want to use in a template files (property name). After that admin can set those settings on "General Settings" page in "Setup" section. Every time you wish to output eg. site name you can use $settings->site_name or wire('settings')->site_name or $settings->option2 to get value of 'Check it' as seen on the first screenshot. (Checked checkbox returns 1). You can change global name ($settings) to something else in module configuration. To get basic markup with all settings and their values use $settings->render(), usefull to check returning values (esp. select/radios - their values are sanitized as page names). Current limitation: -no way to change order of settings, -new settings can only be added at the bottom. Multilanguage To make fields multilanguage aware create a field with a same property name with '_languageName' appended. Example: Your site has two languages: default and french, create site_title and site_title_french fields. Put in a template $settings->site_title. If a user has set french language, this module output site_title_french, otherwise site_title. Please notice that render() function is not language aware. https://github.com/pmarki/ProcessGeneralSettings1 point
-
Lets discuss the new admin theme, there has been very little talk about it, a few questions about its status and some simple designs by a few users. Have you played with it? Do you like it? Do you dislike it? Of course I'm not talking about its design, but the way its structured, how it works and the features it offers so far. ------------------------------ I'm working on a purple color scheme for it and it turned out quite well (imo), but one thing I dislike is the use of iframes. I haven't used iframes before so it might be just me, but I'm struggling with them when it comes to javascript. When iframes are used all scripts are loaded in every frame, which can lead to unexpected results. Javascript is an easy way to add, remove, move etc. elements in the admin, but the iframes complicate things. What are your thoughts? Is it just me? Here's a screenshot of the purple theme:1 point
-
Thanks @AndZyk! That indeed solved the image issues. On your point regarding the logo, serving a compact logo for mobile is what I hope to accomplish in the long road. I also noticed that changing the column to uk-width-1-1@m helped with the resizing on mobile as well (in terms of the column). I appreciate all the help.1 point
-
Hello @louisstephens, first of all great that you are giving UIkit a chance. I am coming from Bootstrap as well but UIkit is now my favorite framework so far. Here are a few points you mixed up: If you only have one item in a container you don't need a grid and instead can just use the uk-width-* classes. The class uk-grid-match is used for cards and makes your image stretched. Also it is not necessary if you only have one item. You should remove it. If you have a grid you should either define uk-child-width-* classes or assign uk-width-* classes to the items. Doing both is not very clean. If you care about validation, you should use data-uk-grid instead of uk-grid. Without the data attribute you get an error in the validation. Considering your logo: Even resized it will be very small on mobile devices. You should either think about a more compact logo or work with the picture element to show optimized versions. Regards, Andreas1 point
-
I was expecting to find a method to hook before admin theme in the hopes that I could modify $config->styles, but unfortunately there's none. Here's how AdminThemeDefault uses it: // /wire/core/modules/AdminTheme/AdminThemeDefault/default.php $config->styles->prepend($config->urls->root . "wire/templates-admin/styles/AdminTheme.css?v=$version"); $config->styles->prepend($config->urls->adminTemplates . "styles/" . ($adminTheme->colors ? "main-$adminTheme->colors" : "main-classic") . ".css?v=$version"); $config->styles->append($config->urls->root . "wire/templates-admin/styles/font-awesome/css/font-awesome.min.css?v=$version"); $ext = $config->debug ? "js" : "min.js"; $config->scripts->append($config->urls->root . "wire/templates-admin/scripts/inputfields.$ext?v=$version"); $config->scripts->append($config->urls->root . "wire/templates-admin/scripts/main.$ext?v=$version"); $config->scripts->append($config->urls->adminTemplates . "scripts/main.$ext?v=$version"); ... <head> ... <script type="text/javascript"><?php echo $helpers->renderJSConfig(); ?></script> <?php foreach($config->styles as $file) echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />"; ?> <?php foreach($config->scripts as $file) echo "\n\t<script type='text/javascript' src='$file'></script>"; ?> <?php echo $extras['head']; ?> </head> Here's how AdminThemeReno uses it: // /wire/core/modules/AdminTheme/AdminThemeReno/default.php // Styles $config->styles->prepend($colorFile . "?v=" . $version); $config->styles->prepend($config->urls->root . "wire/templates-admin/styles/AdminTheme.css?v=$version"); $config->styles->append($config->urls->root . "wire/templates-admin/styles/font-awesome/css/font-awesome.min.css?v=$version"); // Scripts $config->scripts->append($config->urls->root . "wire/templates-admin/scripts/inputfields.$ext?v=$version"); $config->scripts->append($config->urls->root . "wire/templates-admin/scripts/main.$ext?v=$version"); $config->scripts->append($config->urls->adminTemplates . "scripts/main.$ext?v=$version"); ... <head> ... <script type="text/javascript"><?php echo $helpers->renderJSConfig(); ?></script> <?php foreach($config->styles as $file) echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />"; ?> <?php foreach($config->scripts as $file) echo "\n\t<script type='text/javascript' src='$file'></script>"; ?> <?php echo $extras['head']; ?> </head> There arent any method calls anywhere. BUT, with my SUPER hacky way, you can intercept the styles as they're added to $config->styles. <?php namespace ProcessWire; // /site/templates/admin.php class MyFileArray extends FilenameArray { private function intercept($filename) { if (strpos($filename, '/templates-admin')) return true; elseif (strpos($filename, '/AdminTheme')) return true; } public function append($filename) { if (!$this->intercept($filename)) { parent::append($filename); } } public function prepend($filename) { if (!$this->intercept($filename)) { parent::append($filename); } } } /** @var Config $config */ $config->styles = new MyFileArray(); require($config->paths->adminTemplates . 'controller.php');1 point
-
I think this is a really positive thing to do. Focus on what you enjoy working on and where you want to take someones site and maybe they'll see that sincerity and take notice.1 point
-
You can kinda "clone" a page into home page like this, but it can't copy image/file fields (as far as I tested). $source = $pages(1015); $home = $pages(1); $source->of(false); $home->of(false); // change template (remember to create new template file and allow access to guest users in Template > Access) // $home->template = $source->template; foreach($source->template->fieldgroup as $f) { if ($home->hasField($f)) $home->$f = $source->$f; } $home->save();1 point
-
I have to agree that I don't think this module needs to be part of core. But I do think that it needs to remain in active development, even if that means it becomes a Pro module. Modules like ListerPro (which I love and use all of the time) bring value to a project, but they aren't necessarily defined as a project requirement by the client. However, if a project requires the functionality of Login/Register/Profile, this module may mean the difference of a client agreeing to use ProcessWire over another CMS. To me, that's a game changer, and is why it has been on my wishlist for some time. I've already started using it for a community project that I've wanted to build, although I'm hoping that it will play nicely with images very soon.1 point
-
1 point
-
1 point
-
Shouldn't this be $value->$languageName in the assignment in the loop in sleepValue?1 point
-
1 point
-
Thanks for letting me know your great module. The module is really handy and fit for many use case. I have waited long to see excel like inputfield like this one as I do not have the ability to make one as I am not good at database. The case I encounter is that I need the permission control over the price for different country. I think it would be the best to make the field multi-language enabled. Below is the update. Only default language is saved correctly, while other languages are still null if I saved any value into them. The issue is that the sanitizeValue() input $value is always null for other languages, while sleepValue() $value is good. I cannot find where the value get removed. <?php namespace ProcessWire; require_once(wire('config')->paths->root . 'wire/modules/LanguageSupport/FieldtypeLanguageInterface.php'); /** * Multi-language capable float field * * ProcessWire 3.x, Copyright 2016 by Ryan Cramer * https://processwire.com * * */ class FieldtypeFloatLanguage extends FieldtypeFloat implements FieldtypeLanguageInterface { public static function getModuleInfo() { return array( 'title' => 'Float (Multi-language)', 'version' => 0, 'summary' => 'Field that stores a floating point (decimal) number in multiple languages', 'permanent' => false, 'requires' => array('LanguageSupportFields'), ); } /** * Sanitize value for storage * * @param Page $page * @param Field $field * @param LanguagesValueInterface|float $value * @return LanguagesPageFieldValue * */ public function sanitizeValue(Page $page, Field $field, $value) { foreach($value as $languageName => $languageValue) { $languageName = $this->wire('languages')->get($languageName)->name; if(!strlen("$languageValue")) $value->$languageName = ''; if(!is_float($languageValue) && !is_int($languageValue)) { $value->$languageName = $this->wire('sanitizer')->float((string) $languageValue, array('blankValue' => '')); } if(is_null($field->precision)) { $value->$languageName = (float) $languageValue; } else { $value->$languageName = round((float) $languageValue, $field->precision); } } return $value; } /** * Return the database schema in specified format * * @param Field $field * @return array * */ public function getDatabaseSchema(Field $field) { $schema = parent::getDatabaseSchema($field); $languageSupport = $this->wire('modules')->get('LanguageSupport'); foreach($languageSupport->otherLanguagePageIDs as $languageID) { $schema['data' . $languageID] = 'float'; $schema['keys']["data{$languageID}"] = "KEY `data{$languageID}` (`data{$languageID}`)"; } return $schema; } /** * Format value for output, basically typecasting to a float and sending to textformatters from FieldtypeFloat * * @param Page $page * @param Field $field * @param LanguagesValueInterface|float $value * @return float * */ public function sleepValue(Page $page, Field $field, $value) { $precision = $field->precision; foreach($value as $languageName => $languageValue) { $languageName = $this->wire('languages')->get($languageName)->name; if(is_null($precision)) $precision = self::getPrecision($languageValue); if(!is_string($languageValue)) $value->languageName = number_format($languageValue, $precision, '.', ''); } return $value; } }1 point
-
1 point
-
1 point
-
Or just provide an ASM multi-select field with a list of the fields that the client can order as they desire. You could do this manually with an Options fieldtype, or perhaps with this: http://modules.processwire.com/modules/fieldtype-fields/ which lets you limit the listed fields based on a selector. You could add this field to a separate "Field Order" tab to keep things clean. Of course then you order the output of the fields in your template file based on the order they have selected.1 point
-
you could also use my handsontable module to create an input for each language and then query the column based on the language code and return the price. the module is alpha and you have to be careful when changing settings after field setup as data may bet lost, but maybe it's worth a try.1 point
-
Why is there no simple preview button? For simple websites I dont need the features of the ProDrafts. I think, it should be in the core.1 point
-
1 point
-
Thanks @adrian since it hooks into the default login method, this should already happen. The module does only provide a username of the user to the login method if it finds a user with the provided email. Like so: Login attempt using default method > hook: check if entered username is in fact email > check if (only one) user exists with this email > return users username for login Default login method procedes. @kixe Thanks for pointing this out. I added this check like the new login module from ryan does it. A login with email is now only possible if the email is unique.1 point
-
To remove the breadcrumbs, and change headline and browser title: $this->addHookBefore('Process::execute', function (HookEvent $e) { /** @var Process $process */ $process = $e-object; if ($process != "ProcessModule") return; $e->wire('breadcrumbs')->removeAll(); $e->wire('processHeadline', 'asd'); $e->wire('processBrowserTitle', 'asd'); }); You can't really remove headline and browser title, because admin theme defaults to page name if it doesn't exist. // AdminThemeDefaultHelpers.php /** * Get the headline for the current admin page * * @return string * */ public function getHeadline() { $headline = $this->wire('processHeadline'); if(!$headline) $headline = $this->wire('page')->get('title|name'); // ... } /** * Render the browser <title> * * @return string * */ public function renderBrowserTitle() { $browserTitle = $this->wire('processBrowserTitle'); if(!$browserTitle) $browserTitle = $this->_(strip_tags($this->wire('page')->get('title|name'))) . ' • ProcessWire'; // ... } But you can set it to a unicode space character, like which works well enough. $e->wire('processHeadline', " "); $e->wire('processBrowserTitle', " ");1 point
-
Thanks. Just to clarify, this is not a core module, and won't ever be. When it comes to the core, I think it's best to intentionally limit the front-end "inputs", and leave anything further to one's own template files or modules that you may install (like this one). That way, we can be certain that the common front-end inputs to ProcessWire sites never exceeds the actual needs of an individual site, which I think is good for security. It already supports multi-language. It uses scssphp and lessphp. People who have already rolled their own solutions may prefer to stick with what they have, since presumably you've customized it to your needs and workflow already. But the compilation in ProCache is definitely handy, and I think folks that haven't already settled on a workflow of their own may find the one built into ProCache very useful. ProCache has always monitored your CSS and JS files for changes (and now SCSS and LESS files) to determine when it needs to merge and minify them. So making scssphp/lessphp part of that process makes a lot of sense. No external watchers, editors or background processes are needed. It's also handy if you want a common solution between servers that works regardless of whether in the dev environment, staging environment, or directly on the server, etc. It's nice knowing that a change will get compiled regardless of how or where the file is edited. You could disable it by editing the module file. But I wouldn't recommend it. A form that allows one to create a new ProcessWire login account without validation would quickly get abused. Over time it would just fill up with millions of bot accounts.1 point
-
Why do you assume it isn't capable of different languages? The source code contains pretty much translatable strings like that: _('You have logged out') – the underscore indicates that it is translatable. What's missing now is the translation itself – feel free to chime in! Here is all you need1 point
-
1 point
-
Yay, update: https://github.com/blynx/MarkupProcesswirePhotoswipe Now has some simple 'themes', cooler ones later ... <?php $pwpswp = $modules->get('MarkupProcesswirePhotoswipe'); echo $pwpswp->renderGallery($page->nicePictures, ['theme' => 'h-scroller']); // available themes: plain, flex, h-scroller 0.7 - 2017/07/11, themes fixed: Size option correctly adopts height value added: Theme functionality added: Simple themes 'plain' (previous default), 'flex', 'h-scroller' other: Updated readme other: No notice on undefined photoswipe options other: Refactoring1 point
-
Update is out: https://github.com/blynx/MarkupProcesswirePhotoswipe Also removed the Pwpswp class alias, because it was pretty pointless. Processwire does not recognise it as a module and I don't really use static methods in that class. 0.5.1 - 2017/07/06, fixes removed: Removed pointless shortcut alias class fixed: Use of correct module/class name for file paths fixed: Configuration instructions for file paths other: Updated readme1 point
-
Ah! yep, I renamed the module later on - thats a bug I will correct later. Thanks!1 point
-
Hey Blynx, Thanks for the nice module Not sure, it's probably just me, but to get this working (local MAMP setup) I had to use the full module class name (MarkupProcesswirePhotoswipe) (not the alias Pwpswp) and the css/javascript etc paths were incorrect , so instead of MarkupPwpswp/path-to-files within the .module file, I had to change these to MarkupProcesswirePhotoswipe/path-to-files After this all worked nicely Thanks again!1 point
-
sure, here are some examples, i have these in a file called schema_helpers.php, which is in my shared functions folder: 1.) function siteSchema() { $page = wire('page'); $schema = array( "@context" => "http://schema.org", "@type" => "Website", "url" => wire('pages')->get(1)->httpUrl, "name" => $page->title, "description" => '', "potentialAction" => array( "@type" => "SearchAction", "target" => wire('pages')->get(1000)->httpUrl . "?q={search_term}", "query-input" => "required name=search_term" ), "about" => array( "@type" => "Thing", "name" => "A very interesting THING", "description" => "Website about a very interesting THING" ) ); if($page->summary) { $schema['description'] = $page->summary; } else { unset($schema['description']); } return '<script type="application/ld+json">' . json_encode($schema) . '</script>'; } 2.) News function jsonldNews($item, $settings) { $image = $item->image ?: getFallbackImage($item); if(!$image) return; $out = ''; $jsonld = array(); $jsonld["@context"] = "http://schema.org/"; $jsonld["@type"] = "NewsArticle"; $jsonld["name"] = $item->title; $jsonld["headline"] = $item->title; $jsonld["url"] = $item->httpUrl; $jsonld["mainEntityOfPage"] = array( '@type' => "WebPage", '@id' => $item->httpUrl ); $jsonld["description"] = $item->summary; $jsonld["datePublished"] = date(DATE_ISO8601, $item->published); $jsonld["dateModified"] = date(DATE_ISO8601, $item->modified); $jsonld["dateline"] = date(DATE_ISO8601, strtotime($item->news_date)); $jsonld["wordCount"] = str_word_count($item->body); $jsonld['author'] = $settings['author']; $jsonld['publisher'] = $settings['entity']; $jsonld['articleBody'] = $item->body; $jsonld['articleSection'] = $item->categories_select->first()->title; // Publisher $pubLogo = wire('pages')->get(3525)->image; if($pubLogo) { $pubLogo = $pubLogo->height(60); $jsonld['publisher'] = array( '@type' =>'Organization', 'name' => 'A Publisher', 'url' => 'https://publisher.org/', 'logo' => array ( '@type' => 'ImageObject', 'url' => $pubLogo->httpUrl, 'height' => $pubLogo->height, 'width' => $pubLogo->width ) ); } // News Items may have a featured image $image = $image->width(696); $jsonld['image'] = array( "@type" => "ImageObject", 'url' => $image->httpUrl, 'height'=> $image->height, 'width' => $image->width ); $out .= '<script type="application/ld+json">' . json_encode($jsonld) . '</script>'; return $out; } 3.) Event function jsonldEvent($event) { if(!$event->event_location_select) return; if($event->template == 'event-child') { // inherit unset fields needed $event->event_link = $event->event_link ? : $event->parent->event_link; $event->body = $event->body ? : $event->parent->body; $event->event_location_select = $event->event_location_select ? : $event->parent->event_location_select; $event->price = $event->price ? : $event->parent->price; $event->currency_code = $event->currency_code ? : $event->parent->currency_code; $event->link = $event->link ? : $event->parent->link; } $out = ''; foreach($event->event_date_m as $ed) { $jsonld = array(); $date8601 = date(DATE_ISO8601, strtotime($ed)); $jsonld["@context"] = "http://schema.org/"; $jsonld["@type"] = "MusicEvent"; $jsonld["name"] = $event->title; $jsonld["url"] = $event->event_link; $jsonld["description"] = $event->body; $jsonld["startDate"] = $date8601; if($event->event_location_select) { $state = $event->event_location_select->state ? $event->event_location_select->state->title : $event->event_location_select->address_state; $jsonld["location"] = array( "@type" => "Place", "name" => $event->event_location_select->title, "url" => $event->event_location_select->link, "address" => array( "@type" => "PostalAddress", "streetAddress" => $event->event_location_select->address_street, "addressLocality" => $event->event_location_select->address_city, "addressRegion" => $state, "postalCode" => $event->event_location_select->address_zip, "addressCountry" => $event->event_location_select->country->title ) ); } if($event->price && $event->currency_code && $event->link) { $jsonld["offers"] = array( "@type" => "Offer", "description" => "Tickets", "price" => $event->price, "priceCurrency" => $event->currency_code, "url" => $event->link ); } $out .= '<script type="application/ld+json">' . json_encode($jsonld) . '</script>'; } return $out; } Also - I don't think you need to use JSON_PRETTY_PRINT1 point
-
Autojoin is a way to have data for some fields bundled into the query that loads the page. It's a way of reducing number of queries for fields that you always want loaded with the page. For instance, you probably always want to load the page's "title" field (a good autojoin candidate). Whereas, something like a large "body" field you probably only need when the full page is rendered. So no need to have that "body" field loaded with every instance of the page (autojoin off). In reality, well indexed and simple MySQL queries are extremely fast, and autojoin may not make that much difference in real use. For example, a couple hundred simple select queries will often run faster than one or two really complex queries. So query counting is futile. But I believe it's still a good idea to use autojoin for fields that you always want loaded with every instance of the page. Most fields do not need to be autojoin. Using autojoin on FieldtypeMulti fields (like pages, files, images, comments, etc.) is a tricky matter because the primary page load query is designed to execute with 1 fetch with no data repetition. That ensures the fastest possible performance. Fields with multiple entries (FieldtypeMulti) are not well suited to being retrieved in 1 fetch. However, ProcessWire can still do it using a MySQL GROUP_CONCAT function to bundle the multiple entires into a string suitable for that 1 fetch. The problem is that MySQL has a byte limit on how much it will GROUP_CONCAT (it's a MySQL setting that we can't count on). As a result, autojoin is okay to use on simple multi-entry fields like Page relations that don't have hundreds of entries–that's because it's just a bunch of integers. But it's not well suited for more complex fields like images that might have long descriptions. As a result, I don't recommend using it with file/image fieldtypes. In PHP5, all object instances are passed by reference. So that particular function is adding on components to the query object to support the autojoin if it can.1 point