Friday, September 30, 2016

5 HDR Photos Done Right, and How to Make Your Own

Who Needs AMP? How to Lazy Load Responsive Images Quick and Easy with Layzr.js

Digital Drawing for Beginners: Before You Publish Your Drawing

Competitive Analysis: How to Find Out Who's Buying From Your Competitors

The Designer's Guide to Outsourcing Using Envato Studio & Envato Market

Character Animation: How to Animate a Backflip in Blender

Photoshop in 60 Seconds: Create a Hero Image Using Scene Generators

Get Started With Firebase for Android

Help! How to Fix Your Overheating Media-Making Mac

Thursday, September 29, 2016

Wednesday, September 28, 2016

How to Get More Views: 5 Video SEO Strategies

5 Landing Page Templates Available Now From Envato Elements

Control a Droid With Your Mind and IBM Bluemix Internet of Things

Get Started With Angular 2 and TypeScript

Digital Drawing for Beginners: From Sketching to Line Art

CSS Grid Layout: Using Grid Areas

15 Simple Invoice Templates: Made For Microsoft Word

15 Best IFTTT Recipes for Productive Business Automation

How to Create a Stylized Chalk Text Effect in Adobe Photoshop

Create a Pokémon GO Style Augmented Reality Game With Vuforia

How to Customize Your Gmail Interface Look With Themes

Particles.js: Motion and Interaction

Sympli for Developers

Now You See Me: How to Get Started With Instagram Stories

How to Create a Road Text Effect in Adobe Illustrator

Tuesday, September 27, 2016

How to Use Siri on a Mac

How to Create a Photo Collage Effect Using Photoshop Actions

Now Available: Web Templates on Envato Elements

Digital Drawing for Beginners: Before You Start Drawing

What is the Difference Between a CV vs Resume?

Improving Website Performance Through Image Optimization

10 Business Presentation Mistakes (And How to Avoid Them)

Building a Welcome Page for Your WordPress Product: Code Part 2

20 Best Minimal WordPress Themes: With Simple, Elegant Designs

How to Use Gmail Keyboard Shortcuts to Save More Time

How to Build a Striped Navigation With Flexbox

How to Build a Striped Navigation With Flexbox

Thanks to flexbox, nowadays we can build some really attractive and modern layouts with relative ease. In this tutorial we’re going to look at an interface used recently for Google National Parks, and see how flexbox can help us improve on it.

 As always, before going any further, let’s look at what we’ll be building (you may need to check out the larger version as the full effect kicks in on viewports wider than 800px):

Be sure to hover over the links to trigger the corresponding effects. 

The Markup

First, let’s examine the markup we’ll be using to build this layout. We define a div element with five links within it (you can use whichever elements you feel are appropriate). Each of our links contains a div with the class of overlay. Below you can see the skeleton of our code:

Initial CSS Styles

With the markup ready, we start defining some initial CSS styles, specifically:

  • Specify the outermost div as a flex container and set its height equal to the viewport height with height: 100vh;.
  • Set an equal width for all links (flex items). To achieve that, we give them each flex: 1. Additionally, all of our links will have a background image (sourced from unsplash.com) which covers the viewport height. As a fallback (in case an image isn’t available), we also specify a unique background color for each one.
  • When we hover over a link, its size becomes three times bigger relative to the size of the other links. We do this by changing the value of the flex property of the target link. Happily enough this property belongs to the animated CSS properties, so we’re able to generate a smooth transition effect (at least in most recent browsers). 

Here’s part of the CSS code demonstrating what we’ve described above:

So far, if we preview the demo in a browser that supports flexbox, we’ll see this result:

Styling the Overlay

Our next step is to assign a few styles to the overlay. Here’s what we’ll do:

  • Give overlay the same dimensions as the parent link. We can achieve this behavior by positioning it absolutely (relative to the immediate parent) and then specifying zero values for all the offset properties. 
  • Define the overlay as a flex container. This way, we’re able to center its direct child (i.e. .overlay-inner element) vertically and horizontally.
  • Add a semi-transparent grey background to the overlay when we hover over the parent link.

