Proposal for Adding Badges and Other ‘Learner Achievements’ to WordPress Profiles

In December 2020, WordPress launched its new “Learn” platform with free courses, workshops, and lesson plans. Since then, the Training Team has continued adding more material. The latest proposal is an open discussion for the community on adding participatory badges for completing coursework.

“I’d like to nail down what kind of thing we would like to see regarding recognising learner achievements on profiles,” wrote WordPress community manager Hugh Lashbrooke in the announcement earlier this month.

The proposal, which now has a GitHub ticket, includes showing the following on a user’s WordPress.org profile page:

  • A course’s completion in the activity stream.
  • The user’s average grade from Learn WordPress.
  • A new “Learning” tab for displaying completed courses with dates and the possibility of individual completed lessons, relevant grades, and other learning data.
  • A new “Learner” badge for anyone who has completed one course.

Currently, there are only two courses available. “That is changing as we develop new content,” wrote Lashbrooke in the post. “So my hope is that we will have these rewards in place now, and as content is created, the rewards will flow naturally.”

One downside to the proposal may be publicly showing a user’s grades. “I’d be against showing the learner’s average grade publicly because it could lead to anxiety, stress, etc., and maybe even stop some people from participating in the courses,” wrote Stephen Cronin in the comments. “Eg: ‘What if I only get a C, will anyone take me seriously? Will it harm my chances of getting a job in the WP space?’ etc. Some people will thrive on that sort of competition, some people … not so much. And I feel like we should be as inclusive as possible.”

Lashbrooke responded that showing grades could be an opt-in feature. However, I would question why it would be necessary to show grades at all. Bragging rights? Maybe. If we could somehow make it shareable via social media, it might be a fun way to get more people to participate.

Several people in the comments were encouraged by the idea of social sharing. Adam Warner even proposed adding the Learn badges to the oEmbed WordPress block, making it easy for users to share their accomplishments on their sites.

However, the first step should be to provide badges for completing a course. It is an easy win and could be automated.

Most user profile badges are for direct contributions to the project, such as writing code or working on a team. However, at least some user-based participatory badges are available already. For example, there is a “Test Contributor” badge for providing feedback on calls for testing.

One side advantage of a Learn achievement system could be for employers who are looking through an applicant’s history. It may help potential employees show off their competency in specific areas of the WordPress platform.

Courtney Engle Robertson, Web Design and Developer Advocate at GoDaddy, questioned Matt Mullenweg during 2020’s State of the Word Q&A session on the role of the Learn platform as it pertains to the job market.

Mullenweg said the first step is organizing the platform and making high-quality educational material available. However, he seemed open to the idea of having a self or administered certification down the line. It would allow people to show that they have completed or tested out of a course.

“It wouldn’t be a perfect system, but it could be a nice way for people to learn more about WordPress,” he said. “And, hopefully, as they go through, since WordPress is open-source, improve the materials as we go through it, both from the point of view of making it more intuitive or easier to understand and also translating, as well. Because there is a huge demand for WordPress really all over the world now.”

View the clip below from the State of the Word Q&A:

“As someone who hires WordPress professionals, I would love to have a request in the job application to link up their WP profile so we can see competency through that learning platform,” commented Chris Badgett, the founder and CEO of LifterLMS, on the proposal.

He also agreed with Mullenweg that people should be able to test out of a course. It would not make sense for those who have already acquired specific skills or knowledge to go through the motions of completing coursework they are already proficient in.

“Creating quizzes or ‘post tests’ in the LMS with a standard minimum passing requirement to earn the achievement badge would help fulfill this,” he said.

For now, some simple gamification via profile badges could boost participation and, perhaps, get more people involved in contributing to the Learn platform. This could also be the first step toward a WordPress certification system.

Leading 650 Engineers with Microsoft’s Brendan Burns

Brendan Burns is famous in engineering circles as one of the co-founders of Kubernetes, but he's more than just a talented developer - he leads a team of 650 engineers at Microsoft.

