Creating a Blogging App Using Angular & MongoDB: Show Post

In the last part of the tutorial series, you saw how to write the REST API endpoint for user login. You used Mongoose to interact with MongoDB from Node. After successful validation, you saw how to use Angular Router for navigating to the HomeComponent.

In this part of the tutorial series, you’ll create a component to list the blog post details on the home page.

Getting Started

Let’s get started by cloning the source code from the last part of the tutorial series.

Navigate to the project directory and install the required dependencies.

Once you have the dependencies installed, restart the client and server application.

Point your browser to http://localhost:4200 and you should have the application running.

Angular Blogging App

Creating the Show Post Component

Once the user gets logged into the application, you’ll display the HomeComponent. HomeComponent acts like a wrapper component for all the components displayed inside it. You’ll be displaying the list of blog posts added by the user in the HomeComponent.

To display the blog posts, let’s create a new component called ShowPostComponent. Create a folder called show-post inside the src/app folder. Inside the show-post folder, create a file called show-post.component.html and add the following HTML code:

Create a file called show-post.component.ts which will contain the ShowPostComponent class. Here is how it looks:

Import the ShowPostComponent in the app.module.ts file.

Add ShowPostComponent in the NgModule in the app.module.ts file. 

Modify the home.component.html file to include the ShowPostComponent selector.

Here is how the modified home.component.html file looks:

Save the above changes and refresh the client application. On signing into the application, you will be able to view the blog posts listed.

Angular Blog App - Show Post Component

Creating the Show Post Component Service

The data displayed in the ShowPostComponent service displays hard-coded data. You’ll need a service to query the blog post list from the MongoDB database. Let’s create a service for your ShowPostComponent.

Create a file called show-post.service.ts in src/app/show-post and add the following code:

Inside the ShowPostService, create a method called getAllPost, which will make the REST API call to get the blog post list. Here is how it looks:

Here is how the show-post.service.ts file looks:

Next, you need to write down the REST API to query the MongoDB collection to get the list of blog posts.

On the server side, let’s get started by creating the model for the post. Inside the models folder, create a file called post.js. Require the Mongoose module and create a schema for the blog post and export it. Here is how the /server/models/post.js looks:

Export the above defined post.js file in app.js.

Create an API endpoint /api/post/getAllPost for fetching the list of blog posts. Use the mongoose client to connect to the MongoDB database.

Once you have the connection established, you can use the Post model to find the list of blog posts.

The .find callback returns the list of documents.

The documents returned will be in ascending order, so add a condition to sort the blog posts in descending order.

Once you have the list of documents queried from the database, return the data along with the status. Here is how the REST API looks:

Making the API Call

In the show-post.component.ts file, define an array list for keeping the results of the API call.

Import the ShowPostService in the ShowPostComponent.

Add the ShowPostService as a provider to the ShowPostComponent.

Define a method called getAllPost to make a call to the service method. Here is how it looks:

As seen in the above code, the result data is set to the posts variable.

Make a call to the above defined method from the ngOnInit method, so that the blog post details are fetched as soon as the component is initialized.

Here is how the show-post.component.ts file looks:

Rendering the Blog Posts

The MongoDB collection might not have entries to be queried. So let’s add a few entries in the MongoDB from the mongo shell.

Enter the MongoDB shell by typing in the following command:

Once you enter the mongo shell, check the database available in the MongoDB database.

Select the blogDb database from the listed entries.

Create a collection named post.

Insert a couple of entries into the post collection.

Now let’s bind our posts variable in the ShowPostComponent to the HTML code.

You’ll be making use of the ngFor directive to iterate over the posts variable and display the blog posts. Modify the show-post.component.html file as shown:

Save the above changes and restart the client and REST API server. Sign in to the application and you will have the inserted records from MongoDB displayed on the home page.

Angular Blog App - Dynamic Blog Post Listing

Wrapping It Up

In this tutorial, you created the ShowPostComponent to display the blog post details from the MongoDB database. You created the REST API for querying the MongoDB database using the Mongoose client from the Node server.

In the next part of the tutorial series, you’ll learn how to create the AddPostComponent for adding new posts from the application user interface.

Source code for this tutorial is available on GitHub.

How was your experience so far? Do let me know your valuable suggestions in the comments below.


Source: Nettuts Web Development

How Web Designers Can Keep Up with Job Market Transformations

This article was sponsored by BAWMedia. Thank you for supporting the partners who make SitePoint possible.

A recent study from Edelman Intelligence has found an interesting fact. It claims freelancers are already feeling the impact of the “Fourth Industrial Revolution”. Artificial Intelligence (AI) is already impacting jobs in most industry sectors. Other innovative technologies are affecting web design work. Thereby, they are influencing freelancers as well.

Freelancers have become quite adept at proactively upgrading their skills. They do this far more than members of the traditional workforce. But not all freelancers are doing so. If you fall into this category, here is how you can not only keep up, but remain at the top of your profession.