Here are the associated CSS styles:

Inner Overlay

Now, it’s time to style the inner parts of our overlay. By default these are hidden and should appear only when we hover over the corresponding parent link. But not immediately, we’ll reveal them after a small delay. This delay is important; if we don’t define it specifically, the transition effect will look a little bit ugly. Remove it and test the demo to understand what I mean. 

So just to recap, first the link gets bigger, then the overlay elements become visible. Also, we use the translate3d() to create some slide in effects. Last but not least, we use the transform-style: preserve-3d hack (or a similar one) to prevent possible flickering effects across different browsers.

And here are the related CSS styles:

Let’s see what that’s given us.


Going Responsive

The page looks great on large screens, but perhaps on small, or even on medium screens we’ll have to make a few adjustments. For example, here are a few things we can do:

  •  Flip the main-axis of the flex container by adding flex-direction: column to it. In doing so the flex items will flow from top to bottom.
  • Cancel all the transition effects and show the overlay elements by default . 

Our desktop-first media query looks as follows (I’ve used 800px only because that suits the embedded demos in this post–you can choose whatever you feel is best):

Here’s the final appearance of our navigation:

Browser Support

The demo works in all recent browsers that support flexbox. 

In some browsers you may notice that the animation of the flex property isn’t as smooth as it should be, or perhaps doesn’t work at all. For example, IE11 doesn’t animate this property, whereas Edge does. This is reasonable enough, considering the fact that flexbox is a new layout mode which is still gaining traction.

Conclusion

In this tutorial, we improved our flexbox knowledge by learning how to build a stylish navigation layout. Hopefully you enjoyed what we’ve built here and have taken some inspiration for your next projects!

If you build a similar layout, don’t forget to show us the approach (pure CSS or JavaScript-based solution) you used.  

In the Wild   

Before closing, I’d like to share with you a few sites which use a similar layout to what we’ve just created:


Building Your Startup: Exporting iCal Files into Calendar Events

How to Create a Football Text Effect in Adobe Illustrator

Monday, September 26, 2016

Master Color Correction With These Two Courses

Digital Drawing for Beginners: An Introduction to the Tools

15 Professional PowerPoint Templates - For Better Business Presentations

How to Recreate Apple TV’s Parallax Thumbnail Rollover Effect

An Introduction to the UserNotifications Framework

How to Draw a Classic Steam Locomotive From Scratch

Particles.js: Control Particle Count and Shape

How to Pick The Best Way to Print Your Photos

How to Design a Logo When You’re Short on Time!

Thursday, September 22, 2016

How to Create a Presentation From a Google Slides Theme

Photoshop in 60 Seconds: How to Properly Fill a Drawn Outline

10 Creative Presentation Ideas: That Will Inspire Your Audience to Action

How to Set Up Basic Routing in Angular 2

How to Create a 3D Black and Gold Text and Logo Mockup

Exploring Devise, Part 1

Exploring Devise, Part 1

In some of my previous articles about image uploading in Rails, I made mention of Devise but did not go deep into it. In this tutorial, I will be teaching you about Devise.

Ready? Let's get started!

Devise Introduction and Modules

Devise is an authentication solution for Rails built with Warden and provided by the awesome people at Plataformatec. Devise provides different modules:

  • Database Authenticatable: This encrypts and stores a password to the database to validate the authenticity of a user while signing in.
  • Omniauthable: This attaches OmniAuth support to Devise. Users of your application will be able to sign in using accounts such as Facebook, Twitter, and Google.
  • Confirmable: This enables the sending of emails with instructions that will help in the verification of an account.
  • Recoverable: This module helps in times when users forget their password and need to recover it. With this, the user will be able to reset the password.
  • Registerable: This handles the signup of users. It also allows users to edit and delete their accounts.
  • Rememberable: This module makes it possible for your application to remember a logged-in user by storing a cookie.
  • Trackable: This module helps track sign-in count, timestamps, and IP address.
  • Timeoutable: This module is responsible for expiring a session that has not been active for a period of time.
  • Validatable: With this module, email and password get to be validated.
  • Lockable: This provides an extra layer of security—when activated, an account can be locked after a given number of failed sign-in attempts.

