All Feeds

Digital Photography School How to Take Vibrant, Razor-Sharp Macro Photos of Flowers The post How to Take Vibrant, Razor-Sharp Macro Photos of Flowers appeared first on Digital Photography School. It was authored by Ramakant Sharda. Macro photography is a very interesting subject for photographers. People love to shoot small objects like insects, flowers, waterdrops, etc. With macro photography, a photographer can show the tiniest details about the subject – details that are not possible to see with the naked eye. Today, let’s find out how to amaze viewers by taking […] The post How to Take Vibrant, Razor-Sharp Macro Photos of Flowers appeared first on Digital Photography School. It was authored by Ramakant Sharda. Feb 28 SitePoint How to Design for Screen Readers with Adobe XD CC When it comes to accessibility, designers tend to focus on colors (i.e. contrast) and UX copy (i.e. wording), whereas developers tend to focus on ARIA attributes (i.e. code that makes websites more accessible). This is due to the fact that, often enough, thick lines are drawn between “who does what”. Also, because creating accessible apps and websites isn’t considered to be exciting, this line is hardly ever questioned. Accessibility is still a black sheep, even in 2020. So, since UX copy is the responsibility of the designer and ARIA attributes are the responsibility of the developer, exactly whose responsibility is it to cater for screen readers? Since: Screen reader UX copy is expressed as Braille or dictation (so how do we communicate this when our UI tools are visual?) Implementation is developer territory (so can we really shift the responsibility of writing UX copy to developers?) As you can see, it’s a two-person job — and yet, the tools simply don’t exist to facilitate this. I mean, make no mistake, some aspects of accessibility design are one-sided (for example, UI designers can very easily take care of color contrast by themselves). However, other aspects such as designing for screen readers requires collaboration between designers and developers. This is where Adobe XD CC’s design handoff and voice prototyping features come in handy. In this article, we’ll discuss what to consider when designing for screen readers, and we’ll also walk through how to use the features mentioned above. What Are Screen Readers? A screen reader is a type of assistive technology that communicates what’s happening on the screen (for those with visual impairments). Screen reader software can be used in combination with the keyboard (for example, users will tab and enter as opposed to using the mouse), but it can also be used in combination with screen reader hardware, which allows for more efficient navigation and also caters for users that use Braille. If you’re an Apple user, for example, you’ll be somewhat aware of Apple VoiceOver, which is the native Apple dictation software that acts as a screen reader. Windows users, however, commonly use either JAWS or NVDA, since there aren’t any native screen reader tools in the Windows operating system. Let’s dive in. 1. Use Headings Screen readers often use headings as a way of deciphering a website’s structure, and if we think too visually we run the risk of leaving out these headings. In the example below, the omission of the “Chapters” heading causes screen readers to assume that the list of chapters is a continuation of the content on the left-hand side, which it obviously isn’t. As a result, screen-reader users won’t be able to skip to “Chapters”, and they might not discover the information within. While there are code workarounds available (such as the aria-label attribute), having a visible heading inclusively offers a clearer experience for everybody, whether disabled or not. Of course, the section is very obviously a list of chapters, as we can infer from the context (i.e. the content). However, those using screen readers very rarely have the luxury of context. It’s like trying to find an object in storage where none of the boxes are labeled. Our designs need these labels and headings. On the technical side, the rule is that every section (as defined by a <section> or <article> tag) should have not only a heading, but an explicit heading that conflicts with no other heading. As an example, if the highest level heading within a section is an <h2>, then there should be no other <h2> heading within that section. Otherwise, screen readers are clueless as to which heading is the label for the section. The post How to Design for Screen Readers with Adobe XD CC appeared first on SitePoint. Feb 27 Digital Photography School Canon EOS R5 Is Being Developed, But Don’t Forget About the R1 The post Canon EOS R5 Is Being Developed, But Don’t Forget About the R1 appeared first on Digital Photography School. It was authored by Jaymes Dempsey. The Canon EOS R5 hasn’t yet hit the shelves, but the rumors keep coming regarding Canon’s full-frame mirrorless line. Rumors which promise something even more exciting (for those of us who can be patient, that is!). Now, the Canon EOS R5 is plenty thrilling in its own right. It was officially announced by Canon earlier […] The post Canon EOS R5 Is Being Developed, But Don’t Forget About the R1 appeared first on Digital Photography School. It was authored by Jaymes Dempsey. Feb 27 Digital Photography School How to Use Exposure Compensation and When You Should Use It The post How to Use Exposure Compensation and When You Should Use It appeared first on Digital Photography School. It was authored by Mat Coker. Sometimes, no matter what you do, your photos seem to keep coming out too dark or too bright. If only there were a simple way to tell your camera to make them a bit brighter or a bit darker. Well, there is! In this tutorial, I’ll show you how to use exposure compensation so you’ll […] The post How to Use Exposure Compensation and When You Should Use It appeared first on Digital Photography School. It was authored by Mat Coker. Feb 27 Harold Davis Chicago Botanic Garden Photography Conference Discount Code I’ve recently returned from a photography conference in Yosemite Valley organized by the Out of Chicago gang. This was an incredible life experience! These guys (and gals) know how to organize things, and present a smorgasbord of photographic offerings at their conferences that is rich beyond belief. Whatever level of photographer you are, if you […] Feb 26 Digital Photography School Making Sense of the Exposure Triangle – ISO, Aperture, and Shutterspeed Made Simple The post Making Sense of the Exposure Triangle – ISO, Aperture, and Shutterspeed Made Simple appeared first on Digital Photography School. It was authored by Jackie Lamas. Ever hear other photographers talking about shooting in manual mode, and using terms like ISO, aperture, and shutter speed and have no idea what they’re talking about? Then this article is for you. While making sense of the Exposure Triangle may seem overwhelming, you’ll learn everything there is to know so that you can get […] The post Making Sense of the Exposure Triangle – ISO, Aperture, and Shutterspeed Made Simple appeared first on Digital Photography School. It was authored by Jackie Lamas. Feb 26 Digital Photography School Viewing Images in Lightroom – What Are The Options? The post Viewing Images in Lightroom – What Are The Options? appeared first on Digital Photography School. It was authored by Kevin Landwer-Johan. Digital photographers can tend to take tons of photos. Viewing images in Lightroom can be a tedious and time-consuming task if you are not familiar with the various tools available to you. In this article, I’ll outline some techniques and tools to help improve your post-processing workflow. Viewing many images in Lightroom The most common […] The post Viewing Images in Lightroom – What Are The Options? appeared first on Digital Photography School. It was authored by Kevin Landwer-Johan. Feb 26 Rick Strahl's Web Log Working with IWebHostEnvironment and IHostingEnvironment in dual targeted ASP.NET Core Projects With .NET Core 3.1 Microsoft broke a fairly low level abstraction by effectively renaming IHostingEnvironment and replacing it IWebHostEnvironment. IHostingEnvironment still exists in .NET Core 3.x and can still be used and it still works, but it's been marked as deprecated and will be removed in a future version. It is recommended that you use IWebHostEnvironment instead. The reasoning behind this presumably was that IHostingEnvironment has multiple implementations for the same type in .NET Core in different packages. The AspNetCore specific version in Microsoft.AspNetCore.Hosting looks like this: public interface IHostingEnvironment { string EnvironmentName { get; set; } string ApplicationName { get; set; } string ContentRootPath { get; set; } IFileProvider ContentRootFileProvider { get; set; } string WebRootPath { get; set; } IFileProvider WebRootFileProvider { get; set; } } while the base Extensions version in Microsoft.Extensions.Hosting doesn't have the WebRoot folder related properties: public interface IHostingEnvironment { string EnvironmentName { get; set; } string ApplicationName { get; set; } string ContentRootPath { get; set; } IFileProvider ContentRootFileProvider { get; set; } } The idea was to use the Web version in ASP.NET projects, while using the plain extensions versions for non-Web apps like Console or Desktop apps. The type duplication isn't very clean, and somewhat understandable that that should this got cleaned up. Unfortunately, in doing so a few problems have been introduced if you need to build libraries that need to work both in .NET Core 2.x and 3.x. Out with old in with the new: IWebHostEnvironment So in .NET Core 3.0 there's a new IWebHostEnvironment and IHostEnvironment that separate out the two behaviors: public interface IWebHostEnvironment : IHostEnvironment { IFileProvider WebRootFileProvider { get; set; } string WebRootPath { get; set; } } public interface IHostEnvironment { string ApplicationName { get; set; } IFileProvider ContentRootFileProvider { get; set; } string ContentRootPath { get; set; } string EnvironmentName { get; set; } } which admittedly is cleaner and more obvious. Since the interfaces are related they can be used interchangeably in many situations and non-Web applications can just stick with IHostEnvironment while Web apps can use IWebHostEnvironment. Presumably in the future there maybe other environments to run in and they may get their own extensions to IHostEnvironment. All good right? Multi-Targeting Required? It's all good if you're creating an ASP.NET core Web application. When you're at the application level, you're not multi-targeting typically, so a 3.x app can use IWebHostEnvironment while a 2.x app can use IHostingEnvironment. In 3.x ASP.NET's default dependency injection provides IWebHostEnvironment as well as IHostingEnvironment (for now) in the default DI container and your .NET Core 3.x single targeted project can just use that. No problemo. But now consider a library that might have to work both in .NET Core 2.x and 3.x. I have a non-significant number of library projects/packages both public and internal and every single one of them has to be multi-targeted in order to work reliably in both versions of .NET Core without a number of warnings and type reference errors. I ran into this originally from an issue submitted by Phil Haack on my Westwind.AspnetCore.Markdown package where the use of IHostingEnvironment in 3.x results in an empty reference through DI (I think this has since been fixed tho) possibly because the wrong type was injected (from extensions rather than the ASP.NET version). But regardless using the 'old' IHostingEnvironment results in a slew of warnings in the code due to the deprecation. Easy to fix you say - reference the new one and we're off right? Except the new interface doesn't exist in 2.x so now you have a situation where you have to multi-target in order to use the new interface in the component. Mind you there's no new functionality no new behavior - nothing really has changed except the abstraction so yes this is pretty grumble worthy because it's essentially a cosmetic change. Originally my packages were either .NET Standard or .NET Core 2.x targeted projects and they would work fine in 3.x. All the functionality introduced works in both framework and so there really was not specific reason to force these projects to dual target - the single 2.1 target works for both. But alas, this IWebHostEnvironment change forces me to use multi-targeted projects in order to use both IHostingEnvironment and IWebHostEnvironment. Hrmph. Multi-Targeting - maybe not so bad? Thankfully multi-targeting is not too hard with the new SDK style project. You can just specify multiple <TargetFrameworks> and a few target specific overrides to reference the appropriate ASP.NET Core framework. That solves the type availability, but it doesn't solve access to the proper hosting environment type in each version. Hacking Around This I haven't really found a good way to do this without using a mulit-targeted project. I can if I continue using IHostingEnvironment but then I'm stuck with a slew of warnings in the project, and the thread of the interface disappearing in future versions. So regardless it's probably necessary to multi-target so that the new interface is used. Given that here's a hacky way I've used to make this work: Multi-target the project Add a NETCORE2 compiler variable Bracket code that wraps IWebHostEnvironemnt in a #if NETCORE2 To multi-target the project is pretty easy with SDK projects thankfully: <PropertyGroup> <TargetFrameworks>netcoreapp3.1;netcoreapp2.1;</TargetFrameworks> </PropertyGroup> You also have to fix up a few depedencies potentially with target framework specific version directives. For example: <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'"> <FrameworkReference Include="Microsoft.AspNetCore.App" /> </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'"> <PackageReference Include="Microsoft.AspNetCore.App" /> </ItemGroup> Alternately you might reference specific individual ASP.NET Core packages although that's no longer the recommendation. Microsoft now recommends you reference the frameworks instead because frankly it's vastly easier to keep one dependency up to date than 20 😄. You can add other framework specific package dependencies into those blocks if there's a difference for 2.x and 3.x. Then I add a NETCORE2 compiler flag, which I set when the code is compiled .NET Core 2.x: <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'"> <DefineConstants>NETCORE2</DefineConstants> </PropertyGroup> So now I can selectively determine which version I'm running and based on that use the appropriate host environment. Yeah that's freaking ugly, but it works to consolidate the two types: #if !NETCORE2 protected IWebHostEnvironment Host { get; } public JavaScriptLocalizationResourcesController( IWebHostEnvironment host, DbResourceConfiguration config, IStringLocalizer<JavaScriptLocalizationResourcesController> localizer) #else protected IHostingEnvironment Host { get; } public JavaScriptLocalizationResourcesController( IHostingEnvironment host, DbResourceConfiguration config, IStringLocalizer<JavaScriptLocalizationResourcesController> localizer) #endif { Config = config; Host = host; Localizer = localizer; } The above is a controller, but the same type of logic can be applied inside of middleware (which also receives DI injection) or even manual provider.GetService<T> requests. If you have one or two places where you use IWebHostEnvironment, this is a quick and dirty way to do it. It's ugly but as long as it's one or two places where this happens it's no big deal. However if your library needs access to the hosting environment in a lot of places this kind of code gets really ugly fast. Take 1 - HostEnvironmentAbstraction My first cut to address this was to build - yup another abstraction. Wrap the native host environment into a container and basically isolate the multi-target logic that I showed above in a single place. That makes for one ugly class, but once that's done I can use the host container anywhere I would normally use the host. Here's the abstration that provides both a DI injectable and static Host property: /// <summary> /// A Hosting Environment Abstraction for ASP.NET Core that /// can be used to provide a single .Host instance that works /// for both .NET Core 3.x and 2.x /// /// Requires dual targeting for 2.x and 3.x /// </summary> /// <example> /// var hostAbstraction = new HostingAbstraction( app.ApplicationServices); /// app.AddSingleton<HostingAbstraction>(hostAbstraction); /// /// then either: /// /// * Use HostEnvironmentAbstraction.CurrentHost /// * Or inject `HostEnvironmentAbstraction` with DI /// </example> public class HostEnvironmentAbstraction { private IHostingEnvironment env; public HostEnvironmentAbstraction(IServiceProvider provider) { if (CurrentHost == null) InitializeHost(provider); } #if NETCORE2 /// <summary> /// Active Web Hosting Environment instance appropriate for the /// .NET version you're running. /// </summary> public static IHostingEnvironment CurrentHost { get; set; } /// <summary> /// Active Web Hosting Environment instance appropriate for the /// .NET version you're running. /// </summary> public IHostingEnvironment Host { get { return CurrentHost; } } #else /// <summary> /// Active Web Hosting Environment instance appropriate for the /// .NET version you're running. /// </summary> public static IWebHostEnvironment CurrentHost {get; set;} /// <summary> /// Active Web Hosting Environment instance appropriate for the /// .NET version you're running. /// </summary> public IWebHostEnvironment Host { get { return CurrentHost; } } #endif /// <summary> /// Initializes the host by retrieving either IWebHostEnvironment or IHostingEnvironment /// from DI /// </summary> /// <param name="serviceProvider"></param> public static void InitializeHost(IServiceProvider serviceProvider) { #if NETCORE2 CurrentHost = serviceProvider.GetService<IHostingEnvironment>(); #else CurrentHost = serviceProvider.GetService<IWebHostEnvironment>(); #endif } } To use this requires a little setup - you basically have to initialize the hosting environment somewhere once during startup. This can be in startup.cs or if you're creating middleware in the middleware hookup code. In Startup.cs and ConfigureServices() you'd use: var provider = services.BuildServiceProvider(); var host = new HostEnvironmentAbstraction(provider); services.AddSingleton<HostEnvironmentAbstraction>(host); You can then inject the HostEnvironmentAbstraction and use the .Host property: private IHostingEnvironment Host {get;} public JavaScriptLocalizationResourcesController( HostEnvironmentAbstraction hostAbstraction, DbResourceConfiguration config, IStringLocalizer<JavaScriptLocalizationResourcesController> localizer) { Host = hostAbstraction.Host; } Alternately you can skip DI and just use the Singleton directly: var host = HostEnvironmentAbstraction.Host; Both give you the right hosting environment for your .NET Core version. This works and certainly is cleaner the ugly conditional code inside of your application. It basically isolates that ugly code into a single ugly library class. The downside with this is that it requires that you use a different object to get the host than you naturally would if you were running on either platform. Yet another abstraction... and going forward that code will not be standard. But again it's unlikely this is heavily used so probably just fine. Take 2 - Use IWebHostEnvironment in 2.x too Another approach is perhaps more user friendly in that it allows for working with IWebHostEnvironment both .NET Core 2.x as well 3.x. The idea with this is basically that on .NET Core 2.x we can duplicate the .NET Core 3.x IWebHostEnvironment interface and pass an existing IHostingEnvironment to populate the values. This is a more verbose implementation, but the usage is cleaner once implemented as you can basically write 2.x the same way you would 3.x by using IWebHostEnvironment code. Here's the implementation of the LegacyHostEnvironment class that implements the faked IWebHostEnvironment and IHostEnvironment interfaces that don't exist in 2.x: #if NETCORE2 using Microsoft.Extensions.FileProviders; namespace Microsoft.AspNetCore.Hosting { public class LegacyHostEnvironment : IWebHostEnvironment { public LegacyHostEnvironment(IHostingEnvironment environment) { ApplicationName = environment.ApplicationName; ContentRootFileProvider = environment.ContentRootFileProvider; ContentRootPath = environment.ContentRootPath; EnvironmentName = environment.EnvironmentName; WebRootFileProvider = environment.WebRootFileProvider; WebRootPath = environment.WebRootPath; } public string ApplicationName { get; set; } public IFileProvider ContentRootFileProvider { get; set; } public string ContentRootPath { get; set; } public string EnvironmentName { get; set; } public IFileProvider WebRootFileProvider { get; set; } public string WebRootPath { get; set; } } public interface IWebHostEnvironment : IHostEnvironment { IFileProvider WebRootFileProvider { get; set; } string WebRootPath { get; set; } } public interface IHostEnvironment { string ApplicationName { get; set; } IFileProvider ContentRootFileProvider { get; set; } string ContentRootPath { get; set; } string EnvironmentName { get; set; } } } #endif To use this now you want to create an instance of this environment and add it to DI, but it's only necessary on 2.x. You basically need to get an instance of the IHostingEnvironment during startup and then create the new type. The following code is what you can use in middleware initialization code in your AddMyMiddleware() implementation: // Initialize the fake IWebHostingEnvironment for .NET Core 2.x #if NETCORE2 // we need a provider to retrieve IHostingEnvironment on 2.x // or you can inject `IServiceProvider` provider = services.BuildServiceProvider(); var ihHost = provider.GetService<IHostingEnvironment>(); var host = new LegacyHostEnvironment(ihHost); services.AddSingleton<IWebHostEnvironment>(host); #endif Once that's done though you can now use IWebHostEnvironment in .NET Core 2.x and that controller implementation just becomes: private IWebHostEnvironment Host {get;} public JavaScriptLocalizationResourcesController( IWebHostEnvironment host, DbResourceConfiguration config, IStringLocalizer<JavaScriptLocalizationResourcesController> localizer) { Host = host; } even in .NET Core 2.x code. Summary Phew - yeah all of this is ugly, and regardless of what you do, if you need to support both .NET Core 2.x and 3.x and you need IWebHostEnvironment you need to multi-target. I haven't found a way around that even with this re-implementation of the last example. The NETCORE2 block is what makes that work and that requires multi-targeting. Maybe there's a better way but I can't think of one for libraries that need to support both .NET Core 2.x and 3.x and require access to IWebHostEnvironment or IHostingEnvironment. This seems like a lot of effort but I was tired of having to remember how to do this on several of my library projects and even more tired of the bracketed #if NETCORE2 code. I guess eventually this will go away as 2.x usage fades away but at the moment support for 2.x for libraries still seems important as there's more 2.x code out there than 3.x at this point. Resources IHostingEnvironment vs IHostEnvironment - obsolete types in .NET Core 3.0 (Andrew Lock) Westwind.AspNetCore NuGet that contains these two classes HostEnvironmentAbstraction on Github this post created and published with the Markdown Monster Editor © Rick Strahl, West Wind Technologies, 2005-2020Posted in ASP.NET Core   Feb 26 SitePoint 10 Ways to Hide Elements in CSS There are multiple ways to hide an element in CSS, but they differ in the way they affect accessibility, layout, animation, performance, and event handling. Animation Some CSS hiding options are all or nothing. The element is either fully visible or fully invisible and there’s no in-between state. Others, such as transparency, can have a range of values, so interpolated CSS animations become possible. Accessibility Each method described below will visually hide an element, but it may or may not hide the content from assistive technologies. For example, a screen reader could still announce tiny transparent text. Further CSS properties or ARIA attributes such as aria-hidden="true" may be necessary to describe the appropriate action. Be wary that animations can also cause disorientation, migraines, seizures, or other physical discomfort for some people. Consider using a prefers-reduced-motion media query to switch off animations when specified in user preferences. Event Handling Hiding will either stop events being triggered on that element or have no effect — that is, the element is not visible but can still be clicked or receive other user interactions. Performance After a browser loads and parses the HTML DOM and CSS object model, the page is rendered in three stages: Layout: generate the geometry and position of each element Paint: draw out the pixels for each element Composition: position element layers in the appropriate order An effect which only causes composition changes is noticeably smoother than those affecting layout. In some cases, the browser can also use hardware acceleration. 1. opacity and filter: opacity() The opacity: N and filter: opacity(N) properties can be passed a number between 0 and 1, or a percentage between 0% and 100% denoting fully transparent and fully opaque accordingly. See the Pen hide with opacity: 0 by SitePoint (@SitePoint) on CodePen. There’s little practical difference between the two in modern browsers, although filter should be used if multiple effects are applied at the same time (blur, contrast, grayscale etc.) Opacity can be animated and offers great performance, but be wary that a fully transparent element remains on the page and can trigger events. metric effect browser support good, but IE only supports opacity 0 to 1 accessibility content not read if 0 or 0% is set layout affected? no rendering required composition performance best, can use hardware acceleration animation frames possible? yes events triggered when hidden? yes 2. color Alpha Transparency opacity affects the whole element, but it's also possible to set the color, background-color, and border-color properties separately. Applying a zero alpha channel using rgba(0,0,0,0) or similar renders an item fully transparent: See the Pen hide with color alpha by SitePoint (@SitePoint) on CodePen. Each property can be animated separately to create interesting effects. Note that transparency can’t be applied to elements with image backgrounds unless they're generated using linear-gradient or similar. The alpha channel can be set with: transparent: fully transparent (in-between animations are not possible) rgba(r, g, b, a): red, green, blue, and alpha hsla(h, s, l, a): hue, saturation, lightness, and alpha #RRGGBBAA and #RGBA metric effect browser support good, but IE only supports transparent and rgba accessibility content still read layout affected? no rendering required painting performance good, but not as fast as opacity animation frames possible? yes events triggered when hidden? yes 3. transform The transform property can be used to translate (move), scale, rotate, or skew an element. A scale(0) or translate(-999px, 0px) off-screen will hide the element: See the Pen hide with transform: scale(0); by SitePoint (@SitePoint) on CodePen. transform offers excellent performance and hardware acceleration because the element is effectively moved into a separate layer and can be animated in 2D or 3D. The original layout space remains as is, but no events will be triggered by a fully hidden element. metric effect browser support good accessibility content still read layout affected? no — the original dimensions remain rendering required composition performance best, can use hardware acceleration animation frames possible? yes events triggered when hidden? no The post 10 Ways to Hide Elements in CSS appeared first on SitePoint. Feb 26 SitePoint How to Prepare for a Remote Job Search The number of people working remotely is at an all-time high, and that’s not just because telecommuting is pants-optional. By giving employees more control over their schedule and work environment, remote jobs can enhance the work-life balance that so many people struggle to maintain. But if you’ve held in-house positions for most of your career, properly preparing for your remote job search can up your chances of impressing remote employers, nailing the interview, and landing a remote job that best fits your needs. What Are Remote Employers Looking For? Remote employers are looking for three things in particular. Independence The office may at times feel like a panopticonic prison, but there is something to be said for workplace accountability. Can you stay focused without a boss periodically checking in on you? Can you stay productive without the sight and sound of other co-workers clacking away on their computers? When you work from home, the Damocles of the deadline is blunted and the motivating effect of being in close proximity to your team members weakens. Remote employers understand these challenges, which is why they look for candidates who can motivate themselves without external prompting. As trite as buzzwords like self-starter and proactive can be, they carry a significant amount of weight in the remote job search. Not only do you need to possess these qualities, you’ll need to be able demonstrate them to potential employers. Communication Working in an office allows employees to be more passive. Don’t know what’s going on? A co-worker can fill you in via a few seconds of conversation. Your boss is only a few steps away. Maybe there’s a whiteboard in the break room with announcements. Sharing a space with people just makes it much easier to stay in the loop. But if you’re on your own, you need to take initiative. To compensate for the lack of face-to-face, a good remote worker will put effort into the virtual communication tools at their disposal. They’ll reach out to people through email or Slack. They’ll suggest video chats or calls to hash things out. Even swapping memes in a group chat can help you stay engaged. But if you give in to the temptation of solitude, communication could suffer, and so could your work. Rational Thinking When communicating primarily through text, it’s all too common for our imaginations to run wild with unfounded anxieties. Emailed your boss a question and they didn’t respond within whatever time frame you’ve arbitrarily decided was reasonable? They must think it’s a dumb question and you’re dumb for asking it. They must not deem you important enough to expediently respond to. They must be offended by something you wrote. Asked a co-worker to do something and they responded with “k”? They hate you. They’re telling everyone how much they hate you. Everyone hates you. You’re garbage! Or … absolutely none of that is true and the coldness of non-verbal communication is messing with your head. Like any good employer, remote employers don’t want drama. They want rational critical thinkers who can vault the pitfalls of remote communication and maintain healthy work relationships. K? How Do You Demonstrate These Skills On Your Resume? Even if you have little to no remote work experience, there are ways to frame your in-house work experience so that it demonstrates remote work skills. What have you done that demonstrates independence? Communication? Rational thinking? Figure it out and integrate it into your resume. For example, if you took the initiative on anything in a previous position, emphasize it. Say you independently devised and implemented project x or volunteered to plan, create, and maintain project y. Explain that you created and ran program z with little oversight. Here are some other ideas to get you thinking: The post How to Prepare for a Remote Job Search appeared first on SitePoint. Feb 25 SitePoint Build a Simple Beginner App with Node, Bootstrap and MongoDB If you’re just getting started with Node.js and want to try your hand at building a web app, things can often get a little overwhelming. Once you get beyond the “Hello, World!” tutorials, much of the material out there has you copy-pasting code, with little or no explanation as to what you’re doing or why. This means that, by the time you’ve finished, you’ve built something nice and shiny, but you also have relatively few takeaways that you can apply to your next project. In this tutorial, I’m going to take a slightly different approach. Starting from the ground up, I’ll demonstrate how to build a no-frills web app using Node.js, but instead of focusing on the end result, I’ll focus on a range of things you’re likely to encounter when building a real-world app. These include routing, templating, dealing with forms, interacting with a database and even basic authentication. This won’t be a JavaScript 101. If that’s the kind of thing you’re after, look here. It will, however, be suitable for those people who feel reasonably confident with the JavaScript language, and who are looking to take their first steps in Node.js. What We’ll Be Building We’ll be using Node.js and the Express framework to build a simple registration form with basic validation, which persists its data to a MongoDB database. We’ll add a view to list successful registration, which we’ll protect with basic HTTP authentication, and we’ll use Bootstrap to add some styling. The tutorial is structured so that you can follow along step by step. However, if you’d like to jump ahead and see the end result, the code for this tutorial is also available on GitHub. Basic Setup Before we can start coding, we’ll need to get Node, npm and MongoDB installed on our machines. I won’t go into depth on the various installation instructions, but if you have any trouble getting set up, please visit our forums and ask for help there. Node.js Many websites will recommend that you head to the official Node download page and grab the Node binaries for your system. While that works, I would suggest that you use a version manager instead. This is a program which allows you to install multiple versions of Node and switch between them at will. There are various advantages to using a version manager. For example, it negates potential permission issues which would otherwise see you installing packages with admin rights. If you fancy going the version manager route, please consult our quick tip: Install Multiple Versions of Node.js Using nvm. Otherwise, grab the correct binaries for your system from the link above and install those. npm npm is a JavaScript package manager which comes bundled with Node, so no extra installation is necessary here. We’ll be making quite extensive use of npm throughout this tutorial, so if you’re in need of a refresher, please consult A Beginner’s Guide to npm — the Node Package Manager. MongoDB MongoDB is a document database which stores data in flexible, JSON-like documents. If you’ve never worked with Mongo before, you might like to check out our beginner-friendly introduction to MongoDB. The quickest way to get up and running with Mongo is to use a service such as mLabs. They have a free sandbox plan which provides a single database with 0.5GB of storage running on a shared virtual machine. This is more than adequate for a simple app with a handful of users. If this sounds like the best option for you, please consult their quick-start guide. You can also install Mongo locally. To do this, please visit the official download page and download the correct version of the community server for your operating system. There’s a link to detailed, OS-specific installation instructions beneath every download link, which you can consult if you run into trouble. A MongoDB GUI Although not strictly necessary for following along with this tutorial, you might also like to install Compass, the official GUI for MongoDB. This tool helps you visualize and manipulate your data, allowing you to interact with documents with full CRUD functionality. Check that Everything is Installed Correctly To check that Node and npm are installed correctly, open your terminal and type: node -v followed by: npm -v This will output the version number of each program (12.14.1 and 6.13.6 respectively at the time of writing). If you installed Mongo locally, you can check the version number using: mongo --version This should output a bunch of information, including the version number (4.2.2 at the time of writing). Check the Database Connection Using Compass If you’ve installed Mongo locally, you start the server by typing the following command into a terminal: mongod Next, open Compass. You should be able to accept the defaults (server: localhost, port: 27017), press the CONNECT button, and establish a connection to the database server. MongoDB Compass connected to localhost Note that the databases admin, config and local are created automatically. Using a Cloud-hosted Solution If you’re using mLabs, create a database subscription (as described in their quick-start guide), then make a note of the connection details. Open Compass, click New Connection, then Fill in connection fields individually. Select Username / Password as the authentication method, then fill out the rest of the details. Finally, click CONNECT and you should be off to the races. Note: if you wish to use a connection string, it should look like this: mongodb://<dbuser>:<dbpassword>@ds211709.mlab.com:11709/?authSource=<dbname>. MongoDB Compass connected to mLabs Note that I called my database sp-node-article. You can call yours what you like. Initialize the Application With everything set up correctly, the first thing we need to do is initialize our new project. To do this, create a folder named demo-node-app, enter that directory and type the following in a terminal: npm init -y This will create and auto-populate a package.json file in the project root. We can use this file to specify our dependencies and to create various npm scripts, which will aid our development workflow. Install Express Express is a lightweight web application framework for Node.js, which provides us with a robust set of features for writing web apps. These features include such things as route handling, template engine integration and a middleware framework, which allows us to perform additional tasks on request and response objects. There’s nothing you can do in Express that you couldn’t do in plain Node.js, but using Express means we don’t have to re-invent the wheel and it reduces boilerplate. So let’s install Express. To do this, run the following in your terminal: npm install express This will see Express added to the dependencies section of the package.json file. This signals to anyone else running our code that Express is a package our app needs to function properly. Install nodemon nodemon is a convenience tool. It will watch the files in the directory it was started in, and if it detects any changes, it will automatically restart your Node application (meaning you don’t have to). In contrast to Express, nodemon is not something the app requires to function properly (it just aids us with development), so install it using: npm install --save-dev nodemon This will add nodemon to the dev-dependencies section of the package.json file. Create Some Initial Files We’re almost through with the setup. All we need to do now is create a couple of initial files before kicking off the app. In the demo-node-app folder create an app.js file and a start.js file. Also create a routes folder, with an index.js file inside. After you’re done, things should look like this: . ├── app.js ├── node_modules │ └── ... ├── package.json ├── package-lock.json ├── routes │ └── index.js └── start.js Now, let’s add some code to those files. In app.js: const express = require('express'); const routes = require('./routes/index'); const app = express(); app.use('/', routes); module.exports = app; Here, we’re importing both the express module and (the export value of) our routes file into the application. The require function we’re using to do this is a built-in Node function which imports an object from another file or module. If you’d like a refresher on importing and exporting modules, read Understanding module.exports and exports in Node.js. After that, we’re creating a new Express app using the express function and assigning it to an app variable. We then tell the app that, whenever it receives a request from forward slash anything, it should use the routes file. Finally, we export our app variable so that it can be imported and used in other files. In start.js: const app = require('./app'); const server = app.listen(3000, () => { console.log(`Express is running on port ${server.address().port}`); }); Here we’re importing the Express app we created in app.js. (Note that we can leave the .js off the file name in the require statement.) We then tell our app to listen on port 3000 for incoming connections and output a message to the terminal to indicate that the server is running. And in routes/index.js: const express = require('express'); const router = express.Router(); router.get('/', (req, res) => { res.send('It works!'); }); module.exports = router; Here, we’re importing Express into our routes file and then grabbing the router from it. We then use the router to respond to any requests to the root URL (in this case http://localhost:3000) with an “It works!” message. Kick off the App Finally, let’s add an npm script to make nodemon start watching our app. Change the scripts section of the package.json file to look like this: "scripts": { "watch": "nodemon ./start.js" }, The scripts property of the package.json file is extremely useful, as it lets you specify arbitrary scripts to run in different scenarios. This means that you don’t have to repeatedly type out long-winded commands with a difficult-to-remember syntax. If you’d like to find out more about what npm scripts can do, read Give Grunt the Boot! A Guide to Using npm as a Build Tool. Now, type npm run watch from the terminal and visit http://localhost:3000. You should see “It works!” The post Build a Simple Beginner App with Node, Bootstrap and MongoDB appeared first on SitePoint. Feb 25 Digital Photography School Laowa and Yongnuo to Support Micro Four Thirds Standard The post Laowa and Yongnuo to Support Micro Four Thirds Standard appeared first on Digital Photography School. It was authored by Jaymes Dempsey. The Micro Four Thirds standard will see official support from three additional companies. Last Thursday, Panasonic and Olympus declared that several manufacturers would be joining them in the production of Micro Four Thirds equipment, including Yongnuo and Venus Optics. You may be familiar with Yongnuo already; in addition to products such as their popular budget […] The post Laowa and Yongnuo to Support Micro Four Thirds Standard appeared first on Digital Photography School. It was authored by Jaymes Dempsey. Feb 25 Digital Photography School Learning to See, Read, and Interpret Light for Better Photography The post Learning to See, Read, and Interpret Light for Better Photography appeared first on Digital Photography School. It was authored by Herb Paynter. In the game of photography, lighting conditions occasionally throw your camera a curveball. In the game of baseball, the pitcher and catcher must coordinate and communicate their actions precisely through a series of gestures or signs. By learning to read the signs that a scene tells you about the existing light, you will be able […] The post Learning to See, Read, and Interpret Light for Better Photography appeared first on Digital Photography School. It was authored by Herb Paynter. Feb 25 Harold Davis Upcoming free “Photography as Poetry” presentation I will be presenting Photography as Poetry at the Alamo Danville Artists’ Society [ADAS] on Tuesday, March 10 2020 at 7:30 PM. My presentation is free, and open to the public. More information below, or click here for details. What: Artist, Photographer, and Writer Harold Davis presents Photography as Poetry Where:  Alamo Danville Artists’ Society [ADAS] […] Feb 24 Digital Photography School Top Ten Tools for Quality Commercial Beverage Photography The post Top Ten Tools for Quality Commercial Beverage Photography appeared first on Digital Photography School. It was authored by Darina Kopcok. Beverage photography is a challenging and exciting niche in photography, often shot by photographers that specialize in food photography. The reflective nature of glassware makes it difficult to shoot. Moreover, photographing cocktails to look cold and icy, means having a few tricks up your sleeve. Having the right tools in your toolbox can go a long way in […] The post Top Ten Tools for Quality Commercial Beverage Photography appeared first on Digital Photography School. It was authored by Darina Kopcok. Feb 24 Digital Photography School Laowa 65mm f2.8 2X Ultra-Macro APO Lens Review The post Laowa 65mm f2.8 2X Ultra-Macro APO Lens Review appeared first on Digital Photography School. It was authored by Matt Murray. When I was offered the chance to review the Laowa 65mm f2.8 2X Ultra-Macro APO lens, I must admit I wondered what all the fuss was about. From a quick look, it appeared roughly the same size and price as the Fujifilm 60mm f2.4 R macro lens – but it is a manual focus lens. […] The post Laowa 65mm f2.8 2X Ultra-Macro APO Lens Review appeared first on Digital Photography School. It was authored by Matt Murray. Feb 24 Digital Photography School Moving to Manual Mode: Which Setting Should You Adjust First? The post Moving to Manual Mode: Which Setting Should You Adjust First? appeared first on Digital Photography School. It was authored by Kevin Landwer-Johan. Moving to manual mode is often considered too difficult by many beginner photographers. In reality, learning manual mode is not so hard to do. Sure, it’s not for everyone. Many photographers are content to let their camera sort out the exposure settings. One of the most common questions I get asked by people I am […] The post Moving to Manual Mode: Which Setting Should You Adjust First? appeared first on Digital Photography School. It was authored by Kevin Landwer-Johan. Feb 23 Digital Photography School Weekly Photography Challenge – Orange The post Weekly Photography Challenge – Orange appeared first on Digital Photography School. It was authored by Caz Nowaczyk. This week’s photography challenge topic is the color ORANGE! This is a fun challenge. You can capture the color orange in so many ways. You can use macro, flowers and autumn leaves, landscapes (think orange sunrises or sunsets, or wildflowers), cityscapes, minimalist photography, abstracts or people wearing orange clothing. The orange can be a major […] The post Weekly Photography Challenge – Orange appeared first on Digital Photography School. It was authored by Caz Nowaczyk. Feb 21 Digital Photography School DIY: How to Create a Coffee-Stained Texture for Aging Images in Photoshop The post DIY: How to Create a Coffee-Stained Texture for Aging Images in Photoshop appeared first on Digital Photography School. It was authored by Megan Kennedy. As a kid, I remember coffee-staining scrap paper to create ancient maps that marked out treasure in the backyard. Nowadays, I’ve discovered that the same process can be great for photography projects too. With help from Photoshop, experimenting with textural layers is a great way to introduce an aged look to your images. But sometimes it can […] The post DIY: How to Create a Coffee-Stained Texture for Aging Images in Photoshop appeared first on Digital Photography School. It was authored by Megan Kennedy. Feb 21 Harold Davis Exciting Ride to Tower Arch So there were four of us, or six if you count me, myself, and I: also my old friend Eric, my German friend and colleague in x-ray photographics Julian, and Loki the Australian sheep dog. We happy few drove in Eric’s Blue Ganesh, an off-road modified high-clearance Toyota 4-Runner with under-armor plates, video front and […] Feb 20 SitePoint How to Properly Organize Files in Your Codebase & Avoid Mayhem The main library, data, UI, docs and wiki, tests, legacy and third-party components … How do we keep track and maintain order within all of this? Organizing the files in your codebase can become a daunting task. Relax — we've got this! In this article, we’ll review the most common systems for both small and large projects, with some easy-to-follow best practices. Why Bother? As with pretty much all of the tasks related to project management — documentation, software commits, deployment — you’ll benefit from taking a conscious, programmatic approach. Not only it will reduce problems now, but it will also save you and your team quality time in the future when you need to quickly access and review things. You surely can recall function names from the top of your head for whatever is it that you're coding right now, and quickly find a file you need to edit, and sharply tell what works from what doesn't — or so you think. But could you say the same about that project you were working on last year? Let's admit it: software projects can go on spans of inactivity that last for months, and even years. A simple README file could do a lot for your colleagues or your future self. But let's think about the other ways you could structure your project, and establish some basic rules to name files, address project documentation, and to some degree organize an effective workflow that would stand the test of time. Making Sense of Things We’ll establish a "baseline" for organizing files in a project — a logic that will serve us for a number of situations within the scope of software development. As with our rules for committing changes to your codebase the right way, none of this is carved in stone, and for what it's worth, you and your team might come up with different guidelines. In any case, consistency is the name of the game. Be sure you understand (and discuss or dispute) what the rules are, and follow them once you've reached a consensus. The Mandatory Set This is a reference list of files that nearly every software project should have: README: this is what GitHub renders for you right under the sourcetree, and it can go a long way to explaining what the project is about, how files are organized, and where to find further information. CHANGELOG: to list what's new, modified or discontinued on every version or revision — normally in a reverse chronological order for convenience (last changes first). COPYING LICENSE: a file containing the full text of the license covering the software, including some additional copyright information, if necessary (such as third-party licenses). .gitignore: assuming you use Git (you most probably do), this will also be a must to tell what files not to sync with the repository. (See Jump Start Git's primer on .gitignore and the documentation for more info, and have a look at a collection of useful .gitignore templates for some ideas.) Supporting Actors The post How to Properly Organize Files in Your Codebase & Avoid Mayhem appeared first on SitePoint. Feb 20 Designmodo 6 Simple Typography Tips to More Professional Looking Websites Devs often struggle with the design of their websites. One thing that holds their designs back the most is the way they handle type, so in this video, we’re looking at 6 simple steps for you to follow to make … Feb 20 Digital Photography School 6 Tips for Photographing Amazing Light Trails at Blue Hour The post 6 Tips for Photographing Amazing Light Trails at Blue Hour appeared first on Digital Photography School. It was authored by Joey J. Have you seen cityscape photos with light streaks of moving cars? That’s called light trail photography. I see it as a part of the long exposure photography family. However, the exposure doesn’t have to be very long (typically under 30 seconds) to capture light trails. While my absolute favorite long exposure photography style is waterfront […] The post 6 Tips for Photographing Amazing Light Trails at Blue Hour appeared first on Digital Photography School. It was authored by Joey J. Feb 20 SitePoint Productive Remote Work (When Your Mental Health Says “No”) Remote work is not easy. It sounds like a dream (and it honestly is in a lot of ways), but there’s a darker side to remote work that one can’t understand until they’ve done it. Here’s the deal. People that work remotely often suffer from suboptimal mental health, and so you’re probably wondering, why on earth do they do it? Well, the fact is, while remote working comes with some very unique challenges, so does not working remotely. The difference is that remote work can offer the flexibility you need to build a lifestyle that suits you. Indeed, remote work isn’t a silver bullet for burnout or wanderlust, but if you do happen to try it out and eventually wind up succumbing to loneliness, or a lack of motivation or productivity (as many remote workers do), at least you’ll have the opportunity to change things up and make things better. In the eyes of many, it’s the lesser of two evils. That being said, attempting to diagnose what your mind and body needs isn’t that easy. What might work one day might not work on another day, and what might work for one individual might not work for another individual. Humans are complex, and in the case of remote work, everyday productivity tricks often don’t cut it. Let’s take a look. “I feel lonely” Loneliness is a big issue (maybe the biggest?) for freelance remote workers and digital nomads in foreign countries, but it can also affect those that work in distributed teams (especially when some team members aren’t remote, as one can feel like an outsider at work using this setup). Let’s look at the solutions. Utilize co-working spaces Co-working spaces aren’t for everyone. If you teach English, it’s obviously a no-no (not because of the noise, but because the noise would be distracting to other remote workers). If you’re only required to dive into the odd video call, though, many co-working spaces include a few hours of “booth time”. Throw in super-fast Wi-Fi, free coffee, daily events, and a likeminded crowd, joining a co-working space is like joining a community, and some co-working spaces (such as Hubud) and Dojo Bali) are literally famous! Good vibes = a huge motivation boost. Work from bars and cafés Cafés and bars work well too. The noise and seating options might be a tad unpredictable, and when going to a new place one has to find the Wi-Fi password, but all in all the experience is very much the same. It’s still fairly easy to meet other people, as it’s likely that you won’t be the only regular customer. Pro-tip: download Wi-Fi Map app to get the Wi-Fi passwords of networks near you! My favourite café — October Coffee Gaya, Kota Kinabalu, Malaysia) The post Productive Remote Work (When Your Mental Health Says “No”) appeared first on SitePoint. Feb 19