Kick Off Your Projects with Pre-built Websites

Keeping up with the latest industry trends doesn’t have to be all that difficult. This is when you can rely, to some degree, on the efforts of others.

Using pre-built websites is one way to keep pace with the latest design trends. Each of Be Theme’s selection of 300+ customizable pre-built websites can be adapted to meet your needs. They can do so within hours and without any requirement for coding on your part.

These themes feature clean layouts and graphics and offer unsurpassed speed and performance. You can install any or all of them with a 1-click installer, as demonstrated in this cool, 40-second video.

Popular Be Theme Pre-Built Websites

Here’s a sampling of Be Theme pre-built websites. By clicking on the hyperlinks, you’ll get an awareness of how much easier they can make your workflow.

At the same time, they are giving you the opportunity to put into practice the latest web design trends.

Be Salmon

Any website intended for a food-oriented business should feature large images, just like those in this example. This should be done in order to entice visitors to investigate further or make a purchase.

The interactive menu guides visitors toward a call to action. A section on customer testimonials helps to seal the deal.

BeDetailings2

The best thing that can be said about many small business websites is that they’re dull and uninspiring. That certainly won’t be the case when bold, professional images like this (including before and after images) are the new normal. The price listing for services feature of this pre-built website is another must-have.

BeMeeting

This pre-built website lays the foundation for an award-winning events and meetings website. The content addresses the what, where, when, and why of events and meetings using a standard menu, and eye-catching countdown clock and a clean design.

BeManicure

One thing professional designers need to know is who the audience is. Here, the soft design and luxurious imagery emphasizing services and products leads visitors to the integrated eShop.

BeDenim

This pre-built website provides another example of basing a design on who the audience is. In this case, the bold imagery, color combinations, and intuitive icons help guide the visitor to the integrated eShop.

Continue reading %How Web Designers Can Keep Up with Job Market Transformations%


Source: Sitepoint

Replacing jQuery With Vue.js: No Build Step Necessary

It’s been impossible to ignore all of the hype surrounding JavaScript frameworks lately, but they might not be the right fit for your projects. Perhaps you don’t want to set up an entire build system for some small abstractions you could feasibly do without. Perhaps moving a project over to a build system and thus, different deployment method would mean a lot of extra time and effort that you might not be able to bill to a client.
Source: Smashing Magazine

Spicing Up the Bootstrap Carousel with CSS3 Animations

Adding a slider or carousel to showcase content on a website is a common client request for developers. The amount of free and premium carousel plugins available is overwhelming, and a good many of them offer plenty of useful configuration options and dynamic effects.

There are times, however, when a lightweight carousel with minimal options is all you need. In this case, if your project uses Bootstrap, the popular open-source, front-end framework, you won’t need to look any further than the Bootstrap Carousel component.

In this article, I’m going to show how to add some fun animation effects to the Bootstrap Carousel, while still making sure this handy JavaScript component remains bloat-free and quick to implement.

Introducing Animate.css

As rewarding as crafting my own animation effects can be, I’m going to use a well-known, open-source CSS3 animation library most aptly called Animate.css, by Dan Eden.

This is so that I can focus on the task at hand, rather than on explaining the code for CSS3 animations. However, if you want to delve into that topic, you’ll enjoy the CSS3 Animations series here on SitePoint, by Craig Buckler.

Using Animate.css requires two steps:

  1. include animate.min.css in the <head> section of your HTML document
  2. add the classes of animated yourchosenanimation to the elements you intend to animate on your web page.

In the latter step, you would replace yourchosenanimation with the class name corresponding to any of the numerous animations you see on the Animate.css website.

The Bootstrap Carousel component has three main sections:

  • The Carousel indicators track the overall number of slides, give users a visual clue of the position the slide currently being viewed occupies, and offer an alternative navigation for the slider.
  • The Carousel item, located inside a wrapper container with a class of .carousel-inner, represents each individual slide. It’s inside each item that you place your images. You can also add captions to your slides. The nice thing is that you can put pretty much any HTML element inside a container with the class of carousel-caption and Bootstrap will take care of the styling and formatting. It’s these captions that you’re going to animate.
  • Finally, the Carousel controls are the navigation arrows that enable users to access the next and previous slides.

Bootstrap Carousel structure

To keep this demo simple, I’m not going to add images to the carousel. The focus is all on how to animate the carousel captions.

Building the HTML Structure

If you’re following along, here’s what you need to include in your project:

Here’s the code for the Bootstrap Carousel:

[code language=”html”]
<!– indicators –>
<div id=”carouselExampleIndicators” class=”carousel slide”>
<ol class=”carousel-indicators”>
<li data-target=”#carouselExampleIndicators” data-slide-to=”0″ class=”active”></li>
<li data-target=”#carouselExampleIndicators” data-slide-to=”1″></li>
<li data-target=”#carouselExampleIndicators” data-slide-to=”2″></li>
</ol>

<!– carousel content –>
<div class=”carousel-inner”>