Devise Integration

For the purpose of this tutorial, we are going to generate a Rails application that we'll use to check out the workings of Devise. Let's proceed!

rails new devise-app -T

The -T flag tells Rails to generate the application without the default test suite. Navigate to your application directory and drop the following gems into your Gemfile.

Now install the Devise and Bootstrap gems you just added.

bundle install

Rename your app/assets/stylesheets/application.css file to app/assets/stylesheets/application.scss and add the following lines in it:

Open up the app/assets/javascripts/application.js file and require bootstrap-sprockets. Mine looks like this:

Next, you need to run the Rails command to install the configuration files for Devise. You do so by running this command:

rails generate devise:install

The command generates the following on your terminal. You should read it to understand what happened.

The command also generates two files, which you can find in the config directory. It also gives us some instructions on what we should do.

Navigate to your application layout, app/views/layouts/application.html.erb, and make it look like what I have below:

You need to define the default URL options for your development environment. Add the code below in config/environments/development.rb.

Now you need to create a User model for Devise. You can do so using your terminal.

rails generate devise User

This will generate a user.rb file in your app/models directory. The file generated will look like this:

You can see that it contains the default modules I mentioned above. The command you ran also modified your config/routes.rb file by adding a route for devise. You should check that out.

At this point, you need to migrate your database. You do so by running: 

rake db:migrate

Authentication Using Devise

Now you need to create a PagesController and wrap Devise authentication around it—this will prevent unauthorized persons from seeing the page.

rails generate controller Pages index

Open up your routes file and set the root of your application.

Open up your PagesController and add authentication for your index and new pages.

The code shows that the index and new pages are accessible only to registered users. Open up your terminal and start your rails server. Point your browser to http://localhost:3000 and you will automatically be redirected to the Devise sign-in page.

Signing in Without Using Email

The default means of signing into Devise involves the use of email address and password. What if you want to enable users to sign in with their unique username? If that is what you want, it is possible. Let's see how.

Run the command:

rails generate migration AddUsernameToUSers username:string

This will add a new column for username in your users table. Migrate your database.

rake db:migrate

You need to add a field to your views where your users can enter their username. When you go to your app/views directory, you will not find any file that renders the Devise views. This is because Devise loads the views from its gemset. To customize it, you have to generate copies of the views. The command below does the magic.

rails generate devise:views

This will generate some folders and files in your app/views directory.

You will need to edit the page for signing in, signing up, and updating user information. Just paste the blocks of code below into their respective files.

Sign-Up

Edit

Sign-In

Using your text editor, navigate to app/controllers/application_controller.rb. You need to modify it to permit the use of username. Modify it to look like this:

Now a user can sign in with his/her username. At this point there is something not right about your application. When a user signs in, there is no way of signing out. This does not result in a great user experience. I'll show you how to fix that.

From your terminal, create a new directory called shared in your app/views folder.

The file you created above is a partial where the code for your navigation bar will be written. Drop in the following code.

Now you need to render the navigation bar in your application layout. Open up app/views/layouts/application.html.erb and drop in the code to render your navigation bar.

Conclusion

In this part you learned how to install Devise and add authentication to your pages. I also made mention of a partial. I will cover that in a separate tutorial. 

In the next part, we will cover some areas more advanced than this. I hope this was worth your time!


Creating Custom WordPress Administration Pages, Part 3

CSS Grid Layout: Fluid Columns and Better Gutters

CSS Grid Layout: Fluid Columns and Better Gutters

In this tutorial we’re going to take the grid from our previous tutorial and use it as a playground to explore different units of measurement and Grid’s properties. 

Flexible Units

