20+ Online Ad Banner (Maker) Template Designs to Customise Now

Post pobrano z: 20+ Online Ad Banner (Maker) Template Designs to Customise Now

If you’re just getting into online advertising or hoping to boost your online traffic with better advertisements, ad banners are the way to go. 

Ad banners are currently one of the most ubiquitous forms of marketing used on the internet. Companies use them for everything from raising their brand profile to increasing engagement, announcing discounts, and promoting products. They provide an affordable, effective and measurable method to successfully target your ideal audience.  

But what exactly is an ad banner? An ad banner, also called a banner ad or a web banner, is essentially an advertisement consisting of an image with text or a multimedia object that is displayed on a selected web page. It works in much the same way as a physical banner alerting you to a discount on a specific product in a store would entice you to take a closer look and maybe buy the product. 

The sole purpose of an ad banner, therefore, is to catch the eye of visitors on a host website and get them interested enough to click the ad banner, which will take them to the advertiser’s website where the advertiser will try to close the deal. 

7 Components of a Compelling Banner Design

Compelling Web Banner Design

The million dollar question, then, is how do you create a web banner that will attract your ideal customer/client and cause them to click through to your website? First, you need to understand what makes a successful ad banner. 

Before I begin, I want to remind you to KISS. That’s right, Keep It Simple Sunshine. Newbies to design often labour under the mistaken notion that they need to add loads of stuff to make their design effective. But with all design, including ad banner design, your best strategy should be to use a few key elements well. Remember, viewers are probably only going to glance at your web banner for a nanosecond, so you need to focus on making a few elements stand out rather than packing your ad with everything but the kitchen sink.

1. Get Your Dimensions Right 

According to Google AdSense, the most successful standard banner sizes are:

  • 728×90px — Leaderboard
  • 300×600px — Half Page
  • 336×280px — Large Rectangle
  • 300×250px — Medium Rectangle
Top performing ad sizes from Google

We’ll talk about this a bit more later, but for now it’s something for you to be aware of and keep in mind. 

2. Incorporate Your Brand 

Your ad banner is an extension of your company, so its design should be consistent with your company’s brand identity. This means you need to build an ad banner that incorporates your company’s logo, font styles, colour scheme and general style so that when your prospective client/customer clicks through from the ad banner to the dedicated landing page you’ve created for your offer, they’ll feel confident that they’re in the right place because the two will match each other.

3. Make Your Heading the Centre of Attention 

Your ad banner heading needs to be the first thing that your target audience will see, so it’s got to catch their attention with its colour, size, and message. At first glance, it should tell your audience what your ad is about, and it should entice them to keep reading, e.g. „Valentine’s Day Sale”.

4. Use Subtitles Smartly 

This is not always necessary, but if you use secondary text, it should be smaller or a lighter font weight than your heading text, easily readable, and less than ten words. It should give just enough information to get the readers interested and leave them wanting more, e.g. „50% off all items”.

Compelling Banner Design

5. A Picture Is Worth a Thousand Words 

Of course, this doesn’t mean you always have to use images, but if you do, they should be beautiful, luscious images that complement your message and are relevant to your product. 

6. Don’t Forget a 'Call to Action’ Button 

Every banner needs a 'call to action’ button. This is a button with text like ‘Buy Now’, ‘Shop Now’, ‘Enter to win’, etc. that makes the reader act by clicking the button. 

7. Smaller Is Better  

… when it comes to the size of your files, that is. According to Google Ads, your ad file needs to be under 150 KB so that it loads fast on the page before viewers scroll down and miss it entirely. 

Use an Online Banner Maker 

Now, the next thing you need to consider is how to put these elements all together to create an effective design. 

This can be a tall order if you’re not a seasoned designer, but don’t worry—we’ve got two great resources for all you novices out there to help you make the perfect ad banner. These will also work for seasoned designers who need to turn over a project quickly and don’t have the time to create a design from scratch. 

The first is a terrific banner maker app by Placeit. 

Online Banner Maker

This online banner generator offers hundreds of affordable banner design templates that help you make compelling banners quickly and painlessly. But the thing I love the most about this ad creator is that you can enter your headline, subtitle and call to action in the header, and the banner maker app will show you how your specific text looks on all the banner design templates on offer. Totally cool and amazing! Let me show you what I mean. 

How to Use Banner Design Templates

Let’s say you want to create a stunning ad banner design to advertise a New Year’s Sale. All you need to do is follow these simple steps to have your own great banner ready in minutes.

1. Navigate to the Banner Maker at Placeit. 

Sign up for FREE!

2. Fill in the Text Bars at the Top of the Page 

Enter your text in the Heading, Subtitle, and Call to Action bars. Notice that if you can’t come up with a call to action, this online ad creator provides a number of prompts for you. 

Online Banner Maker

As an example, I’ve entered information for a New Year Sale for a fictitious clothing shop client. As you can see in the image below, all the banner templates update with the information I’ve added.

Online Banner Maker

3. Select a Banner Design Template

Peruse the banner ad templates, and when you see a banner design you like and that is appropriate for your business, double-click on it. This will open it up in the custom banner maker.

Online Banner Maker

4. Customise Your Banner Template 

Starting with the controls on the left and working your way down from the top, you can modify your text and change the font style and colour to match your brand. I’m happy with the font style as it matches the brand of my fictitious client, but I changed the colour from red to orange to match their brand. 

Now let’s move to the controls on the right and work from the top. Remember earlier I mentioned that there were four ad banner dimensions that according to Google AdSense work the best? Well, at the very top right of the custom banner maker, you can change your ad banner dimensions from the default 1080x1080px to any dimension you require. I changed mine to the medium rectangle size of 300×250px. 

I then changed the colour of the lines sandwiching „New Year’s Sale”. I changed the button design and colour again to correspond with my fictional client’s brand. I kept the image of the model for the same reason—it corresponded with my client’s brand image. 

Online Banner Maker

Scrolling down the page, you have two additional options. If you get stuck while you’re customising your design, you can try one of the presets on offer. They are all different versions of the banner template you chose and can help you see how your template would look with different settings applied. 

Online Banner Maker

Alternatively, just below the presets, you can see your selected colours and text applied to different banner design templates for more design inspiration.

Online Banner Maker

5. Download Your Banner Design

Once you’re satisfied with your design, hit the Download button at the top of the screen and download your banner design for a small fee. Alternatively, if you regularly need to create ad banners, flyers, posters, social media banners etc., then the monthly plan may be the best deal for you.

Online Banner Maker

20 Best Banner Design Templates

Now that you know how easy it is to use the online banner maker, these 20 best web banner designs will get you even more excited about creating your own banner. 

1. Home Design Store Banner Ad Maker

Home Design Store Banner Ad Maker

Customise this gorgeous Home Design Store Banner Ad Maker template by uploading photos from your own home design portfolio and promote your business on websites your ideal customers frequent. The template offers all sorts of features like beautiful gradient overlays and fantastic frames for dividing up the banner space in different ways. 

2. Banner Generator for Wedding Planners

Home Design Store Banner Ad Maker

Capture the romance and whimsy of a wedding with the Banner Generator for Wedding Planners. The template offers beautiful photos and graphics, and you can even change the dimensions to fit perfectly in Instagram posts. 

3. Online Banner Maker for Discount Eyewear

Online Banner Maker for Discount Eyewear

Use this funky web banner design to entice customers to pop on over to your online eyewear shop and browse your merchandise. The template uses playful illustrations of frames and loads of cool graphics, and it even offers a space to add a promotion code. 

4. Banner Maker for Grocery Stores

Banner Maker for Grocery Stores