<!– first slide –>
<div class=”carousel-item active”>
<div class=”carousel-caption d-md-block”>
<h3 data-animation=”animated bounceInLeft”>
This is the caption for slide 1
</h3>
<h3 data-animation=”animated bounceInRight”>
This is the caption for slide 1
</h3>
<button class=”btn btn-primary btn-lg” data-animation=”animated zoomInUp”>Button</button>
</div>
</div>

<!– second slide –>
<div class=”carousel-item”>
<!– second slide content –>
</div>

<!– third slide –>
<div class=”carousel-item”>
<!– third slide content –>
</div>
</div>

<!– controls –>
<a class=”carousel-control-prev” href=”#carouselExampleIndicators” role=”button” data-slide=”prev”>
<span class=”carousel-control-prev-icon” aria-hidden=”true”></span>
<span class=”sr-only”>Previous</span>
</a>
<a class=”carousel-control-next” href=”#carouselExampleIndicators” role=”button” data-slide=”next”>
<span class=”carousel-control-next-icon” aria-hidden=”true”></span>
<span class=”sr-only”>Next</span>
</a>

</div>
[/code]

The elements inside the carousel caption that you’ll be animating have a data-animation attribute added to them with the specific animation class name as their respective value.

If you’d like to experiment with other animations from the Animate.css library, feel free to replace the values in the data-animation attribute with your chosen animation class names.

Now, give free rein to your creativity and style the carousel captions according to your taste. The style rules that I’m going to focus on here are those relevant to the smooth working of this demo.

More specifically, you’re taking control of the CSS animation-delay property, which defines when each animation starts.

[code language=”css”]
.carousel-caption h3:first-child {
animation-delay: 1s;
}

.carousel-caption h3:nth-child(2) {
animation-delay: 2s;
}

.carousel-caption button {
animation-delay: 3s;
}
[/code]

The snippet above ensures that the elements start their animation sequentially. There’s room for play here. For instance, you can choose to start animating the first two headings at the same time, followed by the button animation. It’s up to you, so have fun with it!

Continue reading %Spicing Up the Bootstrap Carousel with CSS3 Animations%


Source: Sitepoint

Creating a Blogging App Using Angular & MongoDB: Home

In the first part of the tutorial series, you saw how to get started with creating an Angular web app. You learnt how to set up the application and created the Login component.

In this part of the series, you’ll move further and write down the REST API required for interacting with the MongoDB bank end. You’ll also create the Home component which will be displayed after the user has logged in successfully.

Getting Started

Let’s get started by cloning the source code from the first part of the tutorial series.

Navigate to the project directory and install the required dependencies.

Once you have the dependencies installed, restart the application server.

Point your browser to http://localhost:4200 and you should have the application running.

Creating the Login REST API

Inside the project folder AngularBlogApp-Home, create another folder called server. You’ll be writing the REST APIs using Node.js.

Navigate to the server folder and initialize the project.

Enter the required details and you should have the project initialized.

You’ll be using the Express framework for creating the server. Install Express using the following command:

Once you have Express installed, create a file called app.js. This will be the root file for your Node.js server.

Here is how the app.js file looks:

As seen in the above code, you imported express into app.js. Using express, you created an application app.

Using app, you exposed an endpoint /api/user/login which will display a message. Start the Node.js server using the following command:

Point your browser to http://localhost:3000/api/user/login and you should have the message displayed.

You’ll be making a POST request from the Angular service to the server with the username and password parameters. So you need to parse the request parameters.

Install body-parser, which is Node.js body-parsing middleware to parse request parameters.

Once you have it installed, import it in app.js .

Add the following code to the app.js file.

The above two body-parser options return the middleware that only parses json and urlencoded bodies and only looks at requests where the Content-Type header matches the type option.

You’ll be using Mongoose to interact with MongoDB from Node.js. So install Mongoose using Node Package Manager (npm).

Once you have mongoose installed, import it in app.js.

Define the MongoDB database URL in app.js.

Let’s use Mongoose to connect to the MongoDB database. Here is how it looks:

If the connection is established, the message gets logged along with the username and password.

Here is how the app.js file looks:

Restart the Node server using the following command:

To connect to the Node server from the Angular application, you need to set the proxy. Create a file called proxy.json inside the client/src folder. Here is how it looks:

Modify the client package.json file to start the application using the proxy file.

Save the changes and start the client server.

Point your browser to http://localhost:4200 and enter the username and password. Click the sign in button and you should have the parameters logged in the Node console.

Validating the User Login

To interact with MongoDB using Mongoose, you need to define a schema and create a model. Inside the server folder, create a folder called model.

Create a file called user.js inside the model folder. Add the following code to the user.js file:

As seen in the above code, you imported mongoose into user.js. You created a userSchema using the mongoose schema and created the User model using the mongoose model.

Import the user.js file inside the app.js file.

Before querying the MongoDB user collection, you need to create the collection. Go to the MongoDB shell by typing mongo. Create the collection user using the following command:

Insert a record which you’ll be querying against.

Now, once mongoose gets connected to MongoDB, you’ll find the record from the database using the username and password passed in. Here is how the API looks:

As seen in the above code, once you receive a response from the database, you return the same to the client side.

Save the above changes and try running the client and server. Enter the username as roy and password as 123 and you should be able to view the result in the browser console.

Redirecting to the Home Component

Once the user has been validated successfully, you need to redirect the user to the Home component. So let’s start by creating the Home component. 

Create a folder called Home inside the src/app folder. Create a file called home.component.html and add the following HTML code:

Create a file called home.component.css and add the following CSS style:

Create the component file called home.component.ts and add the following code:

As seen in the above code, you just created the HomeComponent using the @Component decorator and specifying the selector, templateUrl, and styleUrls

Add the HomeComponent to the NgModules in app.module.ts.

Import the HomeComponent in the app.routing.ts and define a route for home.

In the validateLogin method in the login.component.ts file, on successful validation redirect the user to the HomeComponent. To redirect, you need to import the Angular Router.

If the response from the API call is a success, you’ll navigate to the HomeComponent using the Angular Router.

Here is how the login.component.ts file looks:

Save the above changes and restart the server. Sign in to the application using the existing username and password, and you will be redirected to the HomeComponent.

Angular Blog App Home Component

Wrapping It Up

In this tutorial, you saw how to write the REST API endpoint for user sign-in. You learnt how to use Mongoose to interact with MongoDB from Node. After successful validation, you saw how to use Angular Router for navigating to the HomeComponent.

How was your experience learning to write an Angular application and its back end? Do let us know your thoughts and suggestions in the comments below.

Source code from this tutorial is available on GitHub.


Source: Nettuts Web Development

How to Take Your Idea from Concept to Creation with Moqups

This article was created in partnership with Moqups. Thank you for supporting the partners who make SitePoint possible.

So, you have a great idea.

You’ve already told your family, friends, and colleagues, and the feedback has been great. Everyone loves the concept, and can see its potential. They think you should just go for it!

But, you know it’s not quite that simple.

Before committing time and money – both yours and other people’s – you need to get real, and work out the details.

As you move your concept from ideation to realization, you’ll need to assemble your team and put together your financing. That means pitching to a wide range of industry professionals: product managers, developers, designers, business analysts, marketers, and investors.

To show them that your vision is both viable and executable, your pitch needs to be abstract enough to capture their imagination, but specific enough to be clear and credible.

You need to build out your concept, assess its technical complexity, and map out its full scale. In other words, you need to get real.

And that’s where Moqups can help.

We designed Moqups as an online, all-in-one creative platform, so that it could take you from your first brainstorming session – capturing and connecting ideas – all the way to fully-realized, interactive, hi-fi prototypes.

Our goal was to create the perfect “low effort – high impact” app.

We think Moqups’ real strength is that it’s UI is both intuitive and easy to master. So, without switching apps, you can produce a wide range of materials that outline the requirements of your project, including workflow diagrams, sitemaps, wireframes, mockups, and interactive prototypes.

Sure, there are a number of more complicated and detailed tools out there for each of these specific artifacts (i.e diagramming apps that just do diagrams, or apps that focus exclusively on wireframing or prototyping).

But when you’re frantically building out your concept, every hour spent struggling with a new and unfamiliar interface is an hour NOT spent on your own product’s future.

So, let’s take a look at three artifacts that you’ll probably want to have as part of your eventual pitch package:

  • Wireframes and prototypes
  • Flow diagrams
  • Sitemaps

Begin Anywhere

During the incubation process, you may be the only one who can make sense of your vision. But even with all that information in your head – or maybe because of it – your ability to explain its intricacies may still be fuzzy, and chaotic.

The best thing you can do is give shape to those scattered ideas by getting them out of your brain and onto the page. That way, you can turn them into something tangible and organized.

But where to begin?

Bruce Mau, in his Incomplete Manifesto for Growth, has a great prompt:

Begin anywhere. John Cage tells us that not knowing where to begin is a common form of paralysis. His advice: begin anywhere.

So don’t worry about prescriptive methodology. Just rely on your intuition. No matter where you start, each artifact will inform the others – and develop in parallel – as your vision comes into focus and becomes more concrete.

A real advantage of an all-in-one tool like Moqups is that it frees you to jump back and forth seamlessly between assets as they develop.

So, let’s get going!

If you want to play along, just head to moqups.com and click on “Try it now for free”.

Wireframes & Prototypes

Software helps users accomplish certain goals by leading them through a series of steps towards those objectives – and your concept is no different. Building a wireframe will help you empathize with your users by putting you in their shoes, and helping you visualize each step they take.

Creating a wireframe is also the most immediate way of getting your vision out of your head, and onto the page, because it lets you experiment with different options and layouts – without worrying about details like colours, fonts, logos, exact sizing, etc.