The whole point of Grid is to enable us to properly control layout on the web, so let’s make our static grid fluid before we go any further. If you recall, we were defining our grid with static pixel measurements:

It’s quite possible to use other units here too, such as ems, or rems for example. Or even more unusual units like vh and vmin

In this case we’re going to change our pixel units for percentages. As we’re defining our column widths and our gutter widths manually we have to make sure the total values equal 100%:

Mind the Gap

There does exist a newer, more efficient way to declare gutter measurements, and that’s with a purpose-made property. We can use grid-column-gap and grid-row-gap, or the shorthand grid-gap property instead. 

Using this means we no longer need to include grid tracks to accommodate our gutters, we only need to declare the columns and rows, so in our case that means three of each:

Hmm, that’s a bit messy, but it sort of does the job. The difference you’ll notice is that the column widths now add up to 100%; our gutters will actually be subtracted from them automatically. 

Repeat

Let’s write this is a neater way, using the repeat() function:

This states “repeat 33.33% three times” giving us three columns. And we don’t even need the grid-template-rows declaration because the auto value is assigned as default anyway. Now we just need to state how big we want our gutters:

grid-gap will accept fixed or flexible units, which means we can perfectly combine fluid columns and fixed gutters without any complex calculations on our part.

Resetting Our grid-column and grid-row Values

Something is amiss: we still have a load of grid-column and grid-row declarations on our grid items, but they’re all wrong because we no longer have as many grid tracks. Happily, because we’re using grid-gap to define our gutters, we can leave positioning of the items to automatic placement–items will no longer fall into the gutters. For now, remove all the positioning:

The fr Unit

One final improvement can be made to our simple grid; we’re going to introduce the fr, or fraction unit. A single fr unit describes “one piece of however many pieces we’re splitting this into”. For example, we could declare our columns using:

Here there’s a total of three fr units, so each column would be one third wide. Here’s another example:

Now there’s a total of four fr units, so the first column would take up half the available width, with the other two columns each taking a quarter.

These units are really powerful, especially in combination with other units of measurement:

Here we’ve declared four columns: 

  • the first is fixed at 300px wide
  • the last is a flexible 20% of the grid container element wide
  • then the fr units are calculated, leaving the second column with one piece of the remaining space
  • and the third with three pieces.

It looks like this, perfectly highlighting auto-placement as our nine items shift to fill the gaps:

But back to our original grid. Let’s replace the clumsy and inaccurate 33.33% value with 1fr: 

Finished pen:

Conclusion

So, to recap:

  1. Grid will accept flexible units in combination with fixed units of measurements.
  2. We needn’t declare gutters within our grid-template, we can use the grid-gap properties instead.
  3. grid-gap means we are less bound to positioning our grid items–we can hand more responsibility over to auto-placement.
  4. The repeat() function will save us time and keep our stylesheets maintainable.
  5. The fr, or fraction unit is a very powerful way of describing grid templates.

We’ve come a long way in just two tutorials, but you’re now the proud owner of a very neat and concise grid! In the next tutorial we’ll explore grid areas, taking a look at the span keyword and some practical layouts.

Useful Resources


How to Create a Set of Retro Media Icons in Affinity Designer

How to Organize Your Pictures for Free With Daminion

Sunday, September 18, 2016

Bearded_Foodies You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Mrsyedwaseem You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

celestegau83 You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

ewposters You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

vinn_oliveira You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

lavaneradi You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Yssa_xoxo You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

GrafficT You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

menmybrand You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

mlsitess You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

siddhshanidham You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

SheannSheann You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

RubyLibHunt You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

pdamindanuwan You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

anamartinez_lan You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

MedAbderrahim12 You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Huang_Cloud001 You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Jean07za You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Lalithgc You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

_IDNews You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Oseiphilip125 You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

narendrasawalk8 You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

felicitysofts You’re smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

RT TheEconomist: The dangerous rise of antibiotic resistance will lead to the resurgence of old diseases … https://t.co/gQdXPrazT8


