-
Posts
813 -
Joined
-
Last visited
-
Days Won
41
Everything posted by Jonathan Lahijani
-
Module FrontendUser: login, logout and register users / members
Jonathan Lahijani replied to pwFoo's topic in Modules/Plugins
Question... let's say I want users only with a particular role to be able to log in, how would I go about that using hooks? Current code: $fu = $modules->get('FrontendUser'); $fu->login(); $fu->login(array('username', 'password', 'persist', 'forgot')); $fu->process($pages->get("/")->url); echo $fu->render(); -
ProcessWire Screencasts / Video Tutorials
Jonathan Lahijani replied to Jonathan Lahijani's topic in Dev Talk
OK, I'm finally going to be breathing some life into this project. I got the title sequence done (well a near final draft) along with intro music (bought the track music from audiojungle). Here's a little teaser: http://jonathanlahijani.com/wirecasts-teaser.mp4 The title sequence is a little choppy. Need to fix that. It's actually just a screen capture of an animation I made using plain old html/css with animate.css. I have about 15 videos done so far, but another 18 to go. This WordPress vs. ProcessWire series will cover many different features and quickly compare the two systems. It will not be biased and will compare the best of WordPress to the best of ProcessWire.- 33 replies
-
- 16
-
-
Determine old vs. new value of field when saving
Jonathan Lahijani posted a topic in Modules/Plugins
I'm having trouble figuring out how to do this correctly. Let's say I have a page with an ASM select field. Let's say this ASM select field has values A, B and C selected. Let's say the page is edited so that the ASM select field has C removed and then it is saved. How do I determine specifically if C was removed and also display a custom notification if C was removed (in addition PW's regular save page notification)? I've got my code to a point where it can determine if this field was changed, but not specifically what value were changed. Not sure how to do it. Thank you. -
Although I generally use CSS frameworks, I decided not to use one for this project because most of the features they provide would not be used (especially the grid system). This site is very low on widget/component-like design, so to me it made sense to selectively bring in only the features that were needed (masonry-layout, lightbox, carousel, etc.). Bootstrap for example comes with a carousel but it's not as good as Slick.js. It also has a lightbox/modal, but it's not optimal for lightbox galleries which is why I used Fresco for images/videos and Featherlight for text. I wouldn't be able to fine-tune the responsive breakpoints Bootstrap provides with its grid system (or at least not without a lot of headache). The site didn't require 6 button styles, accordions, etc. Easy enough to accomplish these features without a framework. Bootstrap automatically makes a mobile optimized navigation from the navbar component, but using Bootstrap's navbar (combined with its grid framework) would have caused a lot of trouble with the masonry photo layout since that masonry photo layout has it's own breakpoints that would clash with Bootstrap. A big CSS framework could be utilized, but my approach is to use the best tools for the task at hand.
-
Hi Ivan, The only paid/commercial plugin is Fresco. Yes, the site is very bandwidth intensive, which is a tradeoff that had to be made but in opinion acceptable given the primary audience viewing the site. One adjustment that might be made is lazy loading of images: http://luis-almeida.github.io/unveil/ Also, maybe a better hosting solution like Digital Ocean. It's on GoDaddy right now.
-
I soft-launched this site a few weeks ago and it's still being refined, however most of it is complete: http://brakhax2.com/ Brakha X2 is a production company headquarted in Los Angeles. They handle many large ad campaigns for well known brands. The bulk of the site consists of the image galleries (/advertising/, /editorials/, /silent-pictures/, etc.). The images in these galleries are not coming in via a typical images field since the images are really more like artwork pieces with it's own set of data. Therefore, I decided to create a template called "image" and a field in it called "image" (max upload of 1) in with some other fields (title, tags [not being used yet], body, etc.). These images then get assigned to each image_gallery in a Page field I created called image_items. By allowing each image / artwork piece to have it's own page, it allows for: a specific URL for each artwork piece page (example: brakhax2.com/images/name-of-the-piece/) fine control when people share images via social media (OG tags) the ability to re-use the entry in Page fields There's some fancy stuff going on in the frontend. I didn't use a CSS framework since it wouldn't have been a good match. I ended up using the following packages: Packery: this takes care of the masonry-style layout on the gallery pages ImagesLoaded: this allows the gallery images to show only after all the images have been loaded. it will show the loading graphic until everything is loaded Featherlight: this is a simple lightbox which is being used for the bios on the contact page Slick.js (aka Slick Carousel): this is being used for the video galleries (/spots/, /inside/) Fresco: a great commercial plugin that powers the lightboxes for the images and videos Responsive-nav: this takes care of the mobile menu logic Animsition: this takes care of page-to-page fade animations There's a few other little techniques/approaches being utilized on the site, but that covers all the major stuff. Eventually I will work in a Gulp workflow so that the CSS and JS is packaged and minified. Jonathan
- 9 replies
-
- 12
-
-
AdminTemplateColumns ProcessPageDelete FormBuilder ProcessWireUpgrade WireMailSwiftMailer MarkupRSSEnhanced
-
Made my own ProcessWire T-shirt: http://i.imgur.com/FBWb59Q.jpg
-
Complicated Page Query (page references, etc.)
Jonathan Lahijani replied to Jonathan Lahijani's topic in General Support
I just implemented this approach based off of your code. I like the bi-directional concept behind it, although data is being stored twice. I can live with that. -
Complicated Page Query (page references, etc.)
Jonathan Lahijani replied to Jonathan Lahijani's topic in General Support
Thank you for the variation in answers. I wonder if this could become a core feature. Pseudo-code off the top of my head: $people = $pages->find("parent=/people/,template=person,first_name=Joe,referenced_by_template=company,referenced_by_field=people"); -
There's been various forum posts regarding a similar topic, but I can't seem to crack this query. Here's my data structure: /companies/ /company-1/ (company.php) /company-2/ (company.php) /company-3/ (company.php) /people/ /person-1/ (person.php) /person-2/ (person.php) /person-3/ (person.php) The company.php template has a Page field (asm-select) called "people" which grabs all the people from /people/. Therefore, a company can be assigned many people. (note: technically this could be done in reverse... meaning I could create a Page field called "companies" and assign that field to the people.php template, but the approach I'm taking makes more sense I believe... can control sort orders, etc.) Now, let's say I want to do a query and find People whose first name is 'Joe' and who belong to a company with the word "Test" in it. $companies = $pages->find("parent=/companies/,template=company,title~=Test"); $people = $pages->find("parent=/people/,template=person,first_name=Joe,XXX=$companies"); The part where I wrote XXX is where I'm lost. XXX would represent a belongs_to relationship like in Ruby on Rails. I mentioned above that I could setup the fields in a reverse way, which if that were the case, this query would be easy (but create other organizational issues), however I want to stick to the approach field approach. I know there's a lot of ways to go about this. Perhaps I'm also overlooking something very obvious too. Edit: This post is the most relevant to what I'm discussing: https://processwire.com/talk/topic/1071-page-fieldtype-two-way-relation/
-
For anyone looking for a great frontend approach / workflow that uses all the cutting edge practices and tools, I highly recommend taking a look at the Sage Starter Theme for WordPress (formerly known as Roots... they changed it to Sage and kept the "Roots" name as the parent organization name). Although Sage is built around WordPress, it's not difficult to strip away the WordPress related bits (mainly template related things and workarounds that fix some of WP's quirks) so it can work with ProcessWire. In fact, this has been my primary frontend technique for most ProcessWire sites. They have a great community over there as well. Relevant links: https://roots.io/ https://roots.io/new-website-sage-and-the-future/
-
Any particular reason you didn't go with Soma's Template Notes module? http://modules.processwire.com/modules/template-notes/
- 15 replies
-
- responsive
- ajax
-
(and 2 more)
Tagged with:
-
As a former (well, still current WP developer due to certain clients), I can tell you that your search is in fact over.
-
Hi Felix, I remember giving Masonry a shot, but at the time, I think I hit some sort of limitation that I believe now really isn't a limitation. I'm going to give Isotope another look however now that the dust has settled on this site. I'm also probably going to swap out the Blueimp Gallery with Slick Carousel. Horst... thanks for pointing that out. Jonathan
-
Nicely done. One little recommendation I have on the frontend is to utilize Slick Carousel instead of Bootstrap's carousel. It's much more powerful and has touch support, among many other features. I will eventually be switching some carousels I've done in the past to it. Zurb Foundation also recommends it now instead of their built in carousel (Orbit Slider, which is being deprecated). - Jonathan
-
I recently created an ecommerce website, iBuildMacs, that I built with ProcessWire. Given that there's been quite a bit activity on combining ecommerce with ProcessWire, I feel many people would be interested in the approach I took. Feel free to visit it at: http://ibuildmacs.com/ The requirements for this site were: a computer configurator, much like the Apple website; example product page here cart checkout payment methods: paypal or check/cash shipping methods: the cost of shipping is based on a fixed cost that is related to the country being shipped. no live quotes The requirements did NOT include: tax rules inventory management coupons, gift certificates different product types: simple products, variable products, digital/downloadable products, etc. user accounts, address management a fancy ajax driven checkout So, I had a bit of flexibility for this site given the specific feature set. I then thought about how I wanted to develop the site. The options I considered included: WooCommerce: I've built several intricate websites with WooCommerce, the most recent being caviar.com. It was good fit that website, but for iBuildMacs, which has less requirements and a very unique product configurator, which WooCommerce could do but with a tremendous amount of overrides and working backward, I decided this wouldn't but the right fit. Plus, I'm trying to become as WordPress-free as possible. FoxyCart: A ProcessWire favorite, however I wanted to challenge myself a little bit with this site, and also keep things under one roof. Magento, Shopify, (insert some specific heavy or cloud-based ecommerce system you like): No. Overkill and making a product configurator would be a pain. After considering my options, I felt just rolling it entirely with ProcessWire and programming the catalog, payment methods, shipping methods and checkout tailored to the site's specific needs was the way to go. This would definitely reduce the time and headache needed in bending anyone of the above systems I mentioned to behave exactly the way I wanted it to. Products This was one of the complicated parts of the website, but ProcessWire, with its infintely flexible custom fields, made this a breeze. I have a product template (product.php). It has some general fields like Title, Body, Image and Base Price. It also has a PageTable field called Features. These features are child pages of the product and use feature template (feature.php), so the Features PageTable field just grabs its data from there. Then, the feature template has some general fields like Title, Body, Image and PageTable field called Feature Options. These feature options are child pages of the feature template using the feature option template (feature_option.php). So, what I ended up having is a 3 level deep structure, with two nested PageTable fields. Here's a video of what it looks like, which is quite slick is very easy to manage: https://vid.me/kjDW Cart When a user adds a configured product to their cart, it must be stored somehow and I thought of a variety of ways to do this. Ultimately, I decided that cart data is handled as a page (using the order.php template) undernearth /orders/. This order.php template has a page name that is based on the session id of the user, so it'll remain unique and not cause a conflict with other people's carts (as well as obscure from people trying to guess it's url, which is used for the order confirmation page). One of the fields in this order.php template is called "products_ordered", which utilizes the Table fieldtype (a Profields table). Video: https://vid.me/MIRl Checkout The checkout is a straight forward form with the basic questions. However, the shipping section is where it gets tricky. The requirements for this site were that each computer has a fixed shipping price depending on the method being used to ship. The shipping methods available to a customer are dependent on their country. I think WooCommerce could manage rules like that, but directly coding it wasn't that difficult. I create an array that stored the 2 payment methods, and another array that stored the 6 total shipping methods. I also have an array for all the countries. I then wrote some JavaScript that managed the relationships between the country chosen and the shipping methods available for the chosen country. When choosing a method, it will update the Shipping cost line item on the car to the right. Just basic JavaScript going on here. All nice and on one page. When the submit button is pressed, it will run through some logic and validate all the data and save it to the same page that stored the cart data. An order confirmation email is sent to the customer, and one is also sent to the admin (SwiftMailer). If Check/Cash was chosen, the user is then simply forwarded to the order confirmation page, which is at /orders/whatever-their-page-name-was-saved-as/. The email they are sent also has a link referencing this page. If PayPal was chosen, a URI is built and the user is taken to PayPal complete payment with PayPal Payments Standard using the Cart Upload command. Documentation here. After they complete Payment on PayPal, they are then taken to the order confirmation page as described previously. Video: https://vid.me/hwfB I will eventually be using ListerPro for a nicer admin orders list display and build a few custom actions to allow administrators to quickly send general emails from the system (like, when the order is shipped). Modules Used Admin Template Columns: http://modules.processwire.com/modules/admin-template-columns/ Markup Simple Navigation: http://modules.processwire.com/modules/markup-simple-navigation/ Maintenance Mode: http://modules.processwire.com/modules/maintenance-mode/ Batcher: http://modules.processwire.com/modules/process-batcher/ Form Builder (for the contact form only): https://processwire.com/talk/store/category/2-form-builder/ Swift Mailer: http://modules.processwire.com/modules/wire-mail-swift-mailer/ PageTable field type ProFields Table: https://processwire.com/talk/store/category/7-profields/ ListerPro (eventually): https://processwire.com/talk/store/category/9-listerpro/ Enjoy!
-
Hey all, I launched this website a few weeks ago: http://www.archsf.com/ It was deceptively simple looking at a first glance of the mockups, however this project turned out to be very challenging and ProcessWire really shined, as it always does. The main template being used on the site is the Project Category template. Here's the "Residental" page, which is powered by that template: http://www.archsf.com/project-categories/residential/ As you can see, if you're on a large screen, there are 5 blocks across (1 callout + 4 projects). I'm using Zurb Foundation (the Grunt/Libsass version, which rocks), however like most CSS frameworks, there isn't an even 5 column structure, so I had to take care of that manually. Then, add in the fact that the website is full browser width, which presents a whole host of width/height manipulation that must be done. All the project thumbnails are the same size, but that first callout is text-based so it's height must calculated based of the height of one of the project thumbnails. But of course, the thumbnails themselves are dynamic in height depending on the browser width. And, you can only get the height of the images once they are loaded in (which is easy thanks to the imagesLoaded plugin). Now, if you look at the next row, it's not 5 easy blocks across, but rather 2 blocks, then a big block that takes up 2 block spaces, then another regular size block. I went through some different approaches to handle that situation, and what I ended up doing is hardcoding a the layout so that specific blocks would appear in specific places. It's not a masonry / nicely floated structure! Then, let's not forget this is a responsive site. So, for the phone-sized breakpoint, there's actually another repeated layout of all the project thumbnails, but it's set to hidden unless viewing that breakpoint (which will hide the other breakpoints). That breakpoint has 2 blocks across, with the occasional 1 block featured project. There is also the tablet-sized breakpoint, which has 4 blocks across. This approach, from a code point of view, is a bit ugly in that content is being repeated on a page, however this was a necessary decision I had to make in order for the complicated layout structure to work. It didn't seem to affect the search engine indexing of the site however. Also, each project thumbnail also has different image sizes based on the breakpoint being viewed. ProcessWire makes creating thumbnails on the fly so easy, which is a huge plus (especially compared to WordPress). Oh, while administrators have the ability to create projects, they sometimes wanted the ability to have a project assigned 2+ times for a page. Now, having them create a repeat project would be inefficient, so I created another template type called 'duplicate_project' which allows a custom title and thumbnail, but then has a dropdown field that makes the duplicate project act as the main project. As for the lightbox that appears when clicking on a project thumbnail. An ajax request is made to the project template file, which returns a JSON object containing the lightbox image data for Blueimp Gallery, which is the lightbox being used (not Foundation's Clearing Lightbox, which I find very annoying!). It works well, except aligning the bottom-left caption (and bottom-right "Project Information" toggle) was an huge exercise in manipulating the absolute positioning of that element, relative to the image itself, because Blueimp by default doesn't align captions relative to the image. I considered using other lightboxes, but Bluimp turned out to be the best one for my needs, and it's responsive out of the box. The projects themselves have their own individual pages/URLs, but not in the classic sense. If you go to a direct URL of the project, I wrote some code so that it will show the FIRST category it's been assigned to, and then automatically bring up the lightbox containing the projects images. It does this by detecting the the page being hit is either project-category.php or project.php and running the necessary code, which involves the same AJAX request to bring up the lightbox. Example: http://www.archsf.com/projects/aptos-street/ The firm page is whole other beast, but I won't get into that. Screenshots demonstrating some internals: Editing a Project Category: http://goo.gl/T30AEh Editing a Project: http://goo.gl/fekgqQ Editing a Duplicate Project: http://goo.gl/ppKfo5 Editing a Callout: http://goo.gl/gfEbPO Editing the Home Page: http://goo.gl/rbHlRQ Overall Page Structure: http://goo.gl/gfEbPO Enjoy. Jonathan
- 7 replies
-
- 17
-
-
Module: Fieldtype Image Extra (multi-language)
Jonathan Lahijani replied to justb3a's topic in Modules/Plugins
Excellent module! -
I think there may be a small bug with this plugin. Let's say you do a fresh install of PW (and use the default admin theme). Then you install Admin Custom Files and check "Include theme based files" and set the folder as "AdminCustomFiles". Then uou create the folder "AdminCustomFiles" in your /site/ folder and then create a css file called AdminThemeDefault.css, and let's say you modify it so #masthead{background:red !important} It doesn't load the file. I think I know the reason... When using the default admin theme without any other admin theme installed, PW doesn't allow the option to switch admin themes per user. As a result, even though you are using the default admin theme, it's not specifically SET. Therefore, to work around this, you have to install another admin theme (like Reno), which then allows you to choose which admin theme a user can have when editing a user. After specifically setting the admin theme to default, only then does the "AdminThemeDefault.css" load. Let me know if what I stated is clear, repeatable and/or if you need a video demonstration. Jonathan
-
Good to hear. I will put together some info about the bugs. I'm planning on featuring the ProcessMigrator plugin as a general exporter/importer of content from one PW site to another. For example, let's say you have a development and production version of a site, and a new set of content needs to be created (on dev), then eventually launched (on prod). Rather than re-creating that content manually on production, I want to show how your plugin can achieve that. WordPress has an export tool, however it's very limited and doesn't work that well for the situation I described. There are some plugins to enhance it but I haven't had great success with those either. There's one commercial plugin which I haven't used but seems to be the ultimate solution to do what I described: https://crowdfavorite.com/ramp/ ProcessMigrator, in my eyes, would be the analog to RAMP.
-
@adrian How's further development going on ProcessMigrator? I was playing around with it yesterday and it seems it's still quite buggy. I tested it about 20 times on fresh installs and got a few errors which I can discuss with you. I would like to feature it in a WordPress vs. ProcessWire screencast. Your plugin solves a huge pain point. Let me know if I can help.
-
Advice on structure/build of following
Jonathan Lahijani replied to Peter Knight's topic in Getting Started
Building upon what you described in your original post and what Joss said... Templates and Relationships - bars (bars.php) - bar1 (bar.php) - bar2 (bar.php) - barN (bar.php) - chocolate types (chocolate_types.php) - chocolate_type1 (chocolate_type.php) - chocolate_type2 (chocolate_type.php) - chocolate_typeN (chocolate_type.php) - confectioners (confectioners.php) - confectioner1 (confectioner.php) - confectioner2 (confectioner.php) - confectionerN (confectioner.php) - shops (shops.php) - shop1 (shop.php) - shop2 (shop.php) - shopN (shop.php) - countries (countries.php) - country1 (country.php) - country2 (country.php) - countryN (country.php) Fields - bars (page field, multi-select asm or whatever is the most appropriate given amount of data) - chocolate_type (page field, regular select or whatever makes the most sense; i'm assuming each bar has one chocolate type) - confectioners field (page field, multi-select asm or whatever is the most appropriate given amount of data) - shops field (page field, multi-select asm or whatever is the most appropriate given amount of data) - country field (page field, regular select or whatever makes the most sense; i'm assuming each confectioner has one country) Templates w/ Fields - bar.php - title - (etc) - chocolate_type - chocolate_type.php - title - (etc) - confectioner.php - title - (etc) - bars - country - shop.php - title - (etc) - bars - country.php - title - (etc) Example Code Per Template - bars.php list bars: foreach($page->children as $bar) - chocolate_types.php list chocolate types: foreach($page->children as $chocolate_type) - confectioners.php list confectioners: foreach($page->children as $confectioner) - shops.php list shops: foreach($page->children as $shop) - countries.php list countries: foreach($page->children as $country) - chocolate_type.php list bars that have the chocolate type: $bars = $pages->find("parent=/bars/, template=bar, chocolate_type={$page}"); foreach($bars as $bar) - confectioner.php list bars: foreach($page->bars as $bar) - shop.php list bars: foreach($page->bars as $bar) - country.php list confectioners in the country: $confectioners = $pages->find("parent=/confectioners/, template=confectioner, country={$page}");