Whether you’re selling eggs, meat, or fresh fruit and vegetables, the Banner Maker for Grocery Stores template offers an exciting array of alluring images to hook your potential customers. Combine them with the wonderful hand-drawn icons and the large array of stylish and modern fonts on offer, and you have everything you need to create a knock-out web banner design.

5. Ad Banner Maker for an Online Clothing Sale

Ad Banner Maker for an Online Clothing Sale

A great half-page banner template, the Ad Banner Maker for an Online Clothing Sale template is perfect for showing off your clothing photos and creating a bold modern banner for any website.

6. Banner Maker for Furniture Store Promo Codes

Banner Maker for Furniture Store Promo Codes

The Banner Maker for Furniture Store Promo Codes uses a minimalist approach to web banner design. Using a strong, appealing photo, a beautiful cursive font in the header, and a bold, modern font for the call to action button, the template is an ode to the power of simplicity. 

7. Online Banner Maker for Ice Cream Shops

Online Banner Maker for Ice Cream Shops

If you run an ice-cream business, this is the banner template for you, but really it’s also a great web banner design for any number of businesses. Select one of their tantalising images or upload one of your own, promise a giveaway, and watch the customers roll in. 

8. Summer Online Banner Maker

Summer Online Banner Maker

Summer Online Banner Maker is a light and playful banner template that uses illustration and fun background elements to reference the joy of summer while enticing visitors to click the call to action button and join the fun.  

9. Home Care Online Banner Maker

Home Care Online Banner Maker

Looking for a great banner template to drum up business for a home care business? Check out the Home Care Online Banner Maker template. It’s simple, customisable, and can also be adapted to create a social media banner. 

10. Ad Banner Template for Furniture Store Giveaway

Ad Banner Template for Furniture Store Giveaway

Another excellent furniture store banner template from the banner generator, Ad Banner Template for Furniture Store Giveaway is an elegant, eye-catching way to grab your prospective clients’ attention, thanks to its prominent image overlaid with creative fonts.

11. Online Banner Ad Maker for Travel Agency

Online Banner Ad Maker for Travel Agency

The banner you create for your travel agency needs to inspire wanderlust. The Online Banner Ad Maker for Travel Agency template will do just that with its choice of beautiful images from around the world. It’s easy to customise with your brand fonts and colours using the super online banner maker controls.

12. Camera Giveaway Ad Banner Make

Camera Giveaway Ad Banner Make

Another great example of a half-page banner template, the Camera Giveaway Ad Banner Maker uses images of a range of cameras and lenses. And, of course, the banner creator helps you modify your template so that it’ll be ready to add to your ad campaign in no time. 

13. Ad Banner Creator for Store Sales

Ad Banner Creator for Store Sales

With its cool black and white images and strong modern fonts, this ad banner uses a very specific aesthetic to communicate polish and sophistication. Ad Banner Creator for Store Sales is a great banner template for brands that sell classic and timeless clothing. 

14. Custom Promotional Online Banner Maker

Custom Promotional Online Banner Maker

Another great banner template that uses fabulous illustration and playful text, Custom Promotional Online Banner Maker is a great reminder that offering stuff for free is a great way to get clicks. Just make sure that the freebie is an example of the fantastic products you offer, and you’ll probably gain a loyal customer.

15. Vertical Online Banner Maker

 Vertical Online Banner Maker

A great way to attract clicks is to ask more questions than you answer. Is this a conceptual art piece? Am I going to get an extra 30% off a cool piece of furniture or a ginormous pink balloon? How could you not click to find out? 

16. Minimal Discount Online Banner Maker

Minimal Discount Online Banner Maker

Minimal Discount Online Banner Maker carries minimalism to the next level. The web banner design rests heavily on the magnetism of the images provided (or the images you upload) and the power of one large badge that rests in the lower right corner of the banner. This badge acts as the banner’s text box and button as well. You can add your header text or a call to action, but whatever you do, make it irresistible.

17. Ad Maker for Art Supplies Shop

Ad Maker for Art Supplies Shop

Promoting your art supply business online is a cinch with the Ad Maker for Art Supplies Shop template. The template offers lots of fun art-inspired graphics, and you can make it as colourful and playful as you like.

18. Black Friday Sales Online Banner Template

Black Friday Sales Online Banner Template

Another great banner ad template that uses gorgeous black and white photos and strong modern text, Black Friday Sales Online Banner Template is a clean and alluring template that your target audience won’t be able to resist. 

19. Christmas Sale Ad Generator

Christmas Sale Ad Generator

Since Christmas comes every year, it’s always a good idea to have the Christmas Sale Ad Generator template on standby for when you need it. It’s a versatile template that can be used for a wide variety of businesses and customised to reflect your particular brand. 

20. 50% Off Shoes Ad Banner Template

50 Off Shoes Ad Banner Template

A beautifully designed banner targeting shoe shops but ideal for a variety of merchandise, the wonderful 50% Off Shoes Ad Banner Template is a joy to use. You can add photos of your own merchandise, change the background colour of the right side of the banner, and add a wide variety of fun graphics and effects or upload your own. 

More Terrific Banner Design Templates

Now let’s move to the second great resource for web banner design, Envato Elements. 

These banner ad templates are more suitable for those who have some knowledge of Adobe Photoshop and Illustrator. If that’s you then head on over to Elements and take a look at their terrific banner templates. Here are just a few to whet your appetite. 

Corporate Banners

This eye-catching collection of corporate banner design templates is perfect for small and medium businesses who may not have a budget to hire a designer. The pack contains 10 creative layouts designed with Adobe Photoshop. The layered PSD files are easy to customise with editable text and fully scalable vector shapes. 

Banner Ad Templates

New Year Offer Ad Banner

This collection of 25 banner ad templates is designed to fit Google’s recommended sizes for online ad banners. The PSD files are provided in well-organised layers for easy and targeted customisation. The templates also use smart objects and vector shapes that can be scaled and customised to fit your needs. A really versatile and useful collection. 

Banner Ad Templates

Web Design Banner Ads

These three sets of web banner design templates contain three of the four most successful standard banner sizes—the half page, leaderboard, and large rectangle—which can be scaled down to fulfil the fourth most successful standard banner size, the medium rectangle. As is the case with all the templates found at Envato Elements, the PSD files contained in the template can all be customised to suit your needs.

Banner Ad Templates

These are just a small sample of the thousands of web banner designs to be found at Envato Elements, and you can download as many as you like for one affordable price. What’s also great is that the price also gives you access to thousands of other creative graphics and templates that you can also use as often as you like. Now that’s a deal that’s hard to beat!

Select Your Favourite Custom Banner Maker 

This is just a small sample of the terrific banner templates you can customise and download at both Placeit and Envato Elements. If you haven’t found just the right one for you here, head on over to both sites and have a browse. I just know there’s a web banner design there you can use to take your business to the heights you and it deserve. And be sure to let us know what you think of our list and if you’ve found a banner template you just can’t do without. Looking forward to hearing all about it. 

By the way, if you’re looking for a YouTube channel banner template, a Facebook banner template, or any other social media banner template, check out last week’s article, 20+ Social Media Image Maker Templates for Instagram, Facebook + More. Have a read—you won’t be disappointed. 

How to Turn a Photo Into Art by Creating a Painting Photoshop Action

Post pobrano z: How to Turn a Photo Into Art by Creating a Painting Photoshop Action

Final product image
What You’ll Be Creating

In this tutorial, you will learn how to turn a photo into art. I will explain everything in so much detail that everyone can create the effect, even those who have just opened Photoshop for the first time.

The effect shown above is the one I will show you how to create in this tutorial. If you would like to create the even more advanced photo art effect shown below, using just a single click and in only a few minutes, then check out my Paint Photoshop Action.

Action final result

What You’ll Need

To recreate the design above, you will need the following resources:

1. How to Start Creating an Action