from Twitter https://twitter.com/devwebbest

RT Global_Policy: Future Demagogues? Powerful Individuals in a Globalized World #Zuckerberg #Schmidt #Musk #Kalani… https://t.co/m4gAYRS048


from Twitter https://twitter.com/devwebbest

RT michaeldweiss: Compensation payments same news cycle as UN confirms Assad gassing people is inconvenience to th… https://t.co/jROcZv2NE8


from Twitter https://twitter.com/devwebbest

RT irinnews: The refugee crisis in Europe has largely disappeared from our screens, but it isn't over: … https://t.co/CeoueFkEMI


from Twitter https://twitter.com/devwebbest

RT LSEReviewBooks: 'Bursting with memorable anecdotes, intriguing detail and splashes of colour' … https://t.co/r1lPwNJame


from Twitter https://twitter.com/devwebbest

RT TheStudyofWar: Syrian Military Begins to Withdraw From Vital Aleppo Road - ABC News - https://t.co/ieZybJlujW … https://t.co/PP96kV3p4F


from Twitter https://twitter.com/devwebbest

RT BenParker140: How Europe is splitting the bill on refugees: https://t.co/UHrjh1sScD https://t.co/H7zQ5NJ0VU


from Twitter https://twitter.com/devwebbest

RT ipinst: "Peace cuts across every global issue"- #IPI's hillarysaviello at #PeaceDay Youth Summit- … https://t.co/2OZEmQou58


from Twitter https://twitter.com/devwebbest

RT issafrica: Top view | UN #DemocracyDay: Africa has little to celebrate. https://t.co/Tod2Umq8Jl https://t.co/vwNAlPnWHZ


from Twitter https://twitter.com/devwebbest

RT CrisisGroup: Any sustainable solution to the global refugee crisis must address conflict prevention https://t.co/hmd4JjFwi2 #UN4Refugee…


from Twitter https://twitter.com/devwebbest

RT issafrica: Top read | #Zimbabwe's reforms: An exercise in credibility - or pretence? https://t.co/twCGjlPBbG https://t.co/foZK2pP3xF


from Twitter https://twitter.com/devwebbest

RT GlobPeaceIndex: POSITIVE PEACE: How can we establish peacefulness at home and around the world? #peace https://t.co/oAhv6uaORa


from Twitter https://twitter.com/devwebbest

RT issafrica: Top read | #Africa has suffered a number of blows against #democracy. https://t.co/Tod2Umq8Jl https://t.co/RPZa2Fu6DD


from Twitter https://twitter.com/devwebbest

RT Carnegie_Europe: Ahead of tomorrow's #UN4RefugeesMigrants, check out Carnegie's best analysis on #migration: … https://t.co/1hxBu4w864


from Twitter https://twitter.com/devwebbest

RT TheStudyofWar: .karendeyoung1 quotes GEN Votel from our conference-"Trust deficit w/#Russia." #ISWInsight. … https://t.co/lUivjceMlE


from Twitter https://twitter.com/devwebbest

RT WarOnTheRocks: Do you think the CIA knew about the Turkish coup attempt ahead of time? Then read about this https://t.co/bIXr9W9LJx


from Twitter https://twitter.com/devwebbest

RT keohanedan: The remaining 27 can no longer blame the UK for any lack of progress on EU defense policy. … https://t.co/NMdqbAW5K0


from Twitter https://twitter.com/devwebbest

Saturday, September 17, 2016

velasqueziris60 You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

zovlqa You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

sweetrevengebtq You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

shawneks1 You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

masterkeyhelene You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

projx2go You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Super_johnmike You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

shevenszheng You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

GwynethCheever You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

danthonyl You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

⌘ #RWD websites w/ a strong point of view: https://t.co/lnoPOmAtvj https://t.co/PrdFH7Ez5k … https://t.co/OoDOVdLXCs


from Twitter https://twitter.com/devwebbest

WhyNotDoStuff Thanks Alec, what a lovely example!


from Twitter https://twitter.com/devwebbest