In the first episode of a two-part series, Brendan joins the Dev Interrupted podcast to talk all things engineering leadership and management. After joining Microsoft and being given a team of 30 people, he has seen his teams double each year. Adopting a leadership style that he jokingly refers to as "my form of punishment is micromanagement," Brendan discusses how to be intentional about employee interactions in a remote world, the importance of delivering a concise message and why saying "yes" to as many opportunities as possible has led to career success.

WorkerB Developer Automation From LinearB

“The most powerful tool we have as developers is automation.”
—Scott Hanselman

Developers automate everything about how we write, test and ship code. But when it comes to the process of how we work together as a team on projects, it’s highly manual.  

Is Remote Work better than In-Office for Developers?

In the past year-and-a-half, going remote has been the primary goal and focus for many companies and individuals. The beginning of the remote work overhaul was rocky to say the least but now that all this time has passed and workplaces have figured out how to work with it and not make it an utter mess- Is it worth keeping? Is it better than being in-office? Should remote work be a standard for dev teams, and in-office be secondary?

Well, that depends on a couple of factors. With some feedback from the Dev Interrupted Discord community, let’s dive into the advantages and disadvantages of remote work.

Overcoming Critical Oracle EPM Cloud Migration Challenges With Testing

Due to the low cost of ownership, data security, real-time access to data, scalability, and flexibility, enterprises across the globe are looking to migrate from on-premises Oracle Hyperion to Oracle Fusion Cloud EPM. Undoubtedly, there are numerous benefits of migrating to Oracle EPM Cloud, but there are also some concerns as well. Business users, managers, and IT heads are worried about the initial cost of migration, business disruption, and risks. Furthermore, there is also concern about security, time to transition, ease of adoption, and data conversion.

These concerns are not vague. In fact, they are backed by some potential data.

Twilio Segment Adds New Toolkit to Support Developer Innovation

Twilio Segment, the latest evolution of Twilio post-acquisition of Segment, is looking to build upon all the technical expertise that the company gained in absorbing Segment and has released a new developer toolkit to support this effort. This toolkit is intended to provide robust data collection and integration capabilities. 

Visual basic .net 1

Hello I have VB.NET System ; I wanna to make setup (.exe) for the program. The Program depend on SQL Server Database. How I can make it exe file with the database, and to install all the configuration on any PC. What I shall do according to the connection string ; since the server name will change? I don't have background in that ; any helpful articles or information ?

Think Twice Whether You Need Hibernate

I often saw how people included hibernating into a project, not really thinking about whether they really needed it. And after some time, when the service grew, they began to wonder if this was a mistake.

Let’s try to think ahead of what the general pros and cons of Hibernate are so that we can better determine the next time whether we need to add this dependency in a new microservice. Perhaps it makes sense to get by with simple Spring JDBC, without all that JPA complexity?

My tiny side project has had more impact than my decade in the software industry

That’s a heartwrenching title from Michael Williamson. I believe it though. It’s kinda like a maximized version of the blogging phenomenon where if you work on a post for weeks it’ll flop compared to a post that’s some dumb 20-minute thought. Or how your off-handed remark to some developer at the perfect time might cause some huge pivot in what they are doing, changing the course of a project forever. For Mike, it was a 3,000 line-of-code side project that had more impact on the world than a career of work as a software developer.

I’ve tried to pick companies working on domains that seem useful: developer productivity, treating diseases, education. While my success in those jobs has been variable – in some cases, I’m proud of what I accomplished, in others I’m pretty sure my net effect was, at best, zero – I’d have a tough time saying that the cumulative impact was greater than my little side project.

Impact is fuzzy though, isn’t it? I don’t know Mike, but assuming he is a kind and helpful person, think of all the people he’s likely helped along the way. Not by just saving them minutes of toil, but helped. Helped grow, helped through hard times, helped guide to where they ought to go. Those things are immeasurable and awfully important.

Direct Link to ArticlePermalink


The post My tiny side project has had more impact than my decade in the software industry appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Top 8 Skills To Have to Find a Data Analyst Job