Step 1

First, open the photo that you want to work with. To open your photo, go to File > Open, choose your photo, and click Open. Now, before we get started, just check a couple of things:

  1. Your photo should be in RGB Color mode, 8 Bits/Channel. To check this, go to Image > Mode.
  2. For best results, your photo size should be 2000–3500 px wide/high. To check this, go to Image > Image Size.
  3. Your photo should be the Background layer. If it is not, go to Layer > New > Background from Layer.
Checking image size and mode

Step 2

If you have changed the image size in the previous step, in the History panel, click on the camera icon to create a new snapshot. Then, set the Snapshot 1 as the source of the history brush tool.

Creating new snapshot

2. How to Create the Painting Effect

Step 1

In this section, we are going to create the painting effect. Go to Layer > New > Layer to create a new layer and name it Painting_Large_Details.

Creating new layer

Step 2

Now choose the Art History Brush Tool (Y), and set the Area to 500 px, Tolerance to 0 px, and Style to Tight Long. Then, pick a soft brush, set the Diameter to 20 px, and brush over the whole photo.

Brushing into layer

Step 3

Go to Layer > New > Layer to create a new layer and name it Painting_Large_Details.

Creating new layer

Step 4

Now choose the Art History Brush Tool (Y), and set the Area to 500 px, Tolerance to 0 px, and Style to Tight Long. Then, pick a soft brush, set the Diameter to 10 px, and brush over the whole photo.

Brushing into layer

Step 5

Go to Layer > Layer Mask > Hide All to add a layer mask that hides the whole layer.

Adding layer mask

Step 6

Now set the foreground color to #000000, choose the Brush Tool (B), pick a soft brush, and brush over the area where you want more details to appear. Feel free to use different brush sizes.

Brushing into layer mask

Step 7

Go to Layer > New > Layer to create a new layer and name it Painting_Small_Details.

Creating new layer

Step 8

Now choose the Art History Brush Tool (Y), and set the Area to 500 px, Tolerance to 0 px, and Style to Tight Long. Then, pick a soft brush, set the Diameter to 5 px, and brush over the whole photo.

Brushing into layer

Step 9

Go to Layer > Layer Mask > Hide All to add a layer mask that hides the whole layer.

Adding layer mask

Step 10

Now set the foreground color to #000000, choose the Brush Tool (B), pick a soft brush, and brush over the area where you want more details to appear. Feel free to use different brush sizes.

Brushing into mask

3. How to Create the Emboss Effect

Step 1

In this section, we are going to create the emboss effect. Press Control-Alt-Shift-E on your keyboard to make a screenshot, and then press Control-Shift-U to desaturate this layer.

Making screenshot

Step 2

Go to Filter > Stylize > Emboss and set the Angle to 135°, Height to 3 px, and Amount to 200%.

Adding emboss filter

Step 3

Now change the Blending Mode of this layer to Hard Light, and name it Emboss Effect.

Changing blending mode

You Made It!

Congratulations, you have succeeded! Here is our final result:

Final result

If you would like to create the even more advanced photo art effect
shown below, using just a single click and in only a few minutes, then
check out my Paint Photoshop Action.

The action will create amazing, realistic painting photo effects from your photos with no work at all from your side! You just open your photo and play the action. It’s really that simple! The action
will do all the work for you, leaving you fully layered and customizable
results that you can further modify.

The action also creates ten preset color looks and five overlay textures that you can
choose from.

The action comes with a detailed video tutorial that demonstrates how to use the action and customize the results to get the most out of the effect.

Action final result

You may also like:

How to Turn a Photo Into Art by Creating a Painting Photoshop Action

Post pobrano z: How to Turn a Photo Into Art by Creating a Painting Photoshop Action

Final product image
What You’ll Be Creating

In this tutorial, you will learn how to turn a photo into art. I will explain everything in so much detail that everyone can create the effect, even those who have just opened Photoshop for the first time.

The effect shown above is the one I will show you how to create in this tutorial. If you would like to create the even more advanced photo art effect shown below, using just a single click and in only a few minutes, then check out my Paint Photoshop Action.

Action final result

What You’ll Need

To recreate the design above, you will need the following resources:

1. How to Start Creating an Action

Step 1

First, open the photo that you want to work with. To open your photo, go to File > Open, choose your photo, and click Open. Now, before we get started, just check a couple of things:

  1. Your photo should be in RGB Color mode, 8 Bits/Channel. To check this, go to Image > Mode.
  2. For best results, your photo size should be 2000–3500 px wide/high. To check this, go to Image > Image Size.
  3. Your photo should be the Background layer. If it is not, go to Layer > New > Background from Layer.
Checking image size and mode

Step 2

If you have changed the image size in the previous step, in the History panel, click on the camera icon to create a new snapshot. Then, set the Snapshot 1 as the source of the history brush tool.

Creating new snapshot

2. How to Create the Painting Effect

Step 1

In this section, we are going to create the painting effect. Go to Layer > New > Layer to create a new layer and name it Painting_Large_Details.

Creating new layer

Step 2

Now choose the Art History Brush Tool (Y), and set the Area to 500 px, Tolerance to 0 px, and Style to Tight Long. Then, pick a soft brush, set the Diameter to 20 px, and brush over the whole photo.

Brushing into layer

Step 3

Go to Layer > New > Layer to create a new layer and name it Painting_Large_Details.

Creating new layer

Step 4

Now choose the Art History Brush Tool (Y), and set the Area to 500 px, Tolerance to 0 px, and Style to Tight Long. Then, pick a soft brush, set the Diameter to 10 px, and brush over the whole photo.

Brushing into layer

Step 5

Go to Layer > Layer Mask > Hide All to add a layer mask that hides the whole layer.

Adding layer mask

Step 6

Now set the foreground color to #000000, choose the Brush Tool (B), pick a soft brush, and brush over the area where you want more details to appear. Feel free to use different brush sizes.

Brushing into layer mask

Step 7

Go to Layer > New > Layer to create a new layer and name it Painting_Small_Details.

Creating new layer

Step 8

Now choose the Art History Brush Tool (Y), and set the Area to 500 px, Tolerance to 0 px, and Style to Tight Long. Then, pick a soft brush, set the Diameter to 5 px, and brush over the whole photo.

Brushing into layer

Step 9

Go to Layer > Layer Mask > Hide All to add a layer mask that hides the whole layer.

Adding layer mask

Step 10

Now set the foreground color to #000000, choose the Brush Tool (B), pick a soft brush, and brush over the area where you want more details to appear. Feel free to use different brush sizes.

Brushing into mask

3. How to Create the Emboss Effect

Step 1

In this section, we are going to create the emboss effect. Press Control-Alt-Shift-E on your keyboard to make a screenshot, and then press Control-Shift-U to desaturate this layer.

Making screenshot

Step 2

Go to Filter > Stylize > Emboss and set the Angle to 135°, Height to 3 px, and Amount to 200%.

Adding emboss filter

Step 3

Now change the Blending Mode of this layer to Hard Light, and name it Emboss Effect.

Changing blending mode

You Made It!

Congratulations, you have succeeded! Here is our final result:

Final result

If you would like to create the even more advanced photo art effect
shown below, using just a single click and in only a few minutes, then
check out my Paint Photoshop Action.

The action will create amazing, realistic painting photo effects from your photos with no work at all from your side! You just open your photo and play the action. It’s really that simple! The action
will do all the work for you, leaving you fully layered and customizable
results that you can further modify.

The action also creates ten preset color looks and five overlay textures that you can
choose from.

The action comes with a detailed video tutorial that demonstrates how to use the action and customize the results to get the most out of the effect.

Action final result

You may also like:

30 Noteworthy Drawings Of Fan Art