sarah_edo Please keep me posted ;-)


from Twitter https://twitter.com/devwebbest

Trying desperately to find a landing page which doesn’t use Parallax, but rather quirky layouts and illustrations. And failing.


from Twitter https://twitter.com/devwebbest

A fast, responsive search/filters interface done really well. NYC Schoolfinder. https://t.co/2k2VhHKWM6 #rwd https://t.co/fPxweg066U


from Twitter https://twitter.com/devwebbest

Stuurmen by StuurmenFrank - Featured cssawards https://t.co/widEAOmBd7 #webdesign #css https://t.co/ivjYJy5scg


from Twitter https://twitter.com/devwebbest

GIMEZ by awdagency - #SOTD cssawards https://t.co/6OWnyz40WE #webdesign #onepage https://t.co/PmANb8JlvD


from Twitter https://twitter.com/devwebbest

React Container Query for container queries with, well, React. https://t.co/njLi7XSCGM


from Twitter https://twitter.com/devwebbest

Emoji Printer, for creating Emoji-based posters. notwaldorf would approve. https://t.co/Rez7rDkjkz (via jvegis) https://t.co/Jy3kCKynPJ


from Twitter https://twitter.com/devwebbest

sebarh Thanks Sebastian!


from Twitter https://twitter.com/devwebbest

RT RWD: Need to demo/test a locally-built site on various devices? https://t.co/7XFhYww5Uw looks like a great opt… https://t.co/vx4SNiokOi)


from Twitter https://twitter.com/devwebbest

JayUny It doesn’t count! :-)


from Twitter https://twitter.com/devwebbest

Any suggestions for responsive designs in Japan, Russia or South America? URLs are welcome!


from Twitter https://twitter.com/devwebbest

What are some of the most memorable websites you’ve seen lately? (Responsive, art-directed, done well?) #rwd


from Twitter https://twitter.com/devwebbest

RT RWD: Ever wanted to display the right mobile keyboard for numeric inputs? filamentgroup has you covered: https://t.co/2fDBWnc3zo


from Twitter https://twitter.com/devwebbest

RT lukew: links matter https://t.co/AYt7BIr0Si


from Twitter https://twitter.com/devwebbest

ebrunborg Arriving on Sunday. Evening dinner? ;-)


from Twitter https://twitter.com/devwebbest

Don't mind the URL. A[dult] swim singles 2016. 25 weeks, 25 tracks. Visualized. Well done. https://t.co/W4mgtVVWIX https://t.co/XO3yyRIdPj


from Twitter https://twitter.com/devwebbest

Good weekend reading: On Onboarding (and a few other books). Email/sharing is required. https://t.co/Jd6VAVJNCK https://t.co/APdd6ra49Q


from Twitter https://twitter.com/devwebbest

Articles on #security-related, #InternationalRelations (IR) & #HumanSecurity that are evergreen and global in sco… https://t.co/mfJA3Jb5QG


from Twitter https://twitter.com/devwebbest

Friday, September 16, 2016

NCPtour_travel You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

happyesthete You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

onebusinessguru You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

odf_group You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

greatdigitsol You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

ktfarnan You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

LJBPR You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Porkchops_tees You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

smartstitching3 You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

OnesTopAppSol You’re quite smashing! ;) Why not subscribe to our newsletter, with handy tips'n'tricks (1-click)? https://t.co/BNh5FgpB9j


from Twitter https://twitter.com/devwebbest

Malarkey snookca Good point, Andy! indysigner? ;-)


from Twitter https://twitter.com/devwebbest

Do #water-centered #US NGOs need a global Water Grand Strategy? PeterEngelke1 & P Michel say yes https://t.co/phAWktRqs7 AtlanticCouncil


from Twitter https://twitter.com/devwebbest

How to Create a Futuristic Racing Illustration in Sketch

Have you switched to HTTP/2 yet? If not, why not?


from Twitter https://twitter.com/devwebbest