Each company makes endeavors to accumulate data, for example, by checking its rivals' exhibitions, marketing projections, and purchasing patterns, etc. with an end goal to be more serious. Nonetheless, it's not possible for anyone to comprehend clients' practices and rivals' exhibitions without the ability to break down all that data.

The data analyst skills of an individual allude to his capacity to gather and sort out information with the end goal that it is converted into important data. This article will give you the bits of knowledge and patterns that a data analyst skills of an individual can assist with revealing can end up being extremely helpful in making prompt just as future business choices. Let’s get started.

Beginners Guide for Web Scraping Using Selenium

Data experts and researchers often require exact and retrieving data from unconventional sites to train or test algorithms, build datasets, machine learning models, neural networks, etc. However, the website contributes APIs that are an awe-inspiring way to retrieve structured data. But what if there is the absence of an API when you want to bypass the method.

Under such situations, the data can easily be managed through the web page. But the conventional method is highly time-consuming and cumbersome; it becomes more challenging when you have to bargain with websites such as lodge booking, real estate, work listing, etc., as they need to be accessed frequently. However, Selenium allows a computerized method through various models to fetch the information from the website and obtain whatever you want. But before going deep with the process, let's understand web scraping as well as Selenium in detail.

ACF 5.10 Introduces Block API v2 Support, Block Preloading, and Security Improvements

Advanced Custom Fields (ACF) has released version 5.10, the first major release since the plugin was acquired by Delicious Brains. It introduces several new features that were previously experimental, closing out tickets that were started by previous owner Elliot Condon.

The release enables HTML escaping by default, which helps prevent Cross-Site Scripting (XSS) attacks. It runs content rendered by ACF through the WordPress wp_kses() function. There was a little confusion about how this works and the release post has been updated to clarify:

“It’s important to note that this only affects content rendered by ACF in your WordPress dashboard or any front-end forms rendered through acf_form(),” Iain Poulson said. “This will not affect field values loaded through API functions such as get_field() and the_field(). We don’t make any assumptions about where you are using your field values within your theme and do not escape to them as a result.”

Version 5.10 also introduces support for the WordPress Blocks API v2 for ACF blocks. WordPress 5.6 came with a new Block API that makes it easier for theme and plugin developers to style the block content with more consistent results matching the front end. The ACF team has created a Block API v2 help doc with examples that help developers update their blocks and make use of the new block filters included in the update.

Other features introduced in this release include block preloading turned on by default, a new full-height setting for blocks, opacity support for the color-picker, and many bug fixes. Next up on the roadmap for the plugin is adding WordPress REST API support to ACF field groups.

“As API-powered JavaScript front-ends become more and more popular in the WordPress space, it’s clear that many of our customers want this functionality included in ACF core,” Poulson said.

“We also plan to improve the performance of the plugin and work on other quality of life features. Now that our development team has a solid handle on the codebase and the release process, we can start working on these more complicated but long-requested features.”

Shortly after the acquisition, Delicious Brains representatives published a pinned thread in the forum, clarifying expectations for free support and response times. The official support forum for both free and PRO users can be found at support.advancedcustomfields.com, which is more active than the WordPress.org forums. Since the plugin is more developer-focused, the team is taking a looser approach to support by giving the community a place to help each other:

We rarely provide support in either forum. The exception is after a major release, when we keep an eye on both forums to spot any problems caused by the release.

The primary purpose of both forums is for people in the WordPress community who are having trouble with Advanced Custom Fields to help each other. Response times can range from a few days to a few weeks and will likely be from a non-developer. We jump in now and then when the description sounds suspiciously like a bug. 

The release of version 5.10 is a good sign that ACF will continue to make progress under its new ownership and a reassuring milestone for the small minority of users who were unsure about the plugin’s future.

ReactJS Frontend with CodeIgniter backend – How to keep Authentication?