Post pobrano z: 30 Noteworthy Drawings Of Fan Art

Fan-Art is a broad category of art that includes any visual artwork inspired by a work of fiction you like, such as an anime, television show, a novel series, or comic book. Making fan-art is a great way to show your love of a character or series, and practice your drawing skills. There are some fantastic fan artworks, which I believe, would have made any of the characters I’m about to show you appear even more awesome. These fan arts are inspired by numerous genres, and there are some which might have been the outcome of a lot of hard work, and that is why they look vastly different from their movie appearance. 

 So I gathered 30 Fan-Art pieces that are worthy of a look. Just make sure to click the images to support these artists.  

NIMROD 🙂

Leslie Rosique

Julio Lopez

Vicente Valentine

Creon Chkn

Walther Art

Aleksey Rico

Kenneth Hallberg Faigh

NIMROD 🙂

Vicente Valentine

NIMROD 🙂

AMTS creation

Dorota Lamackova

Denis Zhbankov

Paul Tinker

Leandro Cruz

Phil Dunne

Tim Mack

Walther Art

HEY BRO

MUTI

Julio César Melo

Valeria Abatzoglu

Renato Giacomini

Pius Bak

Vicente Valentine

toni infante

El Mehdi Rahif

Beñat Olea Irureta

Rafa Miqueleto

ETH Zurich Foundation: Waiter, Bicycle Courier, Pizza Delivery Man

Post pobrano z: ETH Zurich Foundation: Waiter, Bicycle Courier, Pizza Delivery Man
Print
ETH Zurich Foundation

Brilliant minds shouldn’t be distracted from their studies by part-time jobs.

The ETH Zurich is one of the most renowned universities in the world. Each year, the 50 most outstanding science students receive financial support through the ETH Excellence Scholarship Programme. This allows them to concentrate solely on their master’s degrees and ensures they have the time they need to carry out excellent research. The ETH Excellence Scholarships are funded by donations. The campaign uses the example of the famous ETH graduate Albert Einstein to show how paradox it would be, if brilliant minds were distracted from their studies by part-time jobs. Albert Einstein studied at the ETH Zurich from 1896 to 1900. After publishing his Theory of Relativity in 1905, he taught here from 1912 to 1914 as a professor of theoretical physics.

Advertising Agency:Ruf Lanz, Zurich, Switzerland
Creative Directors:Markus Ruf, Danielle Lanz
Art Direction:Isabelle Hauser
Copywriters:Andreas Hornung, Markus Ruf, Christian Stüdi
Graphic Designers:Philipp Tschirren, Armin Arnold
Account Executive:Marc Gooch
Photographer:Jonathan Heyer
Photographer Assistant:Oliver Schwarz
Production:All in Productions
Producers:Dhondup Tersey, Aliza Eva Berger, Yangdon Nesar
Styling:Nicole Knupfer
Post Production:Aschmann Klauser

ETH Zurich Foundation: Waiter, Bicycle Courier, Pizza Delivery Man

Post pobrano z: ETH Zurich Foundation: Waiter, Bicycle Courier, Pizza Delivery Man
Print
ETH Zurich Foundation

Brilliant minds shouldn’t be distracted from their studies by part-time jobs.

The ETH Zurich is one of the most renowned universities in the world. Each year, the 50 most outstanding science students receive financial support through the ETH Excellence Scholarship Programme. This allows them to concentrate solely on their master’s degrees and ensures they have the time they need to carry out excellent research. The ETH Excellence Scholarships are funded by donations. The campaign uses the example of the famous ETH graduate Albert Einstein to show how paradox it would be, if brilliant minds were distracted from their studies by part-time jobs. Albert Einstein studied at the ETH Zurich from 1896 to 1900. After publishing his Theory of Relativity in 1905, he taught here from 1912 to 1914 as a professor of theoretical physics.

Advertising Agency:Ruf Lanz, Zurich, Switzerland
Creative Directors:Markus Ruf, Danielle Lanz
Art Direction:Isabelle Hauser
Copywriters:Andreas Hornung, Markus Ruf, Christian Stüdi
Graphic Designers:Philipp Tschirren, Armin Arnold
Account Executive:Marc Gooch
Photographer:Jonathan Heyer
Photographer Assistant:Oliver Schwarz
Production:All in Productions
Producers:Dhondup Tersey, Aliza Eva Berger, Yangdon Nesar
Styling:Nicole Knupfer
Post Production:Aschmann Klauser

ETH Zurich Foundation: Waiter, Bicycle Courier, Pizza Delivery Man

Post pobrano z: ETH Zurich Foundation: Waiter, Bicycle Courier, Pizza Delivery Man
Print
ETH Zurich Foundation

Brilliant minds shouldn’t be distracted from their studies by part-time jobs.

The ETH Zurich is one of the most renowned universities in the world. Each year, the 50 most outstanding science students receive financial support through the ETH Excellence Scholarship Programme. This allows them to concentrate solely on their master’s degrees and ensures they have the time they need to carry out excellent research. The ETH Excellence Scholarships are funded by donations. The campaign uses the example of the famous ETH graduate Albert Einstein to show how paradox it would be, if brilliant minds were distracted from their studies by part-time jobs. Albert Einstein studied at the ETH Zurich from 1896 to 1900. After publishing his Theory of Relativity in 1905, he taught here from 1912 to 1914 as a professor of theoretical physics.

Advertising Agency:Ruf Lanz, Zurich, Switzerland
Creative Directors:Markus Ruf, Danielle Lanz
Art Direction:Isabelle Hauser
Copywriters:Andreas Hornung, Markus Ruf, Christian Stüdi
Graphic Designers:Philipp Tschirren, Armin Arnold
Account Executive:Marc Gooch
Photographer:Jonathan Heyer
Photographer Assistant:Oliver Schwarz
Production:All in Productions
Producers:Dhondup Tersey, Aliza Eva Berger, Yangdon Nesar
Styling:Nicole Knupfer
Post Production:Aschmann Klauser

The Dark and Colorful Art of Michael Reeder

Post pobrano z: The Dark and Colorful Art of Michael Reeder

There is something Klimt-esque about Reeder’s art. The mix of realistic faces and skulls in black and white with bold colors, patterns, and geometric shapes, gives life to a type of street art nouveau.

Based in Dallas, Texas, Michael Reeder was influenced from early on by street art. Although he still creates murals, his work has evolved into something different that you can discover on this post or on his website.

The Dark and Colorful Art of Michael Reeder

Post pobrano z: The Dark and Colorful Art of Michael Reeder

There is something Klimt-esque about Reeder’s art. The mix of realistic faces and skulls in black and white with bold colors, patterns, and geometric shapes, gives life to a type of street art nouveau.

Based in Dallas, Texas, Michael Reeder was influenced from early on by street art. Although he still creates murals, his work has evolved into something different that you can discover on this post or on his website.

Gulp for WordPress: Creating the Tasks

Post pobrano z: Gulp for WordPress: Creating the Tasks

This is the second post in a two-part series about creating a Gulp workflow for WordPress theme development. Part one focused on the initial installation, setup, and organization of Gulp in a WordPress theme project. This post goes deep into the tasks Gulp will run by breaking down what each task does and how to tailor them to streamline theme development.

Now that we spent the first part of this series setting up a WordPress theme project with Grunt installed in it, it’s time to dive into the tasks we want it to do for us as we develop the theme. We’re going to get our hands extremely dirty in this post, get ready to write some code!

Article Series:

  1. Initial Setup
  2. Creating the Tasks (This Post)

Creating the style task

Let’s start by compiling src/bundle.scss from Sass to CSS, then minifying the CSS output for production mode and putting the completed bundle.css file into the dist directory.