Chances are, you’ve probably already identified some primary use cases, and imagined the sequence of steps the users should follow. Wireframes give you the chance to figure out what essential elements are required by those screens – content, input fields, buttons, menus – and which ones you may have overlooked.

So, choose a single objective. In this case, I’ve chosen ‘Create an Account’ as my objective. I’ve decided to embed the sign-up fields directly into the home page – in the hope of capturing more leads.

Now, identify the steps required to achieve that goal:

  1. Visit the landing page and enter personal credentials in the sign-up fields
  2. Get confirmation

In this Moqups project, I want every objective – in this case, ‘Create an Account’ – to have its own page. Further, that page will contain a series of nested pages that detail the steps/screens required to achieve that objective.

In the Moqups app, your assets (stencils, pages, icons, images, etc.) are accessed from the left sidebar. Formatting and interactivity is controlled via the right sidebar.

From the left sidebar, click on the Pages tab. From the Pages panel you can create, name, and nest both folders and pages.

If you want to change your page dimensions to suit the device you’re designing for, the Workspace dropdown in the top toolbar (the little gear icon) will give you access to page settings, as well as snapping, guides and grids.

(Moqups UI is intuitive, so I won’t go into too much detail here… but if you need more granular instructions, just visit the Help Center which is pretty comprehensive and user-friendly.)

Now, it’s time to start mocking up your screens.

Click on the Stencil tab in the left sidebar. From the open panel, you can search for relevant stencils to add to your screen; for example, an account registration form is composed of text inputs, checkboxes, radios, and buttons.

Simply drag and drop these stencils onto the page. Then move them around, resize them, or style them by using the Format tab in the right sidebar.

Add as many details as you want, but don’t sweat them too much. At this point, aesthetics aren’t really important. You can always come back and polish your work. It’s more important that you discover whatever input is required from your users – and how the basic navigation will work for them.

Watching your amorphous vision take concrete shape can be wonderfully energizing… so you may want to add a bit of color and tweak the fonts, just to get your blood pumping, and to give you an inspiring sense of your future brand. The important thing is to keep moving, building, and making progress. You can always change, edit, and iterate later.

You may want to go even further, turning your wireframe into a preliminary prototype by adding interactivity. This can provide your stakeholders with a visceral sense of the user experience (UX) and navigation.

A well constructed wireframe/prototype not only helps you communicate your vision in a comprehensive and comprehensible way, but it’s also the kind of document that your designers and developers will need in order to get right down to work.

Flow Diagram

Now that you’ve used the wireframe/prototype to explore the user interface, and you’ve got a feeling for the navigation, it’s time to go explore the business aspects of your project by creating a flow diagram.

Continue reading %How to Take Your Idea from Concept to Creation with Moqups%


Source: Sitepoint

Getting Bootstrap Tabs to Play Nice with Masonry

On the Masonry website, we read that Masonry is …

a JavaScript grid layout library. It works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall.

Bootstrap is one of the most widely adopted, open-source, front-end frameworks. Include Bootstrap in your project, and you’ll be able to whip up responsive web pages in no time.

If you tried using Masonry together with the Tabs widget, one of the many JavaScript components Bootstrap has to offer, chances are you’ve stumbled on some kind of annoying behavior.

I did, and this article highlights what the issue is and what you can do to solve it.

Bootstrap Tabs Explained

Bootstrap’s Tabs component includes two key, related pieces: a tabbed navigation element and a number of content panels. On page load, the first panel has the class .active applied to it. This enables the panel to be visible by default. This class is used via JavaScript to toggle the panel’s visibility via the events triggered by the tabbed navigation links: if .active is present the panel is visible, otherwise the panel is hidden.

If you have some web content that’s best presented in individual chunks, rather than crammed all in one spot, this kind of tabs component might come in handy.

Why Masonry?

In some cases, the content inside each panel is suited to being displayed in a responsive grid layout. For instance, a range of products, services, and portfolio items are types of content that can be displayed in grid format.

However, if grid cells are not of the same height, something like what you see below can happen.

Grid layout without Masonry

A wide gap separates the two rows of content and the layout appears broken.

Nowadays, Bootstrap solves the equal-width issue with the brand new card component, which is based on Flexbox. Just adding the card-deck class to a group of card components is sufficient to achieve equal-width columns.

If you like your cards to be of uneven length, you could use CSS3 Multi Column Layout. (After all, even though there are some browser support bugs, overall it’s quite good.) This underlies the new card columns option that comes packaged with the card component. However, if you still love the nice animation that the Masonry JavaScript library provides out of the box, and its wide browser compatibility, JavaScript is still a viable option in this case.

Setting Up a Demo Page

Getting a demo page up and running helps to show how integrating Bootstrap’s Tabs with Masonry is not as straightforward as one might expect.

This article’s demo page is based on the starter template, available on the Bootstrap website.

Below is the skeleton of the markup for the tabs component:

<ul class="nav nav-tabs" id="myTab" role="tablist">

  <!-- nav item 1 -->
  <li class="nav-item">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
  </li>

  <!-- nav item 2 -->
  <li class="nav-item">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
  </li>

  <!-- nav item 3 -->
  <li class="nav-item">
    <a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
  </li>
</ul>

The nav nav-tabs classes are responsible for giving the tabs their characteristic appearance. The value of the href attribute forms the relationship between a single tab and its corresponding tabbed content. For instance, an href value of #home creates a relationship with the tabbed content with id="home": clicking that particular tab reveals the contents inside the div with the id value of home.

Also, notice how Bootstrap pays attention to accessibility attributes like role, aria-controls, etc.

Here’s a code snippet to illustrate the tabbed content’s structure:

<!-- content 1 -->
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
  <h3>Tab 1 Content</h3>
<div class="card-group">

  <!-- first card -->
  <div class="card">
    <img class="card-img-top" src="path/to/img" alt="Card image cap">
    <div class="card-body">
      <h5 class="card-title">Card title</h5>
      <p class="card-text">Card text here.</p>
      <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
    </div>
  </div>

  <!-- second card -->
  <div class="card">
    <!-- card markup here -->
  </div&lgt;

  <!-- third card -->
  <div class="card">
    <!-- card markup here -->
  </div>

  </div>
</div>

Just add a similar structure for each tabbed content section corresponding to the tabs elements you coded above.

For the full code, check out the CodePen demo.

Continue reading %Getting Bootstrap Tabs to Play Nice with Masonry%


Source: Sitepoint

A Comprehensive Guide To Mobile App Design

(This is a sponsored article.) More than ever, people are engaging with their phones in crucial moments. The average US user spends 5 hours per day on mobile. The vast majority of that time is spent in apps and on websites.
The difference between a good app and a bad app is usually the quality of its user experience (UX). A good UX is what separates successful apps from unsuccessful ones.
Source: Smashing Magazine

8 Tips for Improving Bootstrap Accessibility

A few years ago, I wrote about my experiences on developing a Bootstrap version 3 project to be fully accessible for people with disabilities. This focussed mostly on how accessible it is in terms of front-end design. (It didn’t cover accessibility in terms of screen readers, as that’s a whole other story.)

While I could see that the developers behind Bootstrap were making an effort, there were a few areas where this popular UI library fell short. I could also see that there were issues raised on the project that showed they were actively improving — which is fantastic, considering how approximately 3.6% of websites use Bootstrap.

Recently, Bootstrap version 4 was released, so let’s take a look and see if any of the issues I had in the past have improved.

What We’re Looking For with Design Accessibility

There are a few things to consider when designing a website with accessibility in mind. I believe these improve the user experience for everyone and will likely cover a lot of points you would consider anyway.

Layout

One way to achieve accessibility is by having a clean, easy-to-use layout that looks good on all devices, as well as looking good at a high zoom level. Up to 200% is a good guide.

Bonus points: having front-end code that matches the layout is also good for users who access the Web with a screen reader or by using a keyboard instead of a mouse.

This allows people to use your website easily irrespective of how they’re viewing it.

Continue reading %8 Tips for Improving Bootstrap Accessibility%


Source: Sitepoint

Phoenix I18n

In my previous articles I covered the various aspects of Elixir—a modern functional programming language. Today, however, I would like to step aside from the language itself and discuss a very fast and reliable MVC framework called Phoenix that is written in Elixir.

This framework emerged nearly five years ago and has received some traction since then. Of course, it is not as popular as Rails or Django yet, but it does have great potential and I really like it.

In this article we are going to see how to introduce I18n in Phoenix applications. What is I18n, you ask? Well, it is a numeronym that means “internationalization”, as there are exactly 18 characters between the first letter “i” and the last “n”. Probably, you have also met an L10n numeronym which means “localization”. Developers these days are so lazy they can’t even write a couple of extra characters, eh?

Internationalization is a very important process, especially if you foresee the application being used by people from all around the world. After all, not everyone knows English well, and having the app translated into a user’s native language gives a good impression.

It appears that the process of translating Phoenix applications is somewhat different from, say, translating Rails apps (but quite similar to the same process in Django). To translate Phoenix applications, we use quite a popular solution called Gettext, which has been around for more than 25 years already. Gettext works with special types of files, namely PO and POT, and supports features like scoping, pluralization, and other goodies. 

So in this post I am going to explain to you what Gettext is, how PO differs from POT, how to localize messages in Phoenix, and where to store translations. Also we are going to see how to switch the application’s locale and how to work with pluralization rules and domains.

Shall we start?

Internationalization With Gettext

Gettext is a battle-tested open-source internationalization tool initially introduced by Sun Microsystems in 1990. In 1995, GNU released its own version of Gettext, which is now considered to be the most popular out there (the latest version was 0.19.8 at the time of writing this article). Gettext may be used to create multilingual systems of any size and type, from web apps to operational systems. This solution is quite complex, and we are not going to discuss all its features, of course. The full Gettext documentation can be found at gnu.org.