Hi, I'm an jQuery/Angular Developer last 5 years, and now I've planned move to ReactJS. I'm learning ReactJS by my own, as comparing the similar stuff what I did in jQuery (or Angular). My plan is, just to make a Login-Logout App, with ReactJS front-end and CodeIgniter - MySQL are the backend and database, respectively. Also I know what is CORS, and I'm pretty clear about the REST concepts. Let me explain my react app in brief.

My App component, calls an API via fetch, and upon the response which tells either session is set (as user is logged in) or session isn't set (user logged out/session expired), then the component will render either the 'Login Panel' component or a 'Dashboard' component. It works fine, as I tested. This is my App component.

class App extends Component {
    constructor(props) {
        super(props); //compulsary
        this.state = { isUserAuthenticated: false };
    }
    componentDidMount() {
        var innerThis=this;
        fetch('http://localhost/forReact/index.php/general/authenticate',{
          method:'GET',
          Content_type:'application/json',
          headers: {'Accept': 'application/json', 'Content-Type': 'application/json'},
          mode: 'cors',
          cache: 'no-cache'})
        .then(res => { return res.json() })
        .then(data => { alert(data.message); this.setState({isUserAuthenticated:data.result}); })
        .catch(err => console.error(err));
        }
        render() {
            return (this.state.isUserAuthenticated?<Home/>:<First/>);
        }
    }
    export default App;

This is my CodeIgniter Controller's relevant method (the controller name is General.php)

public function authenticate(){
$session_data = $this->session->get_userdata();
if (is_null($session_data)) {
$this->sendJson(array("message"=>"No session","result"=>false));
}
else if (empty($session_data['username'])) {
$this->sendJson(array("message"=>"No username index","result"=>false));
}
else if ($session_data['username']=="") {
$this->sendJson(array("message"=>"Empty Username","result"=>false));
}
else{
$this->sendJson(array("message"=>"Valid Session","result"=>true));
}
}

This is the login component, which is being rendered in the App component, when there are no sessions set.