We’re going to use a couple of Gulp plugins to do the heavy lifting. We’ll use gulp-sass to compile things and gulp-clean-css to minify. Then, gulp-if will allow us to conditionally run functions which, In our case, will check if we are in production or development modes before those tasks run and then execute accordingly.

We can install all three plugins in one fell swoop:

npm install --save-dev gulp-sass gulp-clean-css gulp-if

Let’s make sure we have something in our bundle.scss file so we can test the tasks:

$colour: #f03;

body {
  background-color: $colour;
}

Alright, back to the Gulpfile to import the plugins and define the task that runs them:

import { src, dest } from 'gulp';
import yargs from 'yargs';
import sass from 'gulp-sass';
import cleanCss from 'gulp-clean-css';
import gulpif from 'gulp-if';
const PRODUCTION = yargs.argv.prod;

export const styles = () => {
  return src('src/scss/bundle.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpif(PRODUCTION, cleanCss({compatibility:'ie8'})))
    .pipe(dest('dist/css'));
}

Let’s walk through this code to explain what’s happening.

  • The src and dest functions are imported from Gulp. src will read the file that you pass as an argument and return a node stream.
  • We pull in yargs to create our flag that separates tasks between the development and production modes.
  • The three plugins are called into action.
  • The PRODUCTION flag is defined and held in the prod command.
  • We define styles as the task name we will use to run these tasks in the command line.
  • We tell the task what file we want processed (bundle.scss) and where it lives (src/scss/bundle.scss).
  • We create „pipes” that serve as the plungs that run when the styles command is executed. Those pipes run in the order they are written: convert Sass to CSS, minify the CSS (if we’re in production), and place the resulting CSS file into the dist/css directory.

Go ahead. Run gulp styles in the command line and see that a new CSS file has been added to your CSS directory dist/css.

Now do gulp styles --prod. The same thing happens, but now that CSS file has been minified for production use.

Now, assuming you have a functioning WordPress theme with header.php and footer.php, the CSS file (as well as JavaScript files when we get to those tasks) can be safely enqueued, likely in your functions.php file:

function _themename_assets() {
  wp_enqueue_style( '_themename-stylesheet', get_template_directory_uri() . '/dist/css/bundle.css', array(), '1.0.0', 'all' );
}
add_action('wp_enqueue_scripts', '_themename_assets');

That’s all good, but we can make our style command even better.

For example, try inspecting the body on the homepage with the WordPress theme active. The styles that we added should be there:

As you can see, it says that our style is coming from bundle.css, which is true. However, it would be much better if the name of the original SCSS file is displayed here instead for our development purposes — it makes it so much easier to locate code, particularly when we’re working with a ton of partials. This is where source maps come into play. That will detail the location of our styles in DevTools. To further illustrate this issue, let’s also add some SCSS inside src/scss/components/slider.scss and then import this file in bundle.scss.

//src/scss/components/slider.scss
body {
  background-color: aqua;
}
//src/scss/bundle.scss
@import './components/slider.scss';
$colour: #f03;
body {
  background-color: $colour;
}

Run gulp styles again to recompile your files. Your inspector should then look like this:

The DevTools inspector will show that both styles are coming from bundle.css. But we would like it to show the original file instead (i.e bundle.scss and slider.scss). So let’s add that to our wish list of improvements before we get to the code.

The other thing we’ll want is vendor prefixing to be handled for us. There’s nothing worse than having to write and manage all of those on our own, and Autoprefixer is the tool that can do it for us.

And, in order for Autoprefixer to work its magic, we’ll need the PostCSS plugin.

OK, that adds up to three more plugins and tasks we need to run. Let’s install all three:

npm install --save-dev gulp-sourcemaps gulp-postcss autoprefixer

So gulp-sourcemaps will obviously be used for sourcemaps. gulp-postcss and autoprefixer will be used to add autoprefixing to our CSS. postcss is a famous plugin for transforming CSS files and autoprefixer is just a plugin for postcss. You can read more about the other things that you can do with postcss here.

Now at the very top let’s import our plugins into the Gulpfile:

import postcss from 'gulp-postcss';
import sourcemaps from 'gulp-sourcemaps';
import autoprefixer from 'autoprefixer';

And then let’s update the task to use these plugins:

export const styles = () => {
  return src('src/scss/bundle.scss')
    .pipe(gulpif(!PRODUCTION, sourcemaps.init()))
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpif(PRODUCTION, postcss([ autoprefixer ])))
    .pipe(gulpif(PRODUCTION, cleanCss({compatibility:'ie8'})))
    .pipe(gulpif(!PRODUCTION, sourcemaps.write()))
    .pipe(dest('dist/css'));
}

To use the the sourcemaps plugin we have to follow some steps:

  1. First, we initialize the plugin using sourcemaps.init().
  2. Next, pipe all the plugins that you would like to map.
  3. Finally, Create the source map file by calling sourcemaps.write() just before writing the bundle to the destination.

Note that all the plugins piped between sourcemaps.init() and sourcemaps.write() should be compatible with gulp-sourcemaps. In our case, we are using sass(), postcss() and cleanCss() and all of them are compatible with sourcemaps.

Notice that we only run the Autoprefixer begind the production flag since there’s really no need for all those vendor prefixes during development.

Let’s run gulp styles now, without the production flag. Here’s the output in bundle.css:

body {
  background-color: aqua; }
body {
  background-color: #f03; }
/*#sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVuZGxlLmNzcyIsInNvdXJjZXMiOlsiYnVuZGxlLnNjc3MiLCJjb21wb25lbnRzL3NsaWRlci5zY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIkBpbXBvcnQgJy4vY29tcG9uZW50cy9zbGlkZXIuc2Nzcyc7XG5cbiRjb2xvdXI6ICNmMDM7XG5ib2R5IHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3VyO1xufVxuOjpwbGFjZWhvbGRlciB7XG4gICAgY29sb3I6IGdyYXk7XG59IiwiYm9keSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogYXF1YTtcbn0iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFDQUEsQUFBQSxJQUFJLENBQUM7RUFDRCxnQkFBZ0IsRUFBRSxJQUFJLEdBQ3pCOztBRENELEFBQUEsSUFBSSxDQUFDO0VBQ0QsZ0JBQWdCLEVBRlgsSUFBSSxHQUdaOztBQUNELEFBQUEsYUFBYSxDQUFDO0VBQ1YsS0FBSyxFQUFFLElBQUksR0FDZCJ9 */#

The extra text below is source maps. Now, when we inspect the site in DevTools, we see:

Nice! Now onto production mode:

gulp styles --prod

Check DevTools against style rules that require prefixing (e.g. display: grid;) and confirm those are all there. And make sure that your file is minified as well.

One final notice for this task. Let’s assume we want multiple CSS bundles: one for front-end styles and one for WordPress admin styles. We can create add a new admin.scss file in the src/scss directory and pass an array of paths in the Gulpfile:

export const styles = () => {
  return src(['src/scss/bundle.scss', 'src/scss/admin.scss'])
    .pipe(gulpif(!PRODUCTION, sourcemaps.init()))
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpif(PRODUCTION, postcss([ autoprefixer ])))
    .pipe(gulpif(PRODUCTION, cleanCss({compatibility:'ie8'})))
    .pipe(gulpif(!PRODUCTION, sourcemaps.write()))
    .pipe(dest('dist/css'));
}

Now we have bundle.css and admin.css in the dist/css directory. Just make sure to properly enqueue any new bundles that are separated out like this.

Creating the watch task

Alright, next up is the watch task, which makes our life so much easier by looking for files with saved changes, then executing tasks on our behalf without have to call them ourselves in the command line. How great is that?

Like we did for the styles task:

import { src, dest, watch } from 'gulp';

We’ll call the new task watchForChanges:

export const watchForChanges = () => {
  watch('src/scss/**/*.scss', styles);
}

Note that watch is unavailable as a name since we already have a variable using it.

Now let’s run gulp watchForChanges the command line will be on a constant, ongoing watch for changes in any .scss files inside the src/scss directory. And, when those changes happen, the styles task will run right away with no further action on our part.

Note that src/scss/**/*.scss is a glob pattern. That basically means that this string will match any .scss file inside the src/scss directory or any sub-folder in it. Right now, we are only watching for .scss files and running the styles task. Later, we’ll expand its scope to watch for other files as well.

Creating the images task

As we covered earlier, the images task will compress images in src/images and then move them to dist/images. Let’s install a gulp plugin that will be responsible for compressing images:

npm install --save-dev gulp-imagemin

Now, import this plugin at the top of the Gulpfile:

import imagemin from 'gulp-imagemin';

And finally, let’s write our images task:

export const images = () => {
  return src('src/images/**/*.{jpg,jpeg,png,svg,gif}')
    .pipe(gulpif(PRODUCTION, imagemin()))
    .pipe(dest('dist/images'));
}

We give the src() function a glob that matches all .jpg, .jpeg, .png, .svg and .gif images in the src/images directory. Then, we run the imagemin plugin, but only for production. Compressing images can take some time and isn’t necessary during development, so we can leave it out of the development flow. Finally, we put the compressed versions of images in dist/images.

Now any images that we drop into src/images will be copied when we run gulp images. However, running gulp images --prod, will both compress and copy the image over.

Last thing we need to do is modify our watchForChanges task to include images in its watch:

export const watchForChanges = () => {
  watch('src/scss/**/*.scss', styles);
  watch('src/images/**/*.{jpg,jpeg,png,svg,gif}', images);
}

Now, assuming the watchForChanges task is running, the images task will be run automatically whenever we add an image to the src/images folder. It does all the lifting for us!

Important: If the watchForChanges task is running and when the Gulpfile is modified, it will need to be stopped and restarted in order for the changes to take effect.

Creating the copy task

You probably have been in situations where you’ve created files, processed them, then needed to manually grab the production files and put them where they need to be. Well, as we saw in the images task, we can use the copy feature to do this for us and help prevent moving wrong files.

export const copy = () => {
  return src(['src/**/*','!src/{images,js,scss}','!src/{images,js,scss}/**/*'])
    .pipe(dest('dist'));
}

Try to read the array of paths supplied to src() carefully. We are telling Gulp to match all files and folders inside src (src/**/*), except the images, js and scss folders (!src/{images,js,scss}) and any of the files or sub-folders inside them (!src/{images,js,scss}/**/*).

We want our watch task to look for these changes as well, so we’ll add it to the mix:

export const watchForChanges = () => {
  watch('src/scss/**/*.scss', styles);
  watch('src/images/**/*.{jpg,jpeg,png,svg,gif}', images);
  watch(['src/**/*','!src/{images,js,scss}','!src/{images,js,scss}/**/*'], copy);
}

Try adding any file or folder to the src directory and it should be copied over to the the /dist directory. If, however, we were to add a file or folder inside of /images, /js or /scss, it would be ignored since we already handle these folders in separate tasks.

We still have a problem here though. Try to delete the added file and it won’t happen. Our task only handles copying. This problem could also happen for our /images, /js and /scss, folders. If we have old images or JavaScript and CSS bundles that were removed from the src folder, then they won’t get removed from the dist folder. Therefore, it’s a good idea to completely clean the dist folder every time to start developing or building a theme. And that’s what we are going to do in the next task.

Composing tasks for developing and building

Let’s now install a package that will be responsible for deleting the dist folder. This package is called del:

npm install --save-dev del

Import it at the top:

import del from 'del';

Create a task that will delete the dist folder:

export const clean = () => {
  return del(['dist']);
}

Notice that del returns a promise. Thus, we don’t have to call the cb() function. Using the new JavaScript features allows us to refactor this to:

export const clean = () => del(['dist']);

The folder should be deleted now when running gulp clean. What we need to do next is delete the dist folder, run the images, copy and styles tasks, and finally watch for changes every time we start developing. This can be done by running gulp clean, gulp images, gulp styles, gulp copy and then gulp watch. But, of course, we will not do that manually. Gulp has a couple of functions that will help us compose tasks. So, let’s import these functions from Gulp:

import { src, dest, watch, series, parallel } from 'gulp';

series() will take some tasks as arguments and run them in series (one after another). And parallel() will take tasks as arguments and run them all at once. Let’s create two new tasks by composing the tasks that we already created:

export const dev = series(clean, parallel(styles, images, copy), watchForChanges)
export const build = series(clean, parallel(styles, images, copy))
export default dev;

Both tasks will do the exact same thing: clean the dist folder, then styles, images and copy will run in parallel one the cleaning is complete. We will start watching for changes as well for the dev (short for develop) task, after these parallel tasks. Additionally, we are also exporting dev as the default task.

Notice that when we run the build task, we want our files to be minified, images to be compressed, and so on. So, when we run this command, we will have to add the --prod flag. Since this can easily be forgotten when running the build task, we can use npm scripts to create aliases for the dev and build commands. Let’s go to package.json, and in the scripts field, we will probably find something like this:

"scripts": {
  "test": "echo "Error: no test specified" && exit 1"
}

Let’s change it to this:

"scripts": {
  "start": "gulp",
  "build": "gulp build --prod"
},

This will allow us to run npm run start in the command line, which will go to the scripts field and find what command corresponds to start. In our case, start will run gulp and gulp will run the default gulp task, which is dev. Similarly, npm run build will run gulp build --prod. This way, we can completely forget about the --prod flag and also forget about running the Gulp tasks using the gulp command. Of course, our dev and build commands will do more than that later on, but for now, we have the foundation that we will work with throughout the rest of the tasks.

Creating the scripts task

As mentioned, in order to bundle our JavaScript files, we are going to need a module bundler. webpack is the most famous option out there, however it is not a Gulp plugin. Rather, it’s a plugin on its own that has a completely separate setup and configuration file. Luckily, there is a package called webpack-stream that helps us use webpack within a Gulp task. So, let’s install this package:

npm install --save-dev webpack-stream

webpack works with something called loaders. Loaders are responsible for transforming files in webpack. And to transform new Javascript versions into ES5, we will need a loader called babel-loader. We will also need @babel/preset-env but we already installed this earlier:

npm install --save-dev babel-loader

Let’s import webpack-stream at the top of the Gulpfile:

import webpack from 'webpack-stream';

Also, to test our task, lets add these lines in src/js/bundle.js and src/js/components/slider.js:

// bundle.js
import './components/slider';
console.log('bundle');


// slider.js
console.log('slider')

Our scripts task will finally look like so:

export const scripts = () => {
  return src('src/js/bundle.js')
  .pipe(webpack({
    module: {
      rules: [
        {
          test: /\.js$/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: []
            }
          }
        }
      ]
    },
    mode: PRODUCTION ? 'production' : 'development',
    devtool: !PRODUCTION ? 'inline-source-map' : false,
    output: {
      filename: 'bundle.js'
    },
  }))
  .pipe(dest('dist/js'));
}

Let’s break this down a bit:

  • First, we specify bundle.js as our entry point in the src() function.
  • Then, we pipe the webpack plugin and specify some options for it.
  • The rules field in the module option lets webpack know what loaders to use in order to transform our files. In our case we need to transform JavaScript files using the babel-loader.
  • The mode option is either production or development. For development, webpack will not minify the output JavaScript bundle, but it will for production. Therefore, we don’t need a separate Gulp plugin to minify JavaScript because webpack can do that depending on our PRODUCTION constant.
  • The devtool option will add source maps, but not in production. In development, however, we will use inline-source-maps. This kind of source maps is the most accurate though it can be a bit slow to create. If you find it too slow, check the other options here. They won’t be as accurate as inline-source-maps but they can be pretty fast.
  • Finally, the output option can specify some information about the output file. In our case, we only need to change the filename. If we don’t specify the filename, webpack will generate a bundle with a hash as the filename. Read more about these options here.