✎ It’s Friday, so let’s... draw! Some hand lettering inspiration on smashingmag. https://t.co/uURu1z2wCw https://t.co/4y86woGPsZ


from Twitter https://twitter.com/devwebbest

Android From Scratch: Firebase Crash Reporting

What #counterterrorism & #IntelligenceGathering developments have occurred since 9/11? See here https://t.co/krMnBF532C cc CFR_org


from Twitter https://twitter.com/devwebbest

Losing Sirte was far from a fatal blow to the #Islamic State in #Libya, says the CSS’ Lisa Watanabe https://t.co/Mb3QOF6wEi #Terrorism


from Twitter https://twitter.com/devwebbest

The Enhanced Script Notifications in OpenCart 2.2.x.x

The Enhanced Script Notifications in OpenCart 2.2.x.x

Today, we’re going to discuss one of the coolest features of OpenCart—script notifications. Although they've been available since the release of OpenCart 2.x version, they've been enhanced in the recent release of OpenCart 2.2.x.x. Throughout the course of this tutorial, we’ll discuss the concept and demonstrate it by creating a working module.

Introduction

As a developer, you'll often need to alter the flow of the core framework behaviour, whether it’s to add a new feature to the framework or to enhance the existing workflow. In either case, you need to have control over the workflow so that you can hook into the functionality and achieve the desired behavior.

Let’s try to understand it by a simple example. If you’re running a popular online store, chances are that the most popular products of your store will be sold out soon. In this case, it would be nice to get a notification about it and take the proper action accordingly.

So what you could do in the aforementioned example is to look for the method that's called when the order is placed. Next, you can hook into the order creation flow so that you can control when the order is placed. That allows you to execute a random piece of code in the context of the called event. That's where event notifications come into the picture, allowing us run arbitrary code and modify the resulting outcome.

What Are Script Notifications?

As per the official OpenCart documentation:

In 2.2+ we have added a new events system, these are hooks that can be called before and after events such as a controller method call, model method call or templates being loaded. They give the ability to manipulate the input method parameters and returned output.

That's really powerful, as you could literally hook into any method call and change the output returned by that method. However, you should be careful during the implementation of hooks, if you're taking the responsibility of modifying the resulting output of the call. That's because if your implementation returns any value, it will stop any other event actions that are set to be called.

What does it take to implement script notifications? Here are the necessary steps:

Register Your Event

When you're registering your event with OpenCart, you're telling OpenCart that you want to monitor xyz action, and if that happens please execute the foo action in the bar controller file. While doing so, you have two options to choose from—before and after.

If you choose the before option, OpenCart will run the foo action before the action that's being monitored, and in the case of the after option it'll execute foo after the action. In the case of the before option, it's important to note that if the foo method returns anything, OpenCart won't execute the original method code that's being monitored at all.

Later in this article, we'll see how to register an event during custom module implementation.

Implement the Target Action

Next, you'll need to implement the controller and the corresponding action method that's been associated with an event in the first step. That's the place where your custom code should go in. OpenCart sends context-specific arguments to your foo method, so that you could use it if needed.

So that’s just a glimpse of what script notifications are capable of.

Do We Still Need OCMOD?

If you're familiar with either vQmod or OCMOD, chances are that you're going to roll up your sleeves against the event notifications feature. After all, you could achieve everything by the aforementioned goodies that you would have anyway accomplished with event notifications.

For those who are not familiar with either vQmod or OCMOD, listed below are nice introductory articles that explain it.

So, the question is, if you could use either vQmod or OCMOD to alter the core files, why would you use script notifications? It’s because of the fact that there may be multiple OCMOD plugins trying to alter the same code, and that could result in conflict. In the case of events, there’s no chance of conflict as each event is executed in a specific order.

So the conclusion is that if it’s possible to use events, go for that. On the other hand, if you feel that there’s no event available for your use-case, it’s completely fine to go with OCMOD.

Create a Back-End Module