Gettext provides you all the necessary tools to perform localization and presents some requirements on how translation files should be named and organized. Two file types are used to host translations: PO and MO.

PO (Portable Object) files store translations for given strings as well as pluralization rules and metadata. These files have quite a simple structure and can be easily edited by a human, so in this article we will stick to them. Each PO file contains translations (or part of the translations) for a single language and should be stored in a
directory named after this language: en, fr, de,
etc.

MO (Machine Object) files contain binary data not meant to be edited directly by a human. They are harder to work with, and discussing them is out of the scope of this article.

To make things more complex, there are also POT (Portable Object Template) files. They host only strings of data to translate, but not the translations themselves. Basically, POT files are used only as blueprints to create PO files for various locales.

Sample Phoenix Application

Okay, so now let’s proceed to practice! If you’d like to follow along, make sure you have installed the following:

Create a new sample application without a database by running:

--no-ecto says that the database should not be utilized by the app (Ecto is a tool to communicate with the DB itself). Note that the generator might require a couple of minutes to prepare everything.

Now use cd to go to the newly created i18ndemo folder and run the following command to boot the server:

Next, open the browser and navigate to http://localhost:4000, where you should see a “Welcome to Phoenix!” message.

Hello, Gettext!

What’s interesting about our Phoenix app and, specifically, the welcoming message is that Gettext is already being used by default. Go ahead and open the demo/lib/demo_web/templates/page/index.html.eex file which acts as a default starting page. Remove everything except for this code:

This welcoming message utilizes a gettext function which accepts a string to translate as the first argument. This string can be considered as a translation key, though it is somewhat different from the keys used in Rails I18n and some other frameworks. In Rails we would have used a key like page.welcome, whereas here the translated string is a key itself. So, if the translation cannot be found, we can display this string directly. Even a user who knows English poorly can get at least a basic sense of what’s going on.

This approach is quite handy actually—stop for a second and think about it. You have an application where all messages are in English. If you’d like to internationalize it, in the simplest case all you have to do is wrap your messages with the gettext function and provide translations for them (later we will see that the process of extracting the keys can be easily automated, which speeds things up even more).

Okay, let’s return to our small code snippet and take a look at the second argument passed to gettext: name: "Phoenix". This is a so-called binding—a parameter wrapped with %{} that we’d like to interpolate into the given translation. In this example, there is only one parameter called name.

We can also add one more message to this page for demonstration purposes: 

Adding a New Translation

Now that we have two messages on the root page, where should we add translations for them? It appears that all translations are stored under the priv/gettext folder, which has a predefined structure. Let’s take a moment to discuss how Gettext files should be organized (this applies not only to Phoenix but to any app using Gettext).

First of all, we should create a folder named after the locale it is going to store translations for. Inside, there should be a folder called LC_MESSAGES containing one or multiple .po files with the actual translations. In the simplest case, you’d have one default.po file per locale. default here is the domain’s (or scope’s) name. Domains are used to divide translations into various groups: for example, you might have domains named admin, wysiwig, cart, and other. This is convenient when you have a large application with hundreds of messages. For smaller apps, however, having a sole default domain is enough. 

So our file structure might look like this:

  • en
    • LC_MESSAGES
      • default.po
      • admin.po
  • ru
    • LC_MESSAGES
      • default.po
      • admin.po

To starting creating PO files, we first need the corresponding template (POT). We can create it manually, but I’m too lazy to do it this way. Let’s run the following command instead:

It is a very handy tool that scans the project’s files and checks whether Gettext is used anywhere. After the script finishes its job, a new priv/gettext/default.pot file containing strings to translate will be created.

As we’ve already learned, POT files are templates, so they store only the keys themselves, not the translations, so do not modify such files manually. Open a newly created file and take a look at its contents:

Convenient, isn’t it? All our messages were inserted automatically, and we can easily see exactly where they are located. msgid, as you’ve probably guessed, is the key, whereas msgstr is going to contain a translation.

The next step is, of course, generating a PO file. Run:

This script is going to utilize the default.pot template and create a default.po file in the priv/gettext/en/LC_MESSAGES folder.  For now, we have only an English locale, but support for another language will be added in the next section as well.

By the way, it is possible to create or update the POT template and all PO files in one go by using the following command:

Now let’s open the priv/gettext/en/LC_MESSAGES/default.po file, which has the following contents:

This is the file where we should perform the actual translation. Of course, it makes little sense to do so because the messages are already in English, so let’s proceed to the next section and add support for a second language.

Multiple Locales

Naturally, the default locale for Phoenix applications is English, but this setting can be changed easily by tweaking the config/config.exs file. For example, let’s set the default locale to Russian (feel free to stick with any other language of your choice):

It is also a good idea to specify the full list of all supported locales:

Now what we need to do is generate a new PO file containing translations for the Russian locale. It can be done by running the gettext.merge script again, but with a --locale switch:

Obviously, a priv/gettext/ru/LC_MESSAGES folder with the .po files inside will be generated. Note, by the way, that apart from the default.po file, we also have errors.po. This is a default place to translate error messages, but in this article we are going to ignore it.

Now tweak the priv/gettext/ru/LC_MESSAGES/default.po by adding some translations:

Now, depending on the chosen locale, Phoenix will render either English or Russian translations. But hold on! How can we actually switch between locales in our application? Let’s proceed to the next section and find out!

Switching Between Locales

Now that some translations are present, we need to enable our users to switch between locales. It appears that there is a third-party plug for that called set_locale. It works by extracting the chosen locale from the URL or Accept-Language HTTP header. So, to specify a locale in the URL, you would type http://localhost:4000/en/some_path. If the locale is not specified (or if an unsupported language was requested), one of two things will happen:

  • If the request contains an Accept-Language HTTP header and this locale is supported, the user will be redirected to a page with the corresponding locale.
  • Otherwise, the user will be automatically redirected to a URL that contains the code of the default locale.

Open the  mix.exs file and drop in set_locale to the deps function:

We must also add it to the application function:

Next, install everything:

Our router located at lib/demo_web/router.ex requires some changes as well. Specifically, we need to add a new plug to the :browser pipeline:

Also, create a new scope:

And that’s it! You can boot the server and navigate to http://localhost:4000/ru and http://localhost:4000/en. Note that the messages are translated properly, which is exactly what we need!

Alternatively, you may code a similar feature yourself by utilizing a Module plug. A small example can be found in the official Phoenix guide.

One last thing to mention is that in some cases you might need to enforce a specific locale. To do that, simply utilize a with_locale function:

Pluralization

We have learned the fundamentals of using Gettext with Phoenix, so the time has come to discuss slightly more complex things. Pluralization is one of them. Basically, working with plural and singular forms is a very common though potentially complex task. Things are more or less obvious in English as you have “1 apple”, “2 apples”, “9000 apples” etc (though “1 ox”, “2 oxen”!).

Unfortunately, in some other languages like Russian or Polish, the rules are more complex. For example, in the case of apples, you’d say “1 яблоко”, “2 яблока”, “9000 яблок”. But luckily for us, Phoenix has a Gettext.Plural behavior (you may see the behavior in action in one of my previous articles) that supports many different languages. Therefore all we have to do is take advantage of the ngettext function.

This function accepts three required arguments: a string in singular form, a string in plural form, and count. The fourth argument is optional and can contain bindings that should be interpolated into the translation.

Let’s see ngettext in action by saying how much money the user has by modifying the demo/lib/demo_web/templates/page/index.html.eex file:

%{count} is an interpolation that will be replaced with a number (540 in this case). Don’t forget to update the template and all PO files after adding the above string:

You will see that a new block was added to both default.po files:

We have not one but two keys here at once: in singular and in plural forms. msgstr[0] is going to contain some text to display when there is only one message. msgstr[1], of course, contains the text to show when there are multiple messages. This is okay for English, but not enough for Russian where we need to introduce a third case: 

Case 0 is used for 1 buck, and case 1 for zero or few bucks. Case 2 is used otherwise.

Scoping Translations With Domains

Another topic that I wanted to discuss in this article is devoted to domains. As we already know, domains are used to scope translations, mainly in large applications. Basically, they act like namespaces.

After all, you may end up in a situation when the same key is used in multiple places, but should be translated a bit differently. Or when you have way too many translations in a single default.po file and would like to split them somehow. That’s when domains can come in really handy. 

Gettext supports multiple domains out of the box. All you have to do is utilize the dgettext function, which works nearly the same as gettext. The only difference is that it accepts the domain name as the first argument. For instance, let’s introduce a notification domain to, well, display notifications. Add three more lines of code to the demo/lib/demo_web/templates/page/index.html.eex file:

Now we need to create new POT and PO files:

After the script finishes doing its job, notifications.pot as well as two notifications.po files will be created. Note once again that they are named after the domain. All you have to do now is add translation for the Russian language by modifying the priv/ru/LC_MESSAGES/notifications.po file:

What if you would like to pluralize a message stored under a given domain? This is as simple as utilizing a dngettext function. It works just like ngettext but also accepts a domain’s name as the first argument:

Conclusion

In this article, we have seen how to introduce internationalization in a Phoenix application with the help of Gettext. You have learned what Gettext is and what type of files it works with. We have this solution in action, have worked with PO and POT files, and utilized various Gettext functions.

Also we’ve seen a way to add support for multiple locales and added a way to easily switch between them. Lastly, we have seen how to employ pluralization rules and how to scope translations with the help of domains.

Hopefully, this article was useful to you! If you’d like to learn more about Gettext in the Phoenix framework, you may refer to the official guide, which provides useful examples and API reference for all the available functions.

I thank you for staying with me and see you soon!


Source: Nettuts Web Development