Now we should be able to run gulp scripts and gulp scripts --prod and see a bundle.js file created in dist/js. Make sure that minification and source maps are working properly. Let’s now enqueue our JavaScript file in WordPress, which can be in the theme’s functions.php file, or wherever you write your functions.

<?php
function _themename_assets() {
  wp_enqueue_style( '_themename-stylesheet', get_template_directory_uri() . '/dist/css/bundle.css', array(), '1.0.0', 'all' );
  
  wp_enqueue_script( '_themename-scripts', get_template_directory_uri() . '/dist/assets/js/bundle.js', array(), '1.0.0', true );
}
add_action('wp_enqueue_scripts', '_themename_assets');

Now, looking at the console, let’s confirm that source maps are working correctly by checking the file that the console logs come from:

Without the source maps, both logs will appear coming from bundle.js.

What if we would like to create multiple JavaScript bundles the same way we do for the styles? Let’s create a file called admin.js in src/js. You might think that we can simply change the entry point in the src() to an array like so:

export const scripts = () => {
  return src(['src/js/bundle.js','src/js/admin.js'])
  .
  .
}

However, this will not work. webpack works a bit differently that normal Gulp plugins. What we did above will still create one file called bundle.js in the dist folder. webpack-stream provides a couple of solutions for creating multiple entry points. I chose to use the second solution since it will allow us to create multiple bundles by passing an array to the src() the same way we did for the styles. This will require us to install vinyl-named:

npm install --save-dev vinyl-named

Import it:

import named from 'vinyl-named';

…and then update the scripts task:

export const scripts = () => {
  return src(['src/js/bundle.js','src/js/admin.js'])
  .pipe(named())
  .pipe(webpack({
    module: {
      rules: [
        {
          test: /\.js$/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env']
            }
          }
        }
      ]
    },
    mode: PRODUCTION ? 'production' : 'development',
    devtool: !PRODUCTION ? 'inline-source-map' : false,
    output: {
      filename: '[name].js'
    },
  }))
  .pipe(dest('dist/js'));
}

The only difference is that we now have an array in the src(). We then pipe the named plugin before webpack, which allows us to use a [name] placeholder in the output field’s filename instead of hardcoding the file name directly. After running the task, we get two bundles in dist/js.

Another feature that webpack provides is using libraries from external sources rather than bundling them into the final bundle. For example, let’s say your bundle needs to use jQuery. You can run npm install jquery --save and then import it to your bundle import $ from 'jquery'. However, this will increase the bundle size and, in some cases, you may already have jQuery loaded via a CDN or — in case of WordPress — it can exist as a dependency like so:

wp_enqueue_script( '_themename-scripts', get_template_directory_uri() . '/dist/assets/js/bundle.js', array('jquery'), '1.0.0', true );

So, now WordPress will enqueue jQuery using a normal script tag. How can we then use it inside our bundle using import $ from 'jquery'? The answer is by using webpack’s externals option. Let’s modify our scripts task to add it in:

export const scripts = () => {
  return src(['src/js/bundle.js','src/js/admin.js'])
    .pipe(named())
    .pipe(webpack({
      module: {
        rules: [
          {
            test: /\.js$/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: []
            }
          }
        }
      ]
    },
    mode: PRODUCTION ? 'production' : 'development',
    devtool: !PRODUCTION ? 'inline-source-map' : false,
    output: {
      filename: '[name].js'
    },
    externals: {
      jquery: 'jQuery'
    },
  }))
  .pipe(dest('dist/js'));
}

In the externals option, jquery is the key that identifies the name of the library we want to import. In our case, it will be import $ from 'jquery'. And the value jQuery is the name of a global variable where that the library lives. Now try to import $ from ‘jquery’ in the bundle and use jQuery using the $ — it should work perfectly.

Let’s watch for changes for JavaScript files as well:

export const watchForChanges = () => {
  watch('src/scss/**/*.scss', styles);
  watch('src/images/**/*.{jpg,jpeg,png,svg,gif}', images);
  watch(['src/**/*','!src/{images,js,scss}','!src/{images,js,scss}/**/*'], copy);
  watch('src/js/**/*.js', scripts);
}

And, finally, add our scripts task in the dev and build tasks:

export const dev = series(clean, parallel(styles, images, copy, scripts), watchForChanges);
export const build = series(clean, parallel(styles, images, copy, scripts));

Refreshing the browser with Browsersync

Let’s now improve our watch task by installing Browsersync, a plugin that refreshes the browser each time tasks finish running.

npm install browser-sync gulp --save-dev

As usual, let’s import it:

import browserSync from "browser-sync";

Next, we will initialize a Browsersync server and write two new tasks:

const server = browserSync.create();
export const serve = done => {
  server.init({
    proxy: "http://localhost/yourFolderName" // put your local website link here
  });
  done();
};
export const reload = done => {
  server.reload();
  done();
};

In order to control the browser using Browsersync, we have to initialize a Browsersync server. This is different from a local server where WordPresss would typically live. the first task is serve, which starts the Browsersync server, and is pointed to our local WordPress server using the proxy option. The second task will simply reload the browser.

Now we need to run this server when we are developing our theme. We can add the serve task to the dev series tasks:

export const dev = series(clean, parallel(styles, images, copy, scripts), serve, watchForChanges);

Now run npm start and the browser should open up a new URL that’s different than the original one. This URL is the one that Browsersync will refresh. Now let’s use the reload task to reload the browser once tasks are done:

export const watchForChanges = () => {
  watch('src/scss/**/*.scss', series(styles, reload));
  watch('src/images/**/*.{jpg,jpeg,png,svg,gif}', series(images, reload));
  watch(['src/**/*','!src/{images,js,scss}','!src/{images,js,scss}/**/*'], series(copy, reload));
  watch('src/js/**/*.js', series(scripts, reload));
  watch("**/*.php", reload);
}

As you can see, we added a new line to run the reload task every time a PHP file changes. We are also using series() to wait for our styles, images, scripts and copy tasks to finish before reloading the browser. Now, run npm start and change something in a Sass file. The browser should reload automatically and changes should be reflected after refresh once the tasks have finished running.

Don’t see CSS or JavaScript changes after refresh? Make sure caching is disabled in your browser’s inspector.

We can make even one more improvement to the styles tasks. Browsersync allows us to inject CSS directly to the page without even having to reload the browser. And this can be done by adding server.stream() at the very end of the styles task:

export const styles = () => {
  return src(['src/scss/bundle.scss', 'src/scss/admin.scss'])
    .pipe(gulpif(!PRODUCTION, sourcemaps.init()))
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpif(PRODUCTION, postcss([ autoprefixer ])))
    .pipe(gulpif(PRODUCTION, cleanCss({compatibility:'ie8'})))
    .pipe(gulpif(!PRODUCTION, sourcemaps.write()))
    .pipe(dest('dist/css'))
    .pipe(server.stream());
}

Now, in the watchForChanges task, we won’t have to reload for the styles task any more, so let’s remove the reload task from it:

export const watchForChanges = () => {
  watch('src/scss/**/*.scss', styles);
  .
  .
}

Make sure to stop watchForChanges if it’s already running and then run it again. Try to modify any file in the scss folder and the changes should appear immediately in the browser without even reloading.

Packaging the theme in a ZIP file