In this section, we're going to build a module that demonstrates how to use event notifications in OpenCart. I assume that you're aware of the basic module development process in OpenCart, as we'll skid through the basics. If you're not aware of it, here's a nice article that you can go through quickly.

Let's understand the use-case before we go ahead and implement it. Assume that you have a store that fetches the catalog information from the third-party API back-end. You've set up a cron that regularly fetches the information and inserts it in the OpenCart database, so that it can be displayed in the front-end. Although you've set up a cron that updates the information at regular intervals, you want to make sure that the information displayed in the front-end must be in real time.

In the front-end, OpenCart calls the getProduct function when it displays the product detail page. So, that's the ideal candidate for you to hook into and update the database if the API information has changed.

So let's start creating the back-end files first.

Go ahead and create the admin/controller/module/demoevent.php file with the following contents.

As we discussed earlier, the first thing you would like to do is the registration of the event. It's the install hook that we'll use to do it, as it'll be executed when the module is installed.

We've used the addEvent method of the event model under the extension directory, and that method has three arguments.

The first argument, event_product_info, is the name of the event. You could name it anything, but make sure that it's unique.

The second argument is very important, and it points out to the method that you would like to hook into. In our case, we have to choose the getProduct method of the Product Model under the Catalog directory. So the hierarchy is model/catalog/product/getProduct. In addition to that, it should be prefixed by either catalog or admin, which stands for the application. In our case, it's catalog as we're hooking into the front-end method. Finally, it'll be post-fixed by either before or after, which tells OpenCart to run our code accordingly.

The third argument points to the action of your controller that will be triggered when the event is fired. It's set to custom/product/info, so you'll have to create a Product controller with the info method under the custom directory, as we'll do in a moment.

Finally, the uninstall method is used to remove the event during the uninstallation of the module.

Next, let's create a language file for our custom module at admin/language/en-gb/module/demoevent.php with the following contents.

We've finished with the back-end file setup. Now, you should be able to see our module listed under Extensions > Modules in the back-end of OpenCart. Go ahead and install it. Now, we'll go ahead and create the files in the front-end.

Create a model file catalog/model/custom/product.php with the following contents. It's a typical model file as per the OpenCart structure.

It implements two important methods. The getProductLastModifiedInfo method is used to fetch the last modified date of the product, and the updateProductInfo method is used to update the product information in the database. In a moment, we'll see how these methods will be used.

Finally, let's create one of the most important files of this article, catalog/controller/custom/product.php, with the following contents. It's a controller file that implements the info action method that is set to be called when the getProduct method of the Product Model is called.

The important thing to note here is that OpenCart provides context-specific arguments to your method. The first $route argument tells you the route associated with the event that has been triggered. In our case, it should be catalog/product/getProduct. The second argument is the product id as it's a required argument by the actual getProduct method.

The logic is something like this: we'll compare the modified date of the product in the OpenCart database with the information that's returned by the API callback.

So the first step is to load the real-time product information from the API. Please note that the api_call_to_fetch_product_info method is just a dummy method that you would like to replace with your actual API call.

Next, we use the getProductLastModifiedInfo method, which was created in the earlier section, to fetch the modified date of the product from the OpenCart database.

Finally, we do the comparison, and if the date differs, it'll update the OpenCart database with the latest product information using the updateProductInfo method in our Model class.

We've also returned the product information in array format in the same way the actual getProduct would have returned. It's important to note that as we've provided the return value in our hook, it won't call any further event calls including the call to the original getProduct method as well.

So, in this way you could influence the execution flow in OpenCart. It's a really powerful way to alter the core functionality. However, you should be careful while approaching this solution as it gives you total control to change the resulting output of any method.

Conclusion

Today, we've discussed one of the exciting features in OpenCart called script notifications. We started with an introduction to the subject, and it was the latter half of the article that demonstrated how to use them by building a custom event module.

As always, if you're looking for additional OpenCart tools, utilities, extensions, and so on that you can leverage in your own projects or for your own education, don't forget to see what we have available in the marketplace.

Queries and comments are always welcome!