class LoginPanel extends React.Component {
  constructor(props) {
    super(props); //compulsary
    this.unRef = React.createRef();
    this.pwRef = React.createRef();
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleSubmit(){
  var toServer={"userName":this.unRef.current.value,"passWord":this.pwRef.current.value};
        fetch('http://localhost/forReact/index.php/general/login',{
          method:'POST',
          Content_type:'application/json',
          headers: {'Accept': 'application/json', 'Content-Type': 'application/json'},
          body: JSON.stringify(toServer),
          mode: 'cors',
          cache: 'no-cache'})
        .then(res => { return res.json() })
        .then(data => { alert(data.message); })
        .catch(err => console.log(err));
  }

  render() {
   return (
     <form onSubmit={this.handleSubmit}>
     <input ref={this.unRef} type="text" className="form-control" placeholder="Username"/>
    <input ref={this.pwRef} type="password" placeholder="Password"/>
    <button style={{margin:'1%'}} type="submit">Login</button>
    <button style={{margin:'1%'}} type="reset">Help</button>
     </form>);
   }
 }
export default LoginPanel;

Finally, this is the CodeIgniter Controller's relevant method (the same controller General.php)

public function login(){
$arrived = json_decode(file_get_contents('php://input'), true);
if (!empty($arrived['userName'])&&!empty($arrived['passWord'])) {
$fromDB=$this->Mdl_general->login($arrived['userName'],$arrived['passWord']);
if ($fromDB['result']) {
$this->session->set_userdata('username',$arrived['userName']);
$this->sendJson(array("message"=>$fromDB['message'],"result"=>$fromDB['result']));
}
else{
$this->sendJson(array("message"=>"Username and or Password is/are incorrect!","result"=>false));
}
}
else{
$this->sendJson(array("message"=>"Invalid or Missing Input Parameters!","result"=>false));
}
}

My issue is, when I logged in with the correct username and password (what I have in the mysql table, the alert message is successfully showing, however, it seems the session is not set by the php code,

$this->session->set_userdata('username',$arrived['userName']);

However, if I did the above 'set session' code via a separate controller function, it sets the session successfully. However, even after that, the App component's API Call, still getting the response as the session is not yet set.

What might be the reason? I tried the same via jQuery's Ajax Call and it works. I knew the fetch is much more different from the Ajax Call of jQuery. Could anyone explain, why this login component, didn't trig the PHP code to set the session?

The Fixed Background Attachment Hack

What options do you have if you want the body background in a fixed position where it stays put on scroll? background-attachment: fixed in CSS, at best, does not work well in mobile browsers, and at worst is not even supported by the most widely used mobile browsers. You can ditch this idea completely and let the background scroll on small screens using media queries.

Or get around it with a small fix. I suppose we could call it a “hack” since it’s a workaround in code that arguably we shouldn’t have to do at all.

The issue

Before I show you the fix, let’s examine the issue. We can see it by looking at two different approaches to CSS backgrounds:

  1. a background using a linear gradient
  2. a background using an image

Linear gradient

I want to keep the background gradient in a fixed position on scroll, so let’s apply basic CSS styling to the body that does exactly that:

body {
  background: linear-gradient(335deg, rgba(255,140,107,1) 0%, rgba(255,228,168,1) 100%);
  background-attachment: fixed;
  background-position: center;
  background-repeat: no-repeat;
  height: 100vh;
}

Here are the results in Chrome and Firefox, both on Android, respectively:

Chrome Android
Firefox Android

The gradient simply scrolls along with other content then jumps back. I don’t know exactly why that is — maybe when the URL tab goes up or disappears on scroll and the browser finds it difficult to re-render the gradient in real time? That’s my best guess since it only seems to happen in mobile browsers.

If you’re wondering about iOS Safari, I haven’t tested on iOS personally, but the issue is there too. Some have already reported the issue and it appears to behave similarly.

Background image

This issue with images is no different.

body {
  background: url(../assets/test_pic.jpg);
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
  height: 100vh;
}
The grey section at the top just indicates the presence of an actual URL bar in Chrome Android.

Another interesting thing to note is that when background-attachment: fixed is applied, the height is ignored even if we explicitly specify it. That’s because background-attachment calculates a fixed background position relative to the viewport.

Even if we say the body is 100vh, background-attachment: fixed is not exactly in accordance with it. Weird! Perhaps the reason is that background-attachment: fixed relies on the smallest possible viewport while elements rely on the largest possible viewport. David Bokan explains,

Lengths defined in viewport units (i.e. vh) will not resize in response to the URL bar being shown or hidden. Instead, vh units will be sized to the viewport height as if the URL bar is always hidden. That is, vh units will be sized to the “largest possible viewport”. This means 100vh will be larger than the visible height when the URL bar is shown.

The issues are nicely documented over at caniuse:

  • Firefox does not appear to support the local value when applied on a textarea element.
  • Chrome has an issue that occurs when using the will-change property on a selector which also has background-attachment: fixed defined. It causes the image to get cut off and gain whitespace around it.
  • iOS has an issue preventing background-attachment: fixed from being used with background-size: cover.

Let’s fix it

Call it a temporary hack, if you will. Some of you may have already tried it. Whatever the case, it fixes the linear gradient and background image issues we just saw.

So, as you know, we are getting in trouble with the background-attachment: fixed property and, as you might have guessed, we are removing it from our code. If it’s looking at the smallest possible viewport, then maybe we should be working with an element that looks for the largest possible viewport and position that instead.

So, we are creating two separate elements — one for the background-gradient and another for the rest of the content. We are replacing background-attachment: fixed with position: fixed.

<div class="bg"></div>
<div class="content">
  <!-- content -->
</div>
.bg {
  background: linear-gradient(335deg, rgba(255,140,107,1) 0%, rgba(255,228,168,1) 100%);
  background-repeat: no-repeat;
  background-position: center;
  height: 100vh;
  width: 100vw;
  position: fixed;
  /* z-index usage is up to you.. although there is no need of using it because the default stack context will work. */
  z-index: -1; // this is optional
}

Now, wrap up the rest of the content — except for the element containing the background image — inside a main container.

.content{
  position: absolute;
  margin-top: 5rem;
  left: 50%; 
  transform: translateX(-50%);
  width: 80%;
}

Success!

Chrome Android
Firefox Android

We can use the same trick hack with background images and it works fine. However, you do get some sort of background scrolling when the URL bar hides itself, but the white patch is no longer there.

.img {    
  background: url('../assets/test_pic.jpg');
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  position: fixed;
  height: 100vh;
  width: 100vw;
}

.content {
  position: absolute;
  left: 50%; 
  margin-top: 5rem;
  transform: translateX(-50%);
  width: 80%;
}
Chrome Android
Firefox Android

Here are my takeaways

A fixed-position element with a height set to 100% behaves just like the element with background-attachment: fixed property, which is clearly evident in the example below! Just observe the right-most bar (purple color) in the video.

The website which is being tested is taken from this article.

Even though, David Bokan in his article states that:

That is, a position: fixed element whose containing block is the ICB will resize in response to the URL bar showing or hiding. For example, if its height is 100% it will always fill exactly the visible height, whether or not the URL bar is shown. Similarly for vh lengths, they will also resize to match the visible height taking the URL bar position into account.

If we take into account that last sentence, that doesn’t seem to be the case here. Elements that have fixed positioning and 100vh height don’t change their height whether the URL bar is shown or not. In fact, the height is according to the height of the “largest possible viewport”. This is evident in the example below. Just observe the light blue colored bar in the video.

The website which is being tested is taken from this article.

So, it appears that, when working with a container that is 100vh, background-attachment: fixed considers the smallest possible viewport height while elements in general consider the largest possible viewport height.

For example, background-attachment: fixed simply stops working when a repaint is needed, like when a mobile browser’s address bar goes away on scroll. The browser adjusts the background according to the largest possible viewport (which is now, in fact, the smallest possible viewport as URL bar is hidden) and the browser isn’t efficient enough to repaint on the fly, which results in a major lag.

Our hack addresses this by making the background an element instead of, well, an actual background. We give the element containing the content an absolute position to stack it on top of the element containing the image, then apply a fixed position on the latter. Hey, it works!

Note that the viewport height is calculated excluding the navigation bar at the bottom (if present). Here’s a comparison between the presence and absence of navigation bar at the bottom in Chrome Android.

Is there a downside? Perhaps! We’re using a general <div> instead of an actual <img> tag, so I wouldn’t say the markup is semantic. And that can lead to accessibility issues. If you’re working with an image that adds meaning or context to the content, then an <img> is the correct way to go, utilizing a proper alt description for screen readers.

But if we go the proper <img> route, then we’re right back where we started. Also, if you have a navigation bar at the bottom which too auto hides itself, then I can’t help it. If the hack won’t cut it, then perhaps JavaScript can come to the rescue.


The post The Fixed Background Attachment Hack appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Architecting Database Systems for the Microservices World

Microservices diagram

Introduction to Microservices

Microservices are not new — they have been around for quite a while. However, it is because of recent innovations that the adoption of microservices architecture accelerated. Most importantly:

  • Cloud-native architecture
    • Cloud computing revolutionized the way we handle hardware. Even large companies now are moving towards the cloud because it is much easier to manage and scale despite the higher costs associated (costs eventually go down as companies cut down on resources spent for maintenance).
  • Containers and container management
    • These are also not newer concepts. The Linux operating system had these capabilities natively for a long time. Still, systems such as Docker and Kubernetes changed how we deploy and manage applications, democratizing the whole process with more features and tooling only a few years ago. As a result, it is much easier to slice hardware to our requirements and also to manage them using these tools, which opens up a whole new world of opportunities.

The idea of microservices comes from the service-oriented architecture world. Although they seem similar, they have a lot of differences. The concept of SOA is an enterprise-level concept, whereas microservices is an architectural concept. It focuses only on the application under consideration.