WordPress themes are generally packaged up as a ZIP file that can be installed directly in the WordPress admin. We can create a task that will take the required theme files and ZIP them up for us. To do that we need to install another Gulp plugin: gulp-zip.

npm install --save-dev gulp-zip

And, as always, import it at the top:

import zip from "gulp-zip";

Let’s also import the JSON object in the package.json file. We need that in order to grab the name of the package which is also the name of our theme:

import info from "./package.json";

Now, let’s write our task:

export const compress = () => {
return src([
  "**/*",
  "!node_modules{,/**}",
  "!bundled{,/**}",
  "!src{,/**}",
  "!.babelrc",
  "!.gitignore",
  "!gulpfile.babel.js",
  "!package.json",
  "!package-lock.json",
  ])
  .pipe(zip(`${info.name}.zip`))
  .pipe(dest('bundled'));
};

We are passing the src() the files and folders that we need to compress, which is basically all files and folders (**/), except a few specific types of files, which are preceded by !. Next, we are piping the gulp-zip plugin and calling the file the name of the theme from the package.json file (info.name). The result is a fresh ZIP file an a new folder called bundled.

Try running gulp compress and make sure it all works. Open up the generated ZIP file and make sure that it only contains the files and folders needed to run the theme.

Normally, though, we only need to ZIP things up *after* the theme files have been built. So let’s add the compress task to the build task so it only runs when we need it:

export const build = series(clean, parallel(styles, images, copy, scripts), compress);

Running npm run build should now run all of our tasks in production mode.

Replacing the placeholder prefix in the ZIP file

One step we need to do before zipping our files is to scan them and replace the themename placeholder with the theme name we plan to use. As you may have guessed, there is indeed a Gulp plugin that does that for us, called gulp-replace.

npm install --save-dev gulp-replace

Then import it:

import replace from "gulp-replace";

We want this task to run immediately before our files are zipped, so let’s modify the compress task by slotting it in the right place:

export const compress = () => {
return src([
    "**/*",
    "!node_modules{,/**}",
    "!bundled{,/**}",
    "!src{,/**}",
    "!.babelrc",
    "!.gitignore",
    "!gulpfile.babel.js",
    "!package.json",
    "!package-lock.json",
  ])
  .pipe(replace("_themename", info.name))
  .pipe(zip(`${info.name}.zip`))
  .pipe(dest('bundled'));
};

Try to building the theme now with npm run build and then unzip the file inside the bundled folder. Open any PHP file where the _themename placeholder may have been used and make sure it’s replaced with the actual theme name.

There is a gotcha to watch for that I noticed in the replace plugin as I was working with it. If there are ZIP files inside the theme (e.g. you are bundling WordPress plugins inside your theme), then they will get corrupted when they pass through the replace plugin. That can be resolved by ignoring ZIP files using a gulp-if statement:

.pipe(
  gulpif(
    file => file.relative.split(".").pop() !== "zip",
    replace("_themename", info.name)
  )
)

Generating a POT file

Translation is a big thing in the WordPress community, so for our final task, we let’s scan through all of our PHP files and generate a POT file that gets used for translation. Luckily, we also have a gulp plugin for that:

npm install --save-dev gulp-wp-pot

And, of course, import it:

import wpPot from "gulp-wp-pot";

Here’s our final task:

export const pot = () => {
  return src("**/*.php")
  .pipe(
      wpPot({
        domain: "_themename",
        package: info.name
      })
    )
  .pipe(gulp.dest(`languages/${info.name}.pot`));
};

We want the POT file to generate every time we build the theme:

export const build = series(clean, parallel(styles, images, copy, scripts), pot, compress);

Summing up

Here’s the complete Gulpfile, including all of the tasks we covered in this post:

import { src, dest, watch, series, parallel } from 'gulp';
import yargs from 'yargs';
import sass from 'gulp-sass';
import cleanCss from 'gulp-clean-css';
import gulpif from 'gulp-if';
import postcss from 'gulp-postcss';
import sourcemaps from 'gulp-sourcemaps';
import autoprefixer from 'autoprefixer';
import imagemin from 'gulp-imagemin';
import del from 'del';
import webpack from 'webpack-stream';
import named from 'vinyl-named';
import browserSync from "browser-sync";
import zip from "gulp-zip";
import info from "./package.json";
import replace from "gulp-replace";
import wpPot from "gulp-wp-pot";
  const PRODUCTION = yargs.argv.prod;
  const server = browserSync.create();
  export const serve = done => {
    server.init({
      proxy: "http://localhost:8888/starter"
    });
    done();
  };
  export const reload = done => {
    server.reload();
    done();
  };
  export const clean = () => del(['dist']);
    
  export const styles = () => {
  return src(['src/scss/bundle.scss', 'src/scss/admin.scss'])
    .pipe(gulpif(!PRODUCTION, sourcemaps.init()))
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpif(PRODUCTION, postcss([ autoprefixer ])))
    .pipe(gulpif(PRODUCTION, cleanCss({compatibility:'ie8'})))
    .pipe(gulpif(!PRODUCTION, sourcemaps.write()))
    .pipe(dest('dist/css'))
    .pipe(server.stream());
  }
  export const images = () => {
  return src('src/images/**/*.{jpg,jpeg,png,svg,gif}')
    .pipe(gulpif(PRODUCTION, imagemin()))
    .pipe(dest('dist/images'));
  }
  export const copy = () => {
    return src(['src/**/*','!src/{images,js,scss}','!src/{images,js,scss}/**/*'])
    .pipe(dest('dist'));
  }
    export const scripts = () => {
      return src(['src/js/bundle.js','src/js/admin.js'])
      .pipe(named())
      .pipe(webpack({
        module: {
        rules: [
          {
            test: /\.js$/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: []
                }
              }
            }
          ]
        },
        mode: PRODUCTION ? 'production' : 'development',
        devtool: !PRODUCTION ? 'inline-source-map' : false,
        output: {
          filename: '[name].js'
        },
        externals: {
          jquery: 'jQuery'
        },
      }))
      .pipe(dest('dist/js'));
    }
    export const compress = () => {
      return src([
        "**/*",
        "!node_modules{,/**}",
        "!bundled{,/**}",
        "!src{,/**}",
        "!.babelrc",
        "!.gitignore",
        "!gulpfile.babel.js",
        "!package.json",
        "!package-lock.json",
      ])
      .pipe(
        gulpif(
          file => file.relative.split(".").pop() !== "zip",
          replace("_themename", info.name)
        )
      )
      .pipe(zip(`${info.name}.zip`))
      .pipe(dest('bundled'));
    };
    export const pot = () => {
      return src("**/*.php")
        .pipe(
          wpPot({
            domain: "_themename",
            package: info.name
          })
        )
      .pipe(dest(`languages/${info.name}.pot`));
    };
    export const watchForChanges = () => {
      watch('src/scss/**/*.scss', styles);
      watch('src/images/**/*.{jpg,jpeg,png,svg,gif}', series(images, reload));
      watch(['src/**/*','!src/{images,js,scss}','!src/{images,js,scss}/**/*'], series(copy, reload));
      watch('src/js/**/*.js', series(scripts, reload));
      watch("**/*.php", reload);
    } 
    export const dev = series(clean, parallel(styles, images, copy, scripts), serve, watchForChanges);
    export const build = series(clean, parallel(styles, images, copy, scripts), pot, compress);
    export default dev;

Phew, that’s everything! I hope you learned something from this series and that it helps streamline your WordPress development flow. Let me know if you have any questions in the comments. If you are interested in a complete WordPress theme development course, make sure to check out my course on Udemy with a special discount for you. 😀

The post Gulp for WordPress: Creating the Tasks appeared first on CSS-Tricks.

Agregator najlepszych postów o designie, webdesignie, cssie i Internecie