1676302800
Branded content has changed the way we approach advertising. Unlike conventional advertising methods, which mainly focus on showcasing a product and can be seen as invasive, branded content is “non-salesy” and communicates your brand’s values and vision. It’s immersive and leverages the power of storytelling. It’s different from traditional product placement, which highlights a product by featuring it prominently in a TV show or movie. It also differs from content marketing, which mainly focuses on targeting an audience, promoting calls to action, and generating positive ROI.
What can branded content do for your brand? How do you craft powerful and effective branded content? What are the best platforms you can use for branded content? Here’s an in-depth look at branded content platforms and why it’s worth adding branded content to your marketing strategy in 2023.
Branded content is a marketing technique that refers to creating content that showcases your brand’s message, values, and story. It’s more accessible and designed for a wide range of audience segments. The goal of branded content is to grow your business through awareness and providing crucial information about your brand.
With branded content, you’re essentially creating memorable marketing experiences for your audience. It takes audiences through an immersive experience and allows you to build a connection with them while equipping your brand to garner more positive brand perceptions.
Furthermore, branded content is used to start a conversation around your brand and create an impact on your audience. Given that it uses storytelling, branded content can be used to tap into your audience’s emotions while offering them something of value at the same time in the form of entertainment. It’s also not invasive, which means it allows you to attract customers more naturally.
Over the years, branded content has grown into a considerable advertising force. During the latter part of 2020, spending on branded content grew by 32%, with 31% of advertisers using it to increase product consideration. The same report highlights more uses of branded content, which include driving sales (29%), reaching new target customers (29%), and building long-term brand equity (25%), along with conveying the brand’s values or purpose (24%).
Branded content can help fuel your growth. It’s a versatile technique that can be used across different channels and presented in different formats like video games and podcasts. It also allows brands to collaborate with other creators, such as influencers, to generate content. For example, brands can turn to user-generated content and allow actual users or content creators to create videos or posts to share their story.
Compared to traditional advertising methods, such as display ads, branded content is 22x more engaging. Moreover, given that today’s consumers want brands to pitch in when it comes to tackling social and political issues, branded content has proven to be a valuable tool in any advertiser’s arsenal. When using branded content to address such issues, it’s important to remember that your message should be authentic and in line with your brand’s values. Otherwise, you may run the risk of launching a campaign that comes off as fake.
Furthermore, branded content can drive up to 59% more brand recognition compared to other digital advertising formats. This benefits businesses because this means customers are more likely to remember your brand. It also generates an average of 86% for brand recall and gives brands a higher lift when it comes to brand perceptions.
When done well, branded content has the power to expand your reach, nurture customer trust and loyalty, generate high-quality conversions, and build brand awareness. It can help put your brand on top of customers’ minds when they’re looking for a solution for a particular pain point.
Grin is an all-in-one branded content platform that lets you take your branded content strategy to the next level. With Grin, you can create and simplify content rights agreements for new partnerships or campaigns, repurpose content, promote and distribute branded content across social media channels like TikTok and YouTube, and manage all your brand collaborations.
Furthermore, the platform delivers comprehensive reporting and analytics with custom tag tracking. This allows you to monitor and set up multiple campaigns without overlooking all the little details. It lets you efficiently manage creator partnerships, so you can transform your brand into a more valuable one. Use Grin to discover the right creators and get them onboard for your future campaigns. Access all your content (influencer marketing content + user-generated content) in one platform and generate metrics for all your campaigns. Grin also helps you manage creator payments, from payment tracking to payments, as well as commissions and tax compliance.
The platform integrates with social platforms, eCommerce software, and other marketing solutions, including Klaviyo, Slack, Magento, Instagram, WooCommerce, Shopify, and Gmail.
NapoleonCat is a social media marketing software that goes beyond social media management. It can also be used to publish content and analyze your and your competitor’s performance. It supports an array of platforms, including Facebook Pages, Instagram business accounts, Instagram Ads, and YouTube channels.
It offers the following solutions:
It also lets you issue and manage customer service tickets, monitor and respond to Google reviews, and enhance collaboration through features, such as a shared content calendar, competitive benchmarks, and customer service workflows.
NapoleonCat integrates with several major social media channels, including Facebook, Instagram, Twitter, and YouTube.
Influence.co is a branded content platform designed to help businesses, creators, and influencers grow. With Influence.co, creators can grow their professional network and monetize their influence. For businesses, you can use Influence.co to connect with the right influencers and creators for your brand. Use the platform to reach new audiences, drive brand awareness, generate interest, engage people, and encourage them to take action.
Influence.co lets you discover new influencers with its advanced search tool. You can also use the platform to let influencers find your brand by creating campaign briefs. Use Influence.co to manage your partnerships, monitor your campaigns, and create long-term relationships with your partners.
Fanbytes helps brands leverage branded content through influencer marketing, content creation, and organic and paid social campaigns. It connects brands with leading Gen Z creators through its extensive award-winning influencer network and makes it more convenient for brands to approve influencers and their content.
Fanbytes gives you access to a creative strategy team that can help you formulate innovative campaign strategies for influencer-led branded content. Furthermore, the platform can bolster your branded content strategy, grow your reach, and generate authentic engagement through influencer-led campaigns.
It has worked with some of the world’s leading brands, including Ubisoft, Universal Music Group, Sony Music, Benefit Cosmetics, and Burger King.
Looking to create powerful and effective branded content? Rock Content can help you build content experiences that will win over your audience, build brand awareness, and generate revenue. To date, it has worked with more than 2,000 brands, marketers, and agencies to create and deliver out-of-the-box and compelling content experiences.
Ion, its interactive content platform, makes it easier for brands to craft more memorable interactive experiences while allowing them to collect relevant data at the same time. Wondering how you can keep your audience engaged? Rock Content has a solution for that, too, with its Stage, a service that can be used to integrate the experiences you’ve built into your website.
Some of the companies that have used Rock Content to build premium content experiences include IBM, Microsoft, Yahoo, Cisco, Marvel, and Oracle.
If you’re in need of one platform for SEO, content marketing, social media marketing, and more, then you may want to consider SEMrush. Through its Content Marketing Platform, you can create effective branded content that resonates with your audience. Use data to uncover vital insights about your audience and their needs, find topics you can use to create branded content, optimize your content to appeal to new customers, and start automating routine tasks. The tool also helps you create comprehensive content plans, leverage SEO, monitor brand mentions, monitor performance, and run content audits.
Pressboard, which was acquired by impact.com, gives you access to award-winning tools for branded content and more. It’s an all-in-one platform that lets you manage, measure, and monitor campaigns for sponsored content, native advertising, eCommerce, and social media. With it, you can utilize comprehensive data to create better campaigns and improve performance, generate actionable and shareable reports, and manage multiple campaigns all at once thanks to features like intuitive workflows and multi-user access.
Enjoy access to in-depth benchmarks that you can use to track your performance and see how the competition is doing. Best of all, Pressboard helps future-proof your branded content through innovative cookie-less technology that’s compliant with GDPR, CCPA, and IAB TCF guidelines. Pressboard has worked with top publishers, such as The New York Times, Bustle, and USA Today and collaborates with industry experts to address issues in granular performance tracking for branded content.
Tribe is an influencer marketing platform that helps businesses develop better branded content using technology and expert teams. It’s an end-to-end platform for building, managing, and measuring your own creator community. Use the platform to discover new creators from its pool of over 70,000 content creators and influencers. If you’re already working with content creators, Tribe lets you import them into custom groups, so you can quickly start running branded content campaigns.
Tribe lets you manage your campaigns more conveniently. Simply launch a campaign and watch tailored pitches roll in from the right creators. Plus, the platform lets you automate tasks, such as content approvals and payments. It lets you utilize data, so you can make better decisions. Get to know your audience and collaborators better through audience demographics and estimated performance data for channels like Instagram and TikTok.
Best of all, Tribe has a Brand Safety feature in place. Its proprietary AVS system ensures that brands work only with authentic creators who have a real following. Lastly, the platform allows brands to license quality branded content.
Branded content shouldn’t just be meaningful. It should also be unique so that it stands out from the content generated by your competitors. Highlight your brand, its identity, story, and values. When creating branded content, keep your audience in mind and make sure that you come up with something that they can connect with on an emotional level. And don’t skip on research; try to find out what your competitors are doing. What strategies are they employing? What channels or formats are they using?
Be strategic in choosing the channels where you publish your branded content. Furthermore, consider the types of platforms you’re going to use. This will also influence the type of format that you’ll be using. For example, if you’re planning to use YouTube, you can create longer videos. But if you’re thinking of using the same content for platforms like TikTok or Instagram, then you may want to edit the clip and make it shorter to fit such platforms. One way to find out which channels and platforms work best is to determine what type of content your audience typically consumes and where they spend most of their time.
By knowing who your audiences are, you can create more effective campaigns. Use data to your advantage and find out what resonates with them or what their interests are. This can help you create branded content that resonates with their values or appeals to their emotions.
While you’re at it, don’t forget to personalize your branded content. Find out what your audience’s pain points are and use that to create campaigns that address their specific needs.
Work toward making your branded content relatable and easily accessible. This means crafting branded content that uses a voice and tone that match your brand values. Make sure that you are consistent when it comes to the tone and voice and that you’re publishing content on channels that your audience frequents.
We’ve already established that branded content is versatile and opens up opportunities for collaborations. To expand your reach and grow your audience, you may want to work with content creators, influencers, or creatives who can promote your content on their channels and, consequently, to their followers.
Regularly monitor and assess your campaign performance to see if you’re meeting your goals. Find out how your audience is reacting to your content or what they have to say about your brand. This helps you see whether or not your branded campaign is succeeding or if it needs a bit more work.
Original article source at: https://influencermarketinghub.com/
1676298360
Getting your brand noticed is getting much more difficult by the day. Not necessarily because of the sheer number of businesses in your market that you need to compete against, but also because audiences have started to drown out the noise. And, if they did “hear” what you have to say, the next challenge is to keep their attention for long enough to get your entire message across.
One way to get potential customers to sit up and take notice is to let someone else do the talking for a change — like an influencer.
After all, an influencer’s followers chose to sign up to receive notifications about them. In other words, they’re ready and eager to see, read, or listen to whatever it is that their favorite social media influencers are going to post about next.
If you’re not leveraging the power of influencer marketing yet, specifically when it comes to content creation, continue reading to find out what you’ve been missing out on. As you’ll learn, it’s actually pretty straightforward and will open a world of new opportunities.
In short, influencer-generated content refers to any content that an influencer sources that includes a positive mention of your brand. And, it doesn’t need to be brand sponsored content.
There are various skills that influencers can bring to the table to create content for your brand that can be used on multiple marketing channels. While influencer content is mostly associated with social media, you can also showcase it on your business website.
If you’re thinking that it sounds pretty much the same as user-generated content, you wouldn’t be wrong. The only real difference is that user-generated content can be created by anyone. For example, it can be a product review shared by a customer with no real significant social media presence.
That being said, it doesn’t mean that the influencer needs to have millions of followers (more about that later). Micro influencers can be very effective (if not more) at spreading the word about a brand, its events, products, and/or services.
Influencer Marketing Hub’s The State of Influencer Marketing 2022 report, in association with Refersion, has found that there’s been a sizable increase in content in recent years. More than 80% of participants indicated that they’ve increased the amount of content that they produced. As there’s been an increase in influencer marketing too, our deductive skills tell us that much of this new content must be influencer-created content.
The following five benefits of influencer content clearly show why your brand should also follow that path:
As influencers, especially nano and micro ones, generally interact with a smaller network of followers, their content and interactions are seen as more authentic. According to Neal Schaffer, an influencer marketing keynote speaker and consultant, there’s such a huge demand for authentic content that brands won’t be able to compete in feeds anymore without the help from an influencer. The alternative — paid social — is only going to become less effective.
Also, as social media users are craving more authentic content, the algorithms of social media platforms are also rewarding the efforts of creators.
So, it’s really a win-win. Not only do you receive more authentic content, but you’ll also enjoy better visibility on social platforms.
Consumers tend to trust the influencers that they follow more than paid ads or brand sponsored content. It’s crucial that your audience finds your content credible and as influencers are found to be trustworthy, the content that they create and share will also be deemed as credible.
Content shared by influencers can generate more impressions and drive better engagement. This makes it especially suitable for announcements, like a new product, that are typically time-sensitive.
Not only will influencer-generated content help you to drive more sales, but it can also improve the search engine rankings of your website. In addition to driving more traffic to your site, blogger influencers’ websites probably have a high-domain authority. This means that if they link back to your website, it can improve your domain authority as well.
Content form influencers will require less money and time to create. Plus, if you keep in mind that you’ll be able to repurpose the content, it becomes even more lucrative.
In fact, according to our influencer marketing survey, nearly 70% of respondents planned to increase their influencer marketing spend in 2022. This just proves that brands and marketing teams are well-aware of the effectiveness of influencer marketing.
You can only enjoy these advantages of influencer-generated content if you identify the most suitable ones for your niche and actively manage your working relationship. Here’s what to consider during your search and how you can help them to help you better:
If you have to choose between engagement rate vs follower count, choose engagement rate. Hundreds of thousands of followers doesn't mean that they’re engaged and involved with the content that gets shared.
While our 2022 report about the influencer marketing industry has found that influencer fraud is down, it’s still a possible pitfall that you need to be aware of. So, it’s key that you use tools to double-check that the influencer is indeed authentic by being on the lookout for comments from bots and other forms of inauthentic engagement.
Not only should you pay attention to how followers engage with the influencer’s content but also vice versa. The way that an influencer responds to comments will tell you a lot about the type of connection they have with their audience. Plus, influencers taking the time to respond to comments is one of the best to improve engagement rate. So, it’s the opposite of a vicious cycle.
Engagement rate can only bring you so far. If the influencer isn’t passionate about your brand and its products or services, potential customers will be able to tell. After all, what makes influencer marketing so powerful is that it’s seen as more authentic. However, if they’re pretending to be excited about the brand, you won’t be able to capitalize on that huge benefit.
Consistency is key. Even if you’ve been creating content mostly in-house till now, you would’ve needed a style guide, which is especially important for posting on social media.
Typically included in this type of doc are guidelines about:
Influencers will need similar guidelines. This will help to streamline communication and give them a better idea of the type of content that you have in mind.
While you absolutely should share clear brand guidelines, your influencers should still have enough creative freedom. After all, they know their audiences much better than you and will know what type of content will get the best engagement. Remember, they also create content for a living.
What’s more, giving them the freedom to create will also help with building better influencer relationships tremendously. Basically, at the end of the day, they should still keep their (tone of) voice.
If you’ve ever partnered with a digital marketing agency, the chances are good that you had to lock in their services for a couple of months minimum. And, no, it’s not because of money. Getting results, takes time.
The same applies to entrusting some of your content creation to influencers. Sure, you can launch a single influencer marketing campaign, but if you want to receive more authentic content, try to build a long-term relationship with your network of influencers.
One of the benefits of working with influencers to generate content for your brand is that you can repurpose it. This way, you can use it on various other channels too.
For example, a how-to video on YouTube can be turned into a how-to guide shared on your blog. A short-form lifestyle video on TikTok can be included in your marketing email about product offers aimed at summer. You get the idea.
However, this becomes only possible if you have image rights. You might be eager to get the ball rolling, but make sure that you’re on the same page about who’ll own licensing rights after the collaboration. And, by the same page, interpret it quite literally. It’s always best to get this in writing.
Entrusting some of the content creation to others can help to save time. However, if you have to manage every aspect of your collaborations with influencers alone, the time saved will only go towards tasks like eliminating fake influencers, communication, licensing rights, payouts, and reporting.
To reap the benefits of influencer content, it’s strongly recommended that you use an influencer marketing platform or agency, even if it’s only for influencer discovery. There are many great tools and agencies to choose from like:
While increasing sales and awareness are still the main objectives of brands when running an influencer campaign, more than a quarter (27.6%) use it primarily for user-generated content.
Influencer-generated content doesn’t have to be limited just to social media videos and photos. From how-to guides to AMA live-streaming sessions, there are various ways that you can incorporate content created by influencers into your business website too. Here are some ideas of the different types of content that you can ask your influencers to create.
According to a graph shared by Insider Intelligence, how-to tutorials is the type of influencer content that both UK and US social media followers want to see more of. While Q&A videos aren’t as in demand as how-to content, consumers often search for this type of content online as well. All in all, content in which your influencers answer frequently asked questions can show to your audience that they’re well-versed about your offering, helping to make their voice even more credible.
Videos (or photos) that show how a product or service can complement consumers’ lifestyle can help with brand loyalty. When potential customers abandon their cart, including this type of content in follow-up emails can do wonders for conversions.
Lifestyle photos and videos shot by influencers can easily be included in many other types of email campaigns too. For example, it can quickly turn a dull, text-heavy email newsletter into an attractive email campaign that your email list will actually look forward to open.
Product reviews (like, for example, a before-and-after video) can be very informative. They’re also popular among consumers, with 32% indicating that they would like to see influencers share more product reviews.
This type of content can give influencers an opportunity to share info with your target audience that can help improve brand credibility, while at the same time setting your product apart from available alternatives. And, if showing off your products’ unique selling points is high up on your agenda, why not suggest a side-by-side comparison of a number of products?
Alternatively, if driving excitement is more important than highlighting specs, how about an unboxing video?
Whichever way you choose to review your products, this type of content can fit right in on a product description page or testimonials/reviews section. It’s great for social proof!
If you don’t have a dedicated in-house team of writers, maintaining a company blog is a nightmare. A solution is to delegate some of the writing, and who better than an influencer in your niche?
Not only can featuring a guest post written by an influencer get people excited about your blog (again), but as they have a great understanding of the issues that plague your audience, you’ll get a unique insight that your own writers might not have. Not all the content that your influencers generate has to be visual, there’s still a place for a well-written long-form blog post and it can be very effective to mix it up from time to time.
While similar to user-generated content, influencer-generated content has the benefit of reaching a bigger, more engaged group. It’s one of the best ways to put your brand in a positive light on various platforms.
Content from influencers doesn’t just have to be social media posts. Think bigger (or even more traditional). Guest bloggers can also delight your online community.
Whichever forms of content you decide to use, know that it can put your marketing on steroids and supercharge your efforts with very little work from your side. Concentrate on finding the best influencers for your niche audiences and nurture your relationship with influencers and there’s no reason why the content creation process needs to lead to burnout for any party.
Original article source at: https://influencermarketinghub.com/
1675737060
Content creation is the cornerstone of marketing. It’s a way to get your message out to the world and create a buzz about your brand, product, or service.
For it to get results, though, it needs to resonate with your audience. And, to achieve this, you need to understand where they are coming from and what they want to read.
So, to be a successful content creator, you’ll need to know much more than simply how to take a photo, write a blog post, or capture a video. You need to keep up with trends and know how to research.
If the idea of research didn’t scare you, continue reading to find out how you can join this exciting, fast-paced industry. We’ve scoured the web to summarize the main steps and included a couple of tips to help you set yourself apart from the competition from the get go.
As mentioned earlier, content creation is not limited to the written form and so there’s not just one type of content creator that you can become. In the digital marketing space, content creators manage different digital “departments”. While some companies may use a dedicated content creator for a specific type of medium, others may use one to manage all avenues. Here are some of the main types of content creators that you get and a brief look at their job description:
Content writers create original and engaging written content that can be used on various platforms. They are often also tasked with creating text for the company's various marketing channels, such as social media, and email. That said, blogging is usually the most common channel used by content writers.
Videographers are in charge of filming and editing video content. It’s their responsibility to ensure that the video content is up to the company's standards. YouTube has become the preferred platform for video content creators, but with increasingly more video content getting shared on sites like Instagram, Facebook, and TikTok, there are multiple platforms where videographers can share their craft.
Photographers are the creatives behind many of our images on social media and on websites. They use their skills to create compelling photos that tell stories or capture the world's beauty around them. From fashion to beauty to food to fitness, you’ll find photographers in many different fields. While they have a lot of creative control over what they shoot, they also have to consider what their client wants them to shoot. This means that at times they might have to tackle a less interesting project like shooting product photos.
Podcasts are a great way to share messages. As a podcast host, you often have to act as the middle or neutral party between the guest and the listeners. You’ll be responsible for conducting interviews, providing commentary, and, ultimately, creating an engaging experience for listeners.
One of the most important responsibilities when hosting a podcast is interviewing the guests and asking them relevant questions to keep the interview interesting. So, podcast hosts often work with scripted content ideas. This can be difficult because you need to think of questions on the spot, but it is also rewarding to learn more about your guests and meet interesting people along the way.
Social media influencers have a significant and loyal following on social media. They use their following to promote products and services or convey their messages.
There are many different types of social media influencers that include:
Some examples of the content that social media influencers can create and share include:
Whether you decide to focus on video, blog posts, or podcasts, the following steps will help you to carve your rightful place. While you don’t necessarily need to complete the steps in this exact order, there are certain things, like establishing your target audience, that you’ll need to do first before you can move on to the next step.
Knowing who your target audience is, is crucial to the success of your content and marketing strategy. A brand needs relevant and innovative content to pique the audience’s interest. Though, it doesn’t stop at grabbing their attention, you’ll also need to find ways to keep it. And, knowing what they’ll resonate with will make this challenge much easier.
The benefit of using social media platforms is that they already have a loyal following of users. Just take Facebook with over 2 billion active users, for example. The picture looks pretty much the same for YouTube (with 2.6 billion users), WhatsApp (with more than 2 billion), and Instagram (with an estimate of 2 billion users). So, social media is a good place to start as you already have a captive audience.
It’s all good and well to be on all platforms (and it’s probably worthwhile for more exposure to the brand), but choosing one or two platforms will help you to concentrate your efforts and energy on making that a very successful source. After all, there’s no point in using Snapchat or TikTok, if your ideal audience is B2B business owners.
Also, not all social platforms are created equally. Not only do they attract different audiences, but some platforms have been created for a specific type of content. WordPress is synonymous with blogs. YouTube is the home of video. You get the idea.
Here are some examples of the social and digital platforms that content creators often use to help boost their reach:
YouTube is perfect for vlogging (video blogging). Content creators can utilize the platform for a wide range of videos like how-to videos, product reviews, unboxing videos, tutorials, etc. Not only is YouTube versatile, but video content is also one of the leading forms of digital entertainment. When people have limited time, they would often much rather watch a short video than to read a long article.
What’s easier and faster to digest than a short-form video? A picture. After all, a picture is worth a thousand words and this is especially true for Instagram. Sometimes you can’t type everything you want to share, but in many instances you can do just that with the perfect picture.
Businesses can also use the platform to promote products or sell products directly. Plus, arguably the biggest advantage offered by Instagram is that posts are easily shared, making it perfect for engagement.
Facebook has always been a flexible option for businesses as it allows various marketing methods. From posting short articles, sharing and reposting stories, video content, and loads more, it’s a great way to promote a brand or service.
A content plan can be viewed in some ways as a business plan. It sets the brand up for various scenarios and how to work through each. Best of all, it improves coordination.
If you’ll be working as part of a bigger marketing team, a content plan is a must as it allows teams to work seamlessly together, and ensure everyone is on the same page. There are a number of great project management software tools like Monday.com, Asana, and Trello that can help you to keep things seamless and communication on a roll.
Using an effective content plan also helps to prepare you for each month’s topics and events. For example, if you’ll be focusing on social media specifically, there are a number of social media content calendar templates that you can make your own. Even if you’ll be running the show on your own, a unified calendar helps you to look at your posts from a strategic vantage.
The brand’s voice is how the business speaks to its target audience. To help you find and establish your voice, you may need to complete customer surveys and polls. These efforts will help you to identify the age, gender, profession, and geographical area of your target audience. This is a good example of where you’ll first need to complete one step (identify your target audience) before you can move to the next one (establishing your unique brand voice).
When you invest in essential content tools like Grammarly and Canva, it goes a long way in helping you to refine your content even more. Some of the most popular third-party tools trusted and loved by content creators are:
SEMrush is a must-have tool for any content creator who’s looking to establish their online presence. The tool provides valuable feedback that helps improve SEO, PPC, PR content management, marketing insights and keyword research to name only a few of its features. It basically does it all, making it extremely convenient and cost-effective.
Canva is another exceptional content tool that will help craft great-looking presentations, graphics, infographics, posters, and loads more. Not only is it affordable (it even has a generous free plan), but it’s also very intuitive thanks to its drag-and-drop editor.
If you’ll mainly be working as a content writer, a professional grammar checker, like Grammarly, is a must-have tool. As a matter of fact, even if you’ll not be using the written form as your main medium, it’s still a good idea to invest in such a type of tool. After all, basically every piece of content that you’ll create for the web has a written component to it, whether it’s a short caption or a longer video description. There are many grammar tools and their prices differ from one to the other, but, overall, Grammarly offers some of the best value for money.
For example, Google Ads are excellent for revenue generation, and Google Drive gives teams the liberty to collaborate on simultaneous projects in real time. Then, you can also check out Google My Business and Google Trends.
All businesses need a portfolio to show off experience, talents and what other happy clients have to say. If you’re working in the content creation industry, it’s even more important to take the time to create a portfolio that really manages to communicate your expertise and unique selling points. In addition to including examples of your most successful completed projects, you can also include information similar to an About us page so that potential clients can get a sense of your brand voice and style.
If you create content, having a website and business cards are just some of the more traditional ways that you can use to market yourself. Digital networks and social platforms will also help to boost your online presence needed to thrive in this day and age. Even if you don’t plan on working as a content writer, a blog can be a helpful resource to get the word out about your content creation services (but a little bit more about that later).
Social media serve as digital lines that you can use to establish an authentic connection with your target audience. With a solid social media presence, you can reach your audience and increase the credibility of your services. Even if you don’t plan on becoming a social media influencer, it’s still important that you devote some time to creating content to advertise your own brand on social platforms like Instagram, LinkedIn, Facebook, etc. Plus, it can be a great way to generate social proof.
The good news is that you need no degree to make high-quality content or to be called a content creator. Still, taking extra courses to sharpen your skills and insights is worth the investment.
Aspiring content creators may consider courses about digital marketing, copywriting, content strategy, social media content creation, and content management to name just a few. While there are loads of paid courses online, there are also many free courses offered by credible platforms like Udemy, LinkedIn Learning and Hubspot. For example, yours truly offers a 10-module introduction course to influencer marketing for those of you aspiring to become social media influencers.
Finally, the question that’s been on your mind all this time. Will becoming a content creator pay off? Can you make money?
Whether you tackle content creation full time or you’re a freelance content creator, there's definitely revenue potential. It will take some time before you start seeing fruits (just like with any other business), but if you’re disciplined and you improve and expand your skills continuously, there’s a market.
To give you an idea, the top content creators on YouTube are making millions. Though, we’re not saying that you’ll earn six figures, but there’s definitely earning potential.
For successful content creators, creating content forms part of their lifestyle. After you’ve completed the key steps discussed above, there are a few other things that you should do on a continuous basis to ensure that you can continue to churn out content that’s relevant and gets results. Here are some key habits that you can develop:
Consistency is a critical part of being a successful content creator, no matter what niche you’re serving. All content creators must post regularly. Not only will this ensure that your skills remain sharp, but it will also help to keep you at the top of search engines and boost brand awareness.
Keeping track of key performance indicators (KPIs) is important as it will empower you to see what type of content is working and what isn’t. Metrics that you want to measure include follower count, average social media engagement rate, and post reach.
Blogs are great for SEO. Not only will it help to establish your online presence, but you can also repurpose the blog posts as an infographic, Instagram post, email newsletter, etc. later on.
The above-mentioned steps and tips offer a useful and holistic approach to content creation. Not only will it help you to create better content more often, but it will also make the process less labor-intensive.
At the end of the day, there are many ways to create content, but they all rely on the same basic principles. Know your target audience, know thyself (aka your brand), and know the goals to which you’re working. Even if you don’t make millions like Ryan Kaji, it can be an extremely fulfilling career that you can start today.
Original article source at: https://influencermarketinghub.com/
1671802800
In this article, we will explore content marketing. Content marketing is giving traditional marketing strategies a run for their money. This isn’t surprising considering how effective the right content marketing strategies are. Few businesses find offline marketing strategies to be as effective by comparison.
But, the number of naysayers for digital marketing techniques is reducing. This is thanks to several reasons we’ll talk about in the next sections. And, we’ll talk about how content marketing is effective for any industry. This will help you understand how content marketing will be useful for your business.
The tips we’ll cover here will act as a guide to help you use content marketing for your business.
Content marketing is an integral part of any digital advertising campaign. And this isn’t just because everyone is using content marketing these days. Content marketing consists of several processes that help you sell your products online. This form of marketing is also a useful advertising tool for the service industry.
One reason why content marketing is popular is that it’s versatile. You can use this kind of marketing on several channels to promote your products. Blogs and social media are especially useful mediums for content marketers.
Large social networking platforms like Instagram are perfect for marketers. These platforms allow you to connect directly with your audience. It even allows you to receive feedback in real-time. Thanks to this, you know how your audience feels about your content marketing efforts.
You can even use content marketing for more traditional marketing mediums. For instance, you can use content marketing for print publications and press releases. Your choice of marketing medium doesn’t matter here.
What matters is to increase brand awareness among your audience. Content marketing can help you educate your leads on what your brand is all about. It can also help your old customers learn about new product offerings.
Another reason why content marketing is great is that it helps you boost conversions. A better conversion rate will help you increase your revenue in the long run. But, monetary reasons shouldn’t be the sole motivation for using content marketing.
You should know that content marketing can help you improve your customer relationships. This will allow you to increase customer loyalty to your business. After all, loyal customers want to stay up-to-date on what you’re offering them.
Lastly, content marketing can help you to establish your presence online. This in turn will help you stand out among your competitors.
You now have a basic idea about why content marketing is good for your business. So, let’s discuss the types of content marketing available for different industries.
B2B content marketing involves a set of strategies to engage your target audience. This kind of content marketing revolves around making a connection with audiences. So, you would need content that engages and educates your audience.
But, it’s not easy to find out what kind of data your audience would find informative. This is where data collection comes in.
Content marketers used blogs and social media posts on what customers wanted to read. But, these days, there seems to be a shift in the trend for content marketing. Content marketers are focusing on presenting valuable information to their readers.
They’re able to do this based on useful content that they have at their disposal. Data analytics are commonly used these days to improve content marketing efforts. The best content marketing tools give you actionable data.
Actionable data consists of information about your audience’s preferences. It includes information on how your audience reacts to online marketing campaigns.
You can use this data to connect with your target audience. Using actionable data will also help you increase your brand visibility online. This in turn will increase your click-through ratio (CTR), which is always a good thing.
Some of the most popular companies in the world are using B2B content marketing these days. This includes up-and-coming companies in the tech sector. Slack is one company that has been using B2B content marketing off late.
The company figured out that case studies can be useful to engage audiences. This company uses case studies to inspire viewers. Their case studies are based on customers that have found success using Slack.
This approach gives customers a chance to see how Slack has affected other users. Most companies publish customer testimonials for the same reason. But, these testimonials sometimes appear exaggerated or promotional. Using case studies instead was a stroke of content marketing genius here.
No list of content marketing is complete without a mention of B2C content marketing. Many people confuse it with B2B marketing but it’s not the same. This kind of content marketing is meant to be entertaining for viewers. So, B2C content should be more engaging than most other kinds of content out there.
In this kind of content marketing, you’re speaking directly to your customers. So, what you’re saying to them should be understandable and relatable. Also, B2C content should resonate with your audience and strike an emotional chord.
The biggest companies in the world use B2C content marketing to sell their products. A good example of a company that uses it would be Apple. Apple uses a marketing copy for every new product it launches.
This is meant to help users understand what they can gain from their products. It also allows users to feel closer to the brand. B2C content marketing involves telling stories to promote products.
But, it’s important to remember the scope and timing of these stories. Your marketing strategy would need to consider several factors before telling these stories. You can let audiences in on the story of your brand. But, you’d need to do it in a way that appeals to them.
Source: contentmarketing.io
Alt text : Content marketing goals for b2b and b2c
Consider using the medium that’s suitable for your story-telling. Social media channels and blog posts are pretty popular mediums for B2C marketing. These mediums allow you to connect with customers and receive feedback from them.
In this way, you can learn where you’re going wrong with your marketing efforts.
Another important medium for content marketing is social media. Social media marketing is apt for pretty much every industry. But, some industries have made a greater impact with social media marketing. The fashion industry is surely among these industries.
The largest and smallest fashion brands alike showcase their products on social media. This could be because customers often want to know what apparel looks like before they buy it. Think about it, no one is going to buy a pair of shoes before seeing them first.
This has led to scores of brands posting pictures and videos on social media. They use creative methods like influencer marketing to sell their products online. The influencers they work with use creative means to highlight what a product has to offer.
The introduction of short videos like Instagram Reels has boosted content marketing too. Businesses are now using these informal marketing means to connect with audiences.
Creative content marketing is a popular form of content marketing today. You’ll find this kind of content marketing everywhere you look online. The reason behind its popularity may be because it’s engaging.
Creative content marketing includes social media marketing and blog posts. It also includes the use of infographics like custom images. The versatility of this kind of content marketing makes it accessible to brands of all sizes.
Creative content marketing covers everything from podcasts to live chats. But, some forms of creative content marketing are more suitable for your business. For instance, if you’re going on vacation, you might check out Airbnb. This reputed company uses infographics to give you information on travel trends.
These pieces of data are vital to travelers looking to plan their trips. Airbnb used creative content marketing in this way to promote its services. It also made it easier for viewers to share this information online. This in turn increased back linking to its website.
Interactive content marketing relies on audience participation to promote your products. For this, you would need to create content that can engage an audience. If your content is engaging enough, your audience might stick around.
A good example of interactive content is web quizzes. And the best examples of web quizzes are BuzzFeed. Anyone who has taken a BuzzFeed quiz knows that it’s hard to quit these halfway. So, chances are, people stick around and complete an entire quiz.
This allows BuzzFeed to post several ads on its quiz pages. It can use the relevant algorithms to determine which display ads to post. This allows them to make a good amount of revenue on a relatively small investment.
Interactive content is also useful because it allows you to keep consumers engaged. This lessens the chances of your customers navigating away after clicking on an ad.
Content marketing looks like it’s here to stay and for good reason. Its adaptability makes it appealing to all kinds of businesses. But, you should know that it doesn’t come without its challenges.
Original article sourced at: https://www.techwebspace.com
1669635364
When manipulating DOM elements in the browser, you can use the textContent
property to retrieve the text content of a certain element and all its descendants.
For example, let’s say you have the following HTML <body>
tag:
<body>
<div id="partOne">
<p>Roses are red</p>
<p>Violets are blue</p>
<p>Sunflowers are yellow</p>
</div>
</body>
You can use textContent
property to grab the text content of the <div>
tag as show below:
let str = document.getElementById("partOne").textContent;
console.log(str);
The output of textContent
property will be as follows:
Roses are red
Violets are blue
Sunflowers are yellow
As you can see from the output above, The textContent
property only get the text inside your element, but not the HTML tags. When you need to get the HTML tag as well, you need to use the innerHTML
property instead of textContent
property:
let str = document.getElementById("partOne").innerHTML;
console.log(str);
The output of innerHTML
property will be as follows:
<p>Roses are red</p>
<p>Violets are blue</p>
<p>Sunflowers are yellow</p>
You can also change the textContent
property, which will remove all existing child elements, replacing it with a single text as follows:
document.getElementById("partOne").textContent = "Hello World!";
The HTML <body>
tag will be modified as shown below:
<body>
<div id="partOne">Hello World!</div>
</body>
Please keep in mind that the textContent
property is not supported by Internet Explorer 8 or below.
Original article source at: https://sebhastian.com/
1668509120
The PHP file_get_contents()
function is used to read a file content and return it as a string.
Most of the time, this function is also used to get the content of a file.
But when you need to read a remote file, the function may not work and give a warning response instead.
For example, the following code:
<?php
$res = file_get_contents("https://google.com");
Produced the following warning:
Warning: file_get_contents(https://google.com):
Failed to open stream: no suitable wrapper could be found
in ... on line ...
To access a remote file using the file_get_contents()
function, you need to activate the allow_url_fopen
configuration.
You need to open the php.ini
file loaded by your PHP server and set the allow_url_fopen
configuration to On
.
If you can’t find where your php.ini
file is located, then run the phpinfo()
function by creating a new file:
<?php
phpinfo();
?>
You need to find the php.ini
location as shown below:
Open the php.ini
file, then activate the allow_url_fopen
config:
allow_url_fopen = On
Restart your Apache or Nginx server, and you should be able to read the content of a remote file.
Sometimes, you may see that you can use file_get_contents()
from a local machine but doesn’t work from a server.
This is because your server may have security protocols that prevent file_get_contents()
from working.
For an alternative solution, you can use the cURL library to read the content of a remote file.
Here is an example of using cURL:
// 1. initialize cURL
$ch = curl_init();
// 2. set the URL to access
$url = "https://google.com";
curl_setopt($ch, CURLOPT_URL, $url);
// 3. set cURL to return as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 4. execute cURL and store the result
$output = curl_exec($ch);
// 5. close cURL after use
curl_close($ch);
// 6. print the output
print $output;
You can read more about cURL options in curl_setopt documentation.
Unlike the file_get_contents()
function, cURL is designed to allow data transfer from various network protocols.
It’s usually enabled by default, so you don’t need to tweak your PHP configuration.
Whenever possible, use cURL to access remote files and file_get_contents()
function for local files.
Now you’ve learned how to solve file_get_contents()
function not working. You’ve also learned how to replace the function with cURL.
Original article source at: https://sebhastian.com/
1667302221
GitHub Pages can't run custom Jekyll plug-ins so when generating Tables of Contents (TOCs), you're stuck with either a JavaScript solution or using kramdown's {:toc}
option. However, by using {:toc}
, you are forced to have that code next to your actual markdown and you can't place it in a layout. This means every. single. post. will need to have the snippet. If you choose the JavaScript approach, that's perfectly fine but what if JS is disabled on someone's browser or your page is just really long and it becomes inefficient.
Instead, I wrote this solution entirely in Liquid and can be used as an {% include %}
in any website you want, in any layout you want. Want to see it in action? Here are some awesome websites that I know of using this solution :heart:.
For more information regarding how this include works, read the blog post.
Want anchors next to your Jekyll headings without JavaScript or a plug-in?
Check out the sister project over at allejo/jekyll-anchor-headings.
Alright, so how do you use it?
Download the toc.html
file from the latest release or the master branch
Toss that file in your _includes
folder.
Use it in your template layout where you have {{ content }}
which is the HTML rendered from the markdown source with this liquid tag:
{% include toc.html html=content %}
This snippet is highly customizable. Here are the available parameters to change the behavior of the snippet.
Parameter | Type | Default | Description |
---|---|---|---|
html | string | * | the HTML of compiled markdown generated by kramdown in Jekyll |
sanitize | bool | false | when set to true, the headers will be stripped of any HTML in the TOC |
class | string | '' | a CSS class assigned to the TOC; concat multiple classes with '.' |
id | string | '' | an ID to be assigned to the TOC |
h_min | int | 1 | the minimum TOC header level to use; any heading lower than this value will be ignored |
h_max | int | 6 | the maximum TOC header level to use; any heading greater than this value will be ignored |
ordered | bool | false | when set to true, an ordered list will be outputted instead of an unordered list |
item_class | string | '' | add custom class for each list item; has support for %level% placeholder, which is the current heading level |
submenu_class | string | '' | add custom class(es) for each child group of headings; has support for %level% placeholder which is the current "submenu" heading level |
base_url | string | '' | add a base url to the TOC links for when your TOC is on another page than the actual content |
anchor_class | string | '' | add custom class(es) for each anchor element |
skip_no_ids | bool | false | skip headers that do not have an id attribute |
* This is a required parameter
baseurl
has been deprecated since 1.1.0, use base_url
insteadskipNoIDs
has been deprecated since 1.1.0, use skip_no_ids
insteadThe performance impact of this snippet on your site is pretty negligible. The stats below were gotten from Jekyll's --profile
option.
Filename | Count | Bytes | Time
--------------------------------------+-------+------------+--------
# performance on docs.docker.com from ~Feb 2017
_includes/toc.html | 813 | 524.17K | 6.422
# performance on the "Minimal Mistakes" Jekyll theme
_includes/toc.html | 94 | 29.43K | 0.413
Author: Allejo
Source Code: https://github.com/allejo/jekyll-toc
License: BSD-3 or MIT licenses.
1665021540
The decentralised creator economy occurred with its smart contract technology. A bright example is the decentralised creation platforms which gave growth to the development of NFT in visual arts. They offer transparent rules and equitable rewards to users—the focus on decentralisation results in respect for liberty and rights.
In this article you will see Top 20 Blockchain Content Creation Platforms
1. Cosmos - ATOM
Describe | Price overview | Website |
Cosmos is described as “Blockchain 3.0” — and as we mentioned earlier, a big goal is ensuring that its infrastructure is straightforward to use. To this end, the Cosmos software development kit focuses on modularity. This allows a network to be easily built using chunks of code that already exist. Long-term, it’s hoped that complex applications will be straightforward to construct as a result. Scalability is another priority, meaning substantially more transactions can be processed a second than more old-fashioned blockchains like Bitcoin and Ethereum. If blockchains are to ever achieve mainstream adoption, they’ll need to be able to cope with demand as well as existing payment processing companies or websites — or be even better. ATOM tokens are earned through a hybrid proof-of-stake algorithm, and they help to keep the Cosmos Hub, the project’s flagship blockchain, secure. This cryptocurrency also has a role in the network’s governance. | ![]() | Link |
2. The Sandbox - SAND
Describe | Price overview | Website |
The Sandbox is a blockchain-based virtual world allowing users to create, build, buy and sell digital assets in the form of a game. By combining the powers of decentralized autonomous organizations (DAO) and non-fungible tokens (NFTs), the Sandbox creates a decentralized platform for a thriving gaming community. The Sandbox is a unique platform because it introduces blockchain technology to the world of gaming. By creating a universe where gamers can create and collect blockchain-based assets, the Sandbox aims to revolutionizes the market. It makes a niche for itself in the global market of gaming. By focusing on user-generated content, the Sandbox creates a metaverse of involved players who contribute to the platform’s further development. Not only that, by introducing the SAND token, the Sandbox promotes decentralized governance and allows users to share their views and ideas about the development of the project. Thanks to the evolving technology, decentralized governance is becoming a must-have in blockchain-based projects. | ![]() | Link |
3. ApeCoin - APE
Describe | Price overview | Website |
ApeCoin is an ERC-20 governance and utility token used within the APE Ecosystem to empower and incentivize a decentralized community building at the forefront of web3. ApeCoin is the APE Ecosystem’s governance token, allowing token holders to participate in ApeCoin DAO and giving its participants a shared and open currency that can be used without centralized intermediaries. 62% of all ApeCoin was allocated to the Ecosystem Fund, which will support community-driven initiatives as voted on by ApeCoin DAO members. ApeCoin also gives access to certain parts of the Ecosystem that are otherwise unavailable, like exclusive games and services. For third-party developers, ApeCoin is a tool to participate in the ecosystem by incorporating ApeCoin into services, games, and other projects. | ![]() | Link |
4. Hive - HIVE
Describe | Price overview | Website |
Hive (HIVE) is a blockchain running on a delegated proof-of-stake (DPoS) consensus mechanism. Hive is a social network of apps and services, where users discover the capacity of blockchain technology, connect to the platform and securely share content through equitable redistribution of value. Thus, the users are the proprietors of the network, and sponsors can contact communities and artists directly without intermediaries. Hive is an open source blockchain that focuses on scaling through layer-2 sidechains, while still benefiting from a common layer-1 blockchain backbone to ensure distributed data integrity. The Hive ecosystem runs on two cryptocurrencies — the native governance token, HIVE and the USD-pegged HBD stablecoin. | ![]() | Link |
5. Basic Attention Token - BAT
Describe | Price overview | Website |
This experience is delivered through the Brave Browser, where users can watch privacy-preserving adverts and receive BAT rewards for doing so. On the other hand, advertisers can deliver targeted ads to maximize engagement and cut down losses due to ad fraud and abuse. The Basic Attention Token itself is the unit of reward in this advertising ecosystem, and is exchanged between advertisers, publishers and users. Advertisers pay for their advertising campaigns in BAT tokens. Out of this budget, a small portion is distributed to advertisers, while 70% is distributed to users — whereas the intermediaries that typically drive up advertising costs are cut out of the equation to improve cost-efficiency. | ![]() | Link |
6. Theta Network - THETA
Describe | Price overview | Website |
Theta (THETA) is a blockchain powered network purpose-built for video streaming. The Theta mainnet operates as a decentralized network in which users share bandwidth and computing resources on a peer-to-peer (P2P) basis. The network runs on a native blockchain, with two native tokens, known as Theta (THETA), Theta Fuel (TFUEL), powering the internal economy. Users have an incentive to both watch network content and share network resources, as rewards come in the form of TFUEL tokens. The platform is open source, and token holders receive governance powers as with many proof-of-stake (PoS)-based blockchain ecosystems. In addition to video, data and computing, Theta caters to developers looking to launch decentralized applications (DApps) on its fully featured EVM-compatible Smart contract platform. | ![]() | Link |
7. Galxe - GAL
Describe | Price overview | Website |
Galxe is the world's leading Web3 credential data network. Galxe is built on open and collaborative infrastructure that allows Web3 developers and projects to profit from credential data by building better products and communities. Data curators are rewarded when users employ their credentials in Project Galaxy's Application Modules, Credential Oracle Engine and Credential API at the same time. | ![]() | Link |
8. Steem - STEEM
Describe | Price overview | Website |
Steem is a community-focused blockchain that creates an instant earning opportunity for the network’s users. The protocol is designed to provide an earning opportunity for customers based on their value to the network. It is designed to provide users with a platform where they can post curated content online, and get paid in cryptocurrency. The protocol is a publicly available, incentivized blockchain database that allows users to interact with themselves and earn in return. It leverages technologies from both social media and cryptocurrency to provide users with value. The network ensures the fair treatment of contributors by running a reward structure that reflects each user’s contribution. |
![]() | Link |
9. Horizen - ZEN
Describe | Price overview | Website |
Horizen is known for its expertise in zero-knowledge-based blockchain technology. Their team has made several advancements in the cryptography space, including their zero-knowledge privacy tool library, called Ginger-Lib, and for the release of one of the first zero-knowledge-based scalability solutions. Their blockchain network provides a unique sidechain solution that allows developers to build their own scalable blockchains with the ability to support tens of thousands of transactions per second while maintaining true decentralization across tens of thousands of nodes. Horizen also offers unique optional privacy features. Horizen is a fully decentralized zero-knowledge-enabled blockchain ecosystem that offers massive scalability and optional privacy features. Horizen features Zendoo, a sidechain system that enables the deployment of thousands of independent sidechains that communicate with the mainchain and each other. Horizen's native cryptocurrency, ZEN, is a mineable PoW coin currently trading on major exchanges, including Coinbase, Bittrex, and Binance. ZEN can be staked to participate in Horizen's nearly 50,000 full node network. | ![]() | Link |
10. Status - SNT
Describe | Price overview | Website |
Status, or SNT, is an open-source messaging platform as well as a mobile interface. This interface allows its users to interact with DApps running on the ETH blockchain. In return, users get over 2,000 DApps, can send and receive encrypted messages on a peer-to-peer basis and can make payments as well as utilize smart contracts. The network itself uses Status Network Tokens, or SNT, that are the native currency on the platform. The goal of Status is to make the adoption of Ethereum DApps quicker and more efficient. | ![]() | Link |
11. Mask Network - MASK
Describe | Price overview | Website |
Mask Network is a protocol that allows its users to send encrypted messages over Twitter and Facebook. It essentially acts as a bridge between the internet and a decentralized network running on top. It is a decentralized portal that also allows users to use DApps like crypto payments, decentralized finance, decentralized storage, e-commerce (digital goods/NFTs) and decentralized organizations (DAO) over the top of existing social networks without migrating, creating what is referred to as a decentralized Applet (DApplet) ecosystem. The Mask Network allows users to add a level of privacy to their online interactions. By letting users send encrypted messages to friends, send and receive cryptocurrency and share files, and interact with DApps, all on a decentralized level. | ![]() | Link |
12. Contentos - COS
Describe | Price overview | Website |
The vision of Contentos is to build a "decentralized digital content community that allows content to be freely produced, distributed, rewarded, and traded, while protecting author rights". Contentos strives to incentivize content creation and global diversity and return the rights and value of content to users. | ![]() | Link |
13. Gifto - GTO
Describe | Price overview | Website |
GIFTO protocol aims to become a decentralized universal virtual gifting protocol, the brainchild of the successful Asia Innovations Group, the parent company of popular live-streaming app Uplive and several other popular social games. GIFTO protocol is expected to be a decentralized version of Uplive’s virtual gifting economy. In Uplive, fans buy virtual gifts designed and created by Uplive’s in-house team of designers with an in-app digital currency called diamonds. GIFTO will decouple the gift creation, curation, and revenue share process from centralized platforms like Uplive and put control in the hands of virtual gift creators, curators, content creators, and fans. The transaction flow is expected to work as follows. First, virtual gift creators will design and create virtual gifts (an ERC-721 compliant token). Second, curators will review and approve gifts, making sure they comply with the protocol’s rules and copyright law. Third, content creators will curate a list of approved gifts that their fans can send to them. Fourth, fans purchase GIFTO tokens on cryptocurrency exchange or inside of special wallets like the GIFTO wallet in Uplive. Fifth, fans purchase virtual gifts with their GIFTO tokens and send the gifts to their favorite content creators. | ![]() | Link |
14. MovieBloc - MBL
Describe | Price overview | Website |
MovieBloc's mission is to solve problems caused by the domination of the theatre and home entertainment industry by conglomerates with its blockchain technology. The creators will get a transparent revenue share, audience data, and equal screening opportunity; the viewers will access diverse films and content, and get rewarded for providing curation, subtitles, and marketing materials to the community. | ![]() | Link |
15. Everipedia - IQ
Describe | Price overview | Website |
Everipedia (IQ) is a decentralized information and prediction platform developed as an alternative to Wikipedia. Everypedia is a blockchain-based version of Wikipedia. It runs on top of the EOS blockchain. On Everipedia, anyone anywhere can share information and knowledge as long as it is verifiable, neutral and backed by a true source. Everipedia operates on a 3-module system consisting of a token module, governance module, and submission module. Furthermore, Everipedia features PredIQt, a prediction market where users can predict the future outcome of events. On Everipedia, users can bet the platform's native cryptocurrency, Tokens and the right to propose and vote on edits and proposals for the future direction of the network. | ![]() | Link |
16. Refereum - RFR
Describe | Price overview | Website |
Refereum originally aimed to create a gaming reward and marketing platform that connected game developers and game influencers. Game developers were able to purchase Refereum token, place those tokens into their games, and decide how they want to reward players. In exchange, game influencers received money, in the form of Refereum tokens, for each gamer that they referred to the platform. | ![]() | Link |
17. Phantasma - SOUL
Describe | Price overview | Website |
Phantasma has an easy-to-use connector between dApps, wallets and blockchain via Phantasma Link. It provides cross-chain interoperability with the Ethereum, BSC and NEO blockchains and is capable of a high throughput due to infinite sidechains. With its innovative staking mechanism, dual token system, sustainable tokenomics model and advanced eco-friendly smartNFTs. The chain is designed to be used for digital goods & services for communications, entertainment, marketplaces and on-chain storage solutions for dApp creators and enterprise clients. SmartNFTs are NFTs with dynamic properties that can change based on certain conditions. They provide game developers the opportunity to make dynamic in-game items decentralized, which is not possible with traditional NFTs. They also allow for time-based NFTs, multi-layered NFTs, infused NFTs and locked content within an NFT that can only be accessed by the owner of the NFT. The NFTs can be minted on-demand at a fraction of the costs compared to other blockchains.
| ![]() | Link |
18. U Network - UUU
Describe | Price overview | Website |
U Network describes itself as a decentralized content asset storage, notarization, distribution, publishing, and valuation network. It claims to allow users to convert their own digital content into assets within the U Network ecosystem. The goal is to construct a financial market for content, leading to the redistribution and optimization of value in the token economy. | ![]() | Link |
article data source: coinmarketcap
How and Where to Buy Content Creation Tokens?
You will have to first buy one of the major cryptocurrencies, usually either Bitcoin (BTC), Ethereum (ETH), Tether (USDT), Binance (BNB)…
We will use Binance Exchange here as it is one of the largest crypto exchanges that accept fiat deposits.
Once you finished the KYC process. You will be asked to add a payment method. Here you can either choose to provide a credit/debit card or use a bank transfer, and buy one of the major cryptocurrencies, usually either Bitcoin (BTC), Ethereum (ETH), Tether (USDT), Binance (BNB)…
Once finished you will then need to make a BTC/ETH/USDT/BNB deposit to the exchange from Binance depending on the available market pairs. After the deposit is confirmed you may then purchase Coin/Token from the Binance exchange.
Read more: Top File-sharing Crypto Projects
Thank you for reading !
1662998100
In today's post we will learn about top 3 Libraries for Extracting Web Contents with JavaScript.
Web scraping with JavaScript is a very useful technique to extract data from the Internet for presentation or analysis. However, in this era of dynamic websites, it becomes difficult to accurately extract data from the web because of the ever-changing nature of data.
Web scraping is the process of extracting data from the Internet for storage in different formats or for further processing and analysis. It can also be referred to as web harvesting or web data extraction.
Table of contents:
npm install node-read
read(html [, options], callback)
Where
callback(error, article, meta)
Example
var read = require('node-read');
read('http://howtonode.org/really-simple-file-uploads', function(err, article, res) {
// Main Article.
console.log(article.content);
// Title
console.log(article.title);
// HTML
console.log(article.html);
// DOM
console.log(article.dom);
});
Attempts to download a video from the given url. Returns a readable stream. options
can have the following, in addition to any getInfo()
option and chooseFormat()
option.
range
- A byte range in the form {start: INT, end: INT}
that specifies part of the file to download, ie {start: 10355705, end: 12452856}. Not supported on segmented (DASH MPD, m3u8) formats.begin
- What time in the video to begin. Supports formats 00:00:00.000
, 0ms, 0s, 0m, 0h
, or number of milliseconds. Example: 1:30
, 05:10.123
, 10m30s
.liveBuffer
- How much time buffer to use for live videos in milliseconds. Default is 20000
.highWaterMark
- How much of the video download to buffer into memory. See node's docs for more. Defaults to 512KB.dlChunkSize
- When the chosen format is video only or audio only, the download is separated into multiple chunks to avoid throttling. This option specifies the size of each chunk in bytes. Setting it to 0 disables chunking. Defaults to 10MB.IPv6Block
- IPv6 block to rotate through, an alternative to using a proxy. Read more. Defaults to undefined
.ytdl.videoInfo
- Info.ytdl.videoFormat
- Video Format.Emitted when the video's info
is fetched, along with the chosen format to download.
number
- Chunk length in bytes or segment number.number
- Total bytes or segments downloaded.number
- Total bytes or segments.Emitted whenever a new chunk is received. Passes values describing the download progress.
All miniget events are forwarded and can be listened to from the returned stream.
Call to abort and stop downloading a video.
Use this if you only want to get metainfo from a video.
ImageResolver.js does its best to determine the main image on a URL without loading all images.
Example
* { box-sizing: border-box; }
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #EEE;
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
color: #444;
font-family: 'Lato', sans-serif;
line-height: 2;
padding: 2em;
}
a { color: #3498db; text-decoration: none; }
a:hover { color: #2980b9; }
form {
background: rgba(255, 255, 255, 0.9);
padding: 30px;
width: 330px;
border-radius: 4px;
}
fieldset {
border: 0;
margin: 0;
padding: 0;
font-size: 1em;
}
label {
display: block;
}
input,
button {
max-width: 260px;
font-size: 1em;
padding: .5em;
border-radius: 3px;
border: 1px solid #3498db;
}
button {
border: 0;
background: #3498db;
color: #FFF;
}
.loading {
background: #C5E2ED;
}
.examples li {
list-style: none;
display: inline;
padding: 0;
margin: 0 1ex 0 0;
}
.examples li:first-child {
display: block;
}
.examples,
p {
padding: 0;
margin: 1em 0 0 0;
font-size: .8em;
}
Thank you for following this article.
WEB SCRAPING made simple with JAVASCRIPT tutorial
1660803846
Reminisce caches your tabs (including their content) so that you can close and reopen Light Table without losing your place. To install, simply search for "Reminisce" in the plugin manager.
Features:
Current Limitations:
In principle the system is also really generic – once the above issues are fixed any kind of tab, not just editors, will be able to hook into it and preserve content.
Author: JuliaIDE
Source Code: https://github.com/JuliaIDE/Reminisce
1660113300
The Multipart
middleware converts a Faraday::Request#body
Hash of key/value pairs into a multipart form request, but only under these conditions:
#content_type
.Faraday contains a couple helper classes for multipart values:
Faraday::Multipart::FilePart
wraps binary file data with a Content-Type. The file data can be specified with a String path to a local file, or an IO object.Faraday::Multipart::ParamPart
wraps a String value with a Content-Type, and optionally a Content-ID.Add this line to your application's Gemfile:
gem 'faraday-multipart'
And then execute:
bundle install
Or install it yourself as:
gem install faraday-multipart
First of all, you'll need to add the multipart middleware to your Faraday connection:
require 'faraday'
require 'faraday/multipart'
conn = Faraday.new(...) do |f|
f.request :multipart, **options
# ...
end
Payload can be a mix of POST data and multipart values.
# regular POST form value
payload = { string: 'value' }
# filename for this value is File.basename(__FILE__)
payload[:file] = Faraday::Multipart::FilePart.new(__FILE__, 'text/x-ruby')
# specify filename because IO object doesn't know it
payload[:file_with_name] = Faraday::Multipart::FilePart.new(
File.open(__FILE__),
'text/x-ruby',
File.basename(__FILE__)
)
# Sets a custom Content-Disposition:
# nil filename still defaults to File.basename(__FILE__)
payload[:file_with_header] = Faraday::Multipart::FilePart.new(
__FILE__,
'text/x-ruby',
nil,
'Content-Disposition' => 'form-data; foo=1'
)
# Upload raw json with content type
payload[:raw_data] = Faraday::Multipart::ParamPart.new(
{ a: 1 }.to_json,
'application/json'
)
# optionally sets Content-ID too
payload[:raw_with_id] = Faraday::Multipart::ParamPart.new(
{ a: 1 }.to_json,
'application/json',
'foo-123'
)
conn.post('/', payload)
Sometimes, the server you're calling will expect an array of documents or other values for the same key. The multipart
middleware will automatically handle this scenario for you:
payload = {
files: [
Faraday::Multipart::FilePart.new(__FILE__, 'text/x-ruby'),
Faraday::Multipart::FilePart.new(__FILE__, 'text/x-pdf')
],
url: [
'http://mydomain.com/callback1',
'http://mydomain.com/callback2'
]
}
conn.post(url, payload)
#=> POST url[]=http://mydomain.com/callback1&url[]=http://mydomain.com/callback2
#=> and includes both files in the request under the `files[]` name
However, by default these will be sent with files[]
key and the URLs with url[]
, similarly to arrays in URL parameters. Some servers (e.g. Mailgun) expect each document to have the same parameter key instead. You can instruct the multipart
middleware to do so by providing the flat_encode
option:
require 'faraday'
require 'faraday/multipart'
conn = Faraday.new(...) do |f|
f.request :multipart, flat_encode: true
# ...
end
payload = ... # see example above
conn.post(url, payload)
#=> POST url=http://mydomain.com/callback1&url=http://mydomain.com/callback2
#=> and includes both files in the request under the `files` name
This works for both UploadIO
and normal parameters alike.
After checking out the repo, run bin/setup
to install dependencies.
Then, run bin/test
to run the tests.
To install this gem onto your local machine, run rake build
.
To release a new version, make a commit with a message such as "Bumped to 0.0.2", and change the Unreleased heading in CHANGELOG.md
to a heading like "0.0.2 (2022-01-01)", and then use GitHub Releases to author a release. A GitHub Actions workflow then publishes a new gem to RubyGems.org.
Bug reports and pull requests are welcome on GitHub.
Author: lostisland
Source Code: https://github.com/lostisland/faraday-multipart
License: MIT license
1659881700
Slim is a template language whose goal is to reduce the view syntax to the essential parts without becoming cryptic. It started as an exercise to see how much could be removed from a standard html template (<, >, closing tags, etc...). As more people took an interest in Slim, the functionality grew and so did the flexibility of the syntax.
A short list of the features...
#
for <div id="...">
and .
for <div class="...">
in the default configuration)html_safe?
Slim is a fast, lightweight templating engine with support for Rails 3 and later. It has been heavily tested on all major ruby implementations. We use continuous integration (travis-ci).
Slim's core syntax is guided by one thought: "What's the minimum required to make this work".
As more people have contributed to Slim, there have been syntax additions influenced from their use of Haml and Jade. The Slim team is open to these additions because we know beauty is in the eye of the beholder.
Slim uses Temple for parsing/compilation and is also integrated into Tilt, so it can be used together with Sinatra or plain Rack.
The architecture of Temple is very flexible and allows the extension of the parsing and compilation process without monkey-patching. This is used by the logic less plugin and the translator plugin which provides I18n. In logic-less mode you can use Slim if you like the Slim syntax to build your HTML but don't want to write Ruby in your templates.
Yes, Slim is speedy! Slim was developed right from the start with performance in mind. Benchmarks are done for every commit at http://travis-ci.org/slim-template/slim. Don't trust the numbers? That's as it should be. Please try the benchmark rake task yourself!
However in our opinion you should use Slim because of its features and syntax. We just ensure that Slim doesn't have a negative impact on the performance of your application.
Install Slim as a gem:
gem install slim
Include Slim in your Gemfile with gem 'slim'
or require it with require 'slim'
. That's it! Now, just use the .slim extension and you're good to go.
Here's a quick example to demonstrate what a Slim template looks like:
doctype html
html
head
title Slim Examples
meta name="keywords" content="template language"
meta name="author" content=author
link rel="icon" type="image/png" href=file_path("favicon.png")
javascript:
alert('Slim supports embedded javascript!')
body
h1 Markup examples
#content
p This example shows you how a basic Slim file looks.
== yield
- if items.any?
table#items
- for item in items
tr
td.name = item.name
td.price = item.price
- else
p No items found. Please add some inventory.
Thank you!
div id="footer"
== render 'footer'
| Copyright © #{@year} #{@author}
Indentation matters, but the indentation depth can be chosen as you like. If you want to first indent 2 spaces, then 5 spaces, it's your choice. To nest markup you only need to indent by one space, the rest is gravy.
|
The pipe tells Slim to just copy the line. It essentially escapes any processing. Each following line that is indented greater than the pipe is copied over.
body
p
|
This is a test of the text block.
The parsed result of the above:
<body><p>This is a test of the text block.</p></body>
If the text starts on the same line, the left margin is set at the indent of the pipe + one space. Any additional spaces will be copied over.
body
p
| This line is on the left margin.
This line will have one space in front of it.
This line will have two spaces in front of it.
And so on...
You can also embed html in the text line
- articles.each do |a|
| <tr><td>#{a.name}</td><td>#{a.description}</td></tr>
'
The single quote tells Slim to copy the line (similar to |
), but makes sure that a single trailing white space is appended.
<
You can write html tags directly in Slim which allows you to write your templates in a more html like style with closing tags or mix html and Slim style. The leading <
works like an implicit |
:
<html>
head
title Example
<body>
- if articles.empty?
- else
table
- articles.each do |a|
<tr><td>#{a.name}</td><td>#{a.description}</td></tr>
</body>
</html>
-
The dash denotes control code. Examples of control code are loops and conditionals. end
is forbidden behind -
. Blocks are defined only by indentation. If your ruby code needs to use multiple lines, append a backslash \
at the end of the lines. If your line ends with comma ,
(e.g because of a method call) you don't need the additional backslash before the linebreak.
body
- if articles.empty?
| No inventory
=
The equals sign tells Slim it's a Ruby call that produces output to add to the buffer. If your ruby code needs to use multiple lines, append a backslash \
at the end of the lines. For example:
= javascript_include_tag \
"jquery",
"application"
If your line ends with comma ,
(e.g because of a method call) you don't need the additional backslash before the linebreak. For trailing or leading whitespace the modifiers >
and <
are supported.
=>
. Same as the single equals sign (=
), except that it adds a trailing white space.=<
. Same as the single equals sign (=
), except that it adds a leading white space.==
Same as the single equals sign (=
), but does not go through the escape_html
method. For trailing or leading whitespace the modifiers >
and <
are supported.
==>
. Same as the double equals sign (==
), except that it adds a trailing white space.==<
. Same as the double equals sign (==
), except that it adds a leading white space./
Use the forward slash for code comments - anything after it won't get displayed in the final render. Use /
for code comments and /!
for html comments
body
p
/ This line won't get displayed.
Neither does this line.
/! This will get displayed as html comments.
The parsed result of the above:
<body><p><!--This will get displayed as html comments.--></p></body>
/!
Use the forward slash immediately followed by an exclamation mark for html comments (<!-- ... -->
).
/[...]
/[if IE]
p Get a better browser.
This renders as:
<!--[if IE]><p>Get a better browser.</p><![endif]-->
The doctype keyword can be used to generate the complex doctypes in a very simple manner.
XML VERSION
doctype xml
<?xml version="1.0" encoding="utf-8" ?>
doctype xml ISO-8859-1
<?xml version="1.0" encoding="iso-8859-1" ?>
XHTML DOCTYPES
doctype html
<!DOCTYPE html>
doctype 5
<!DOCTYPE html>
doctype 1.1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
doctype strict
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
doctype frameset
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
doctype mobile
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN"
"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">
doctype basic
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
doctype transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
HTML 4 DOCTYPES
doctype strict
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
doctype frameset
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
doctype transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
/
)You can close tags explicitly by appending a trailing /
.
img src="image.png"/
Note, that this is usually not necessary since the standard html tags (img, br, ...) are closed automatically.
<
, >
)You can force Slim to add a trailing whitespace after a tag by adding a >
.
a> href='url1' Link1
a> href='url2' Link2
You can add a leading whitespace by adding <
.
a< href='url1' Link1
a< href='url2' Link2
You can also combine both.
a<> href='url1' Link1
Sometimes you may want to be a little more compact and inline the tags.
ul
li.first: a href="/a" A link
li: a href="/b" B link
For readability, don't forget you can wrap the attributes.
ul
li.first: a[href="/a"] A link
li: a[href="/b"] B link
Either start on the same line as the tag
body
h1 id="headline" Welcome to my site.
Or nest it. You must use a pipe or an apostrophe to escape processing
body
h1 id="headline"
| Welcome to my site.
Or enable and rely on smart text instead
body
h1 id="headline"
Welcome to my site.
=
and ==
)Can make the call on the same line
body
h1 id="headline" = page_headline
Or nest it.
body
h1 id="headline"
= page_headline
You write attributes directly after the tag. For normal text attributes you must use double "
or single quotes '
(Quoted attributes).
a href="http://slim-lang.com" title='Slim Homepage' Goto the Slim homepage
You can use text interpolation in the quoted attributes.
If a delimiter makes the syntax more readable for you, you can use the characters {...}
, (...)
, [...]
to wrap the attributes. You can configure these symbols (See option :attr_list_delims
).
body
h1(id="logo") = page_logo
h2[id="tagline" class="small tagline"] = page_tagline
If you wrap the attributes, you can spread them across multiple lines:
h2[id="tagline"
class="small tagline"] = page_tagline
You may use spaces around the wrappers and assignments:
h1 id = "logo" = page_logo
h2 [ id = "tagline" ] = page_tagline
Example:
a href="http://slim-lang.com" title='Slim Homepage' Goto the Slim homepage
You can use text interpolation in the quoted attributes:
a href="http://#{url}" Goto the #{url}
The attribute value will be escaped by default. Use == if you want to disable escaping in the attribute.
a href=="&"
You can break quoted attributes with backslash \
a data-title="help" data-content="extremely long help text that goes on\
and on and on and then starts over...."
Write the ruby code directly after the =
. If the code contains spaces you have to wrap the code into parentheses (...)
. You can also directly write hashes {...}
and arrays [...]
.
body
table
- for user in users
td id="user_#{user.id}" class=user.role
a href=user_action(user, :edit) Edit #{user.name}
a href=(path_to_user user) = user.name
The attribute value will be escaped by default. Use == if you want to disable escaping in the attribute.
a href==action_path(:start)
You can also break ruby attributes with backslash \
or trailing ,
as described for control sections.
The attribute values true
, false
and nil
are interpreted as booleans. If you use the attribute wrapper you can omit the attribute assigment.
input type="text" disabled="disabled"
input type="text" disabled=true
input(type="text" disabled)
input type="text"
input type="text" disabled=false
input type="text" disabled=nil
You can configure attributes to be merged if multiple are given (See option :merge_attrs
). In the default configuration this is done for class attributes with the white space as delimiter.
a.menu class="highlight" href="http://slim-lang.com/" Slim-lang.com
This renders as:
<a class="menu highlight" href="http://slim-lang.com/">Slim-lang.com</a>
You can also use an Array
as attribute value and the array elements will be merged using the delimiter.
a class=["menu","highlight"]
a class=:menu,:highlight
*
The splat shortcut allows you to turn a hash into attribute/value pairs.
.card*{'data-url'=>place_path(place), 'data-id'=>place.id} = place.name
This renders as:
<div class="card" data-id="1234" data-url="/place/1234">Slim's house</div>
You can also use methods or instance variables which return a hash as shown here:
.card *method_which_returns_hash = place.name
.card *@hash_instance_variable = place.name
The hash attributes which support attribute merging (see Slim option :merge_attrs
) can be given as an Array
.first *{class: [:second, :third]} Text
This renders as:
div class="first second third"
Splat attributes prefix may be configured via splat_prefix
option. Default value is '*'
*
You can create completely dynamic tags using the splat attributes. Just create a method which returns a hash with the :tag key.
ruby:
def a_unless_current
@page_current ? {tag: 'span'} : {tag: 'a', href: 'http://slim-lang.com/'}
end
- @page_current = true
*a_unless_current Link
- @page_current = false
*a_unless_current Link
This renders as:
<span>Link</span><a href="http://slim-lang.com/">Link</a>
You can define custom tag shortcuts by setting the option :shortcut
. In Rails apps, you need to put this code for your shortcuts into an initializer like config/initializers/slim.rb
. In Sinatra, you simply add the same configuration anywhere below the line where you require 'slim'
.
Slim::Engine.set_options shortcut: {'c' => {tag: 'container'}, '#' => {attr: 'id'}, '.' => {attr: 'class'} }
We can use it in Slim code like this
c.content Text
which renders to
<container class="content">Text</container>
You can define custom shortcuts (Similar to #
for id and .
for class).
In this example we add &
to create a shortcut for the input elements with type attribute.
Slim::Engine.set_options shortcut: {'&' => {tag: 'input', attr: 'type'}, '#' => {attr: 'id'}, '.' => {attr: 'class'}}
We can use it in Slim code like this
&text name="user"
&password name="pw"
&submit
which renders to
<input type="text" name="user" />
<input type="password" name="pw" />
<input type="submit" />
In another example we add @
to create a shortcut for the role attribute.
Slim::Engine.set_options shortcut: {'@' => {attr: 'role'}, '#' => {attr: 'id'}, '.' => {attr: 'class'}}
We can use it in Slim code like this
.person@admin = person.name
which renders to
<div class="person" role="admin">Daniel</div>
You can also set multiple attributes with same value at once using one shortcut.
Slim::Engine.set_options shortcut: {'@' => {attr: %w(data-role role)}}
We can use it in Slim code like this
.person@admin = person.name
which renders to
<div class="person" role="admin" data-role="admin">Daniel</div>
You can also set additional fixed value attributes to a shortcut.
Slim::Engine.set_options shortcut: {'^' => {tag: 'script', attr: 'data-binding',
additional_attrs: { type: "text/javascript" }}}
Then
^products
== @products.to_json
which renders to
<script data-binding="products" type="text/javascript">
[{"name": "product1", "price": "$100"},
{"name": "prodcut2", "price": "$200"}]
</script>
#
and class shortcut .
You can specify the id
and class
attributes in the following shortcut form
body
h1#headline
= page_headline
h2#tagline.small.tagline
= page_tagline
.content
= show_content
This is the same as
body
h1 id="headline"
= page_headline
h2 id="tagline" class="small tagline"
= page_tagline
div class="content"
= show_content
If you use Slim you might want to extend your template with some helpers. Assume that you have the following helper
module Helpers
def headline(&block)
if defined?(::Rails)
# In Rails we have to use capture!
"<h1>#{capture(&block)}</h1>"
else
# If we are using Slim without a framework (Plain Tilt),
# this works directly.
"<h1>#{yield}</h1>"
end
end
end
which is included in the scope that executes the Slim template code. The helper can then be used in the Slim template as follows
p
= headline do
' Hello
= user.name
The content in the do
block is then captured automatically and passed to the helper via yield
. As a syntactic sugar you can omit the do
keyword and write only
p
= headline
' Hello
= user.name
Using the Binding
you can capture to local variables as follows:
module Helpers
def capture_to_local(var, &block)
set_var = block.binding.eval("lambda {|x| #{var} = x }")
# In Rails we have to use capture!
# If we are using Slim without a framework (Plain Tilt),
# you can just yield to get the captured block.
set_var.call(defined?(::Rails) ? capture(&block) : yield)
end
end
The helper can then be used in the Slim template as follows
/ The captured_content variable must be known by the Binding beforehand.
= capture_to_local captured_content=:captured_content
p This will be captured in the variable captured_content
= captured_content
Another interesting use case is to use an enumerable and capture for each element. The helper could look like this
module Capture
def capture(var, enumerable = nil, &block)
value = enumerable ? enumerable.map(&block) : yield
block.binding.eval("lambda {|x| #{var} = x }").call(value)
nil
end
end
and it would be used as follows
- links = { 'http://slim-lang.com' => 'The Slim Template Language' }
= capture link_list=:link_list, links do |url, text|
a href=url = text
Afterwards, link_list
contains the captured content.
If you want includes which are processed at compile time, you can take a look at Include partials. However you can also execute subtemplates at runtime (similar to Rails' #render
). You have to write your own include helper:
module Helpers
def include_slim(name, options = {}, &block)
Slim::Template.new("#{name}.slim", options).render(self, &block)
end
end
This helper can then be used as follows
nav = include_slim 'menu'
section = include_slim 'content'
However this helper doesn't do any caching. You should therefore implement a more intelligent version of the helper which fits your purposes. You should also be aware that most frameworks already bring their own include helper, e.g. Rails has render
.
Use standard Ruby interpolation. The text will be html escaped by default, but you can avoid escaping by using double braces.
body
h1 Welcome #{current_user.name} to the show.
| Unescaped #{{content}} is also possible.
To escape the interpolation (i.e. render as is)
body
h1 Welcome \#{current_user.name} to the show.
Thanks to Tilt, Slim has extensive support for embedding other template engines.
Examples:
coffee:
square = (x) -> x * x
markdown:
#Header
Hello from #{"Markdown!"}
Second Line!
p: markdown: Tag with **inline** markdown!
Supported engines:
Filter | Required gems | Type | Description |
---|---|---|---|
ruby: | none | Shortcut | Shortcut to embed ruby code |
javascript: | none | Shortcut | Shortcut to embed javascript code and wrap in script tag |
css: | none | Shortcut | Shortcut to embed css code and wrap in style tag |
sass: | sass | Compile time | Embed sass code and wrap in style tag |
scss: | sass | Compile time | Embed scss code and wrap in style tag |
less: | less | Compile time | Embed less css code and wrap in style tag |
coffee: | coffee-script | Compile time | Compile coffee script code and wrap in script tag |
markdown: | redcarpet/rdiscount/kramdown | Compile time + Interpolation | Compile markdown code and interpolate #{variables} in text |
textile: | redcloth | Compile time + Interpolation | Compile textile code and interpolate #{variables} in text |
rdoc: | rdoc | Compile time + Interpolation | Compile rdoc code and interpolate #{variables} in text |
The embedded engines can be configured in Slim by setting the options directly on the Slim::Embedded
filter. Example:
Slim::Embedded.options[:markdown] = {auto_ids: false}
You can also specify HTML attributes for the following embedded engines:
Example:
scss class="myClass":
$color: #f00;
body { color: $color; }
This will generate the following HTML:
<style class="myClass" type="text/css">body{color:red}</style>
Slim and the underlying Temple framework are highly configurable. The way how you configure Slim depends a bit on the compilation mechanism (Rails or Tilt). It is always possible to set default options per Slim::Engine
class. This can be done in Rails' environment files. For instance, in config/environments/development.rb you probably want:
# Indent html for pretty debugging and do not sort attributes
Slim::Engine.set_options pretty: true, sort_attrs: false
You can also access the option hash directly:
Slim::Engine.options[:pretty] = true
There are two ways to set options at runtime. For Tilt templates (Slim::Template
) you can set the options when you instantiate the template:
Slim::Template.new('template.slim', optional_option_hash).render(scope)
The other possibility is to set the options per thread which is interesting mostly for Rails:
Slim::Engine.with_options(option_hash) do
# Any Slim engines which are created here use the option_hash
# For example in Rails:
render :page, layout: true
end
You have to be aware that the compiled engine code and the options are cached per template in Rails and you cannot change the option afterwards.
# First render call
Slim::Engine.with_options(pretty: true) do
render :page, layout: true
end
# Second render call
Slim::Engine.with_options(pretty: false) do
render :page, layout: true # :pretty is still true because it is cached
end
The following options are exposed by the Slim::Engine
and can be set with Slim::Engine.set_options
. There are a lot of them but the good thing is, that Slim checks the configuration keys and reports an error if you try to use an invalid configuration key.
Type | Name | Default | Purpose |
---|---|---|---|
String | :file | nil | Name of parsed file, set automatically by Slim::Template |
Integer | :tabsize | 4 | Number of white spaces per tab (used by the parser) |
String | :encoding | "utf-8" | Set encoding of template |
String | :default_tag | "div" | Default tag to be used if tag name is omitted |
Hash | :shortcut | {'.' => {attr: 'class'}, '#' => {attr: 'id'}} | Attribute shortcuts |
Hash | :code_attr_delims | {'(' => ')', '[' => ']', '{' => '}'} | Attribute delimiters for Ruby code attributes |
Hash | :attr_list_delims | {'(' => ')', '[' => ']', '{' => '}'} | Attribute list delimiter |
Array<Symbol,String> | :enable_engines | nil (All enabled) | List of enabled embedded engines (whitelist) |
Array<Symbol,String> | :disable_engines | nil (None disabled) | List of disabled embedded engines (blacklist) |
Boolean | :disable_capture | false (true in Rails) | Disable capturing in blocks (blocks write to the default buffer |
Boolean | :disable_escape | false | Disable automatic escaping of strings |
Boolean | :use_html_safe | false (true in Rails) | Use String#html_safe? from ActiveSupport (Works together with :disable_escape) |
Symbol | :format | :xhtml | HTML output format (Possible formats :html, :xhtml, :xml) |
String | :attr_quote | '"' | Character to wrap attributes in html (can be ' or ") |
Hash | :merge_attrs | {'class' => ' '} | Joining character used if multiple html attributes are supplied (e.g. class="class1 class2") |
Array<String> | :hyphen_attrs | %w(data) | Attributes which will be hyphenated if a Hash is given (e.g. data={a_foo:1,b:2} will render as data-a_foo="1" data-b="2") |
Boolean | :hyphen_underscore_attrs | false | Attributes that have underscores in their names will be hyphenated (e.g. data={a_foo:1,b_bar:2} will render as data-a-foo="1" data-b-bar="2") |
Boolean | :sort_attrs | true | Sort attributes by name |
Symbol | :js_wrapper | nil | Wrap javascript by :comment, :cdata or :both. You can also :guess the wrapper based on :format. |
Boolean | :pretty | false | Pretty HTML indenting, only block level tags are indented (This is slower!) |
String | :indent | ' ' | Indentation string |
Boolean | :streaming | false (true in Rails, see below how to disable it!) | Enable output streaming, improves the perceived performance |
Class | :generator | Temple::Generators::StringBuffer/ RailsOutputBuffer | Temple code generator (default generator generates string buffer) |
String | :buffer | '_buf' ('@output_buffer' in Rails) | Variable used for buffer |
String | :splat_prefix | '*' | Prefix used for splat attributes |
There are more options which are supported by the Temple filters but which are not exposed and are not officially supported. You have to take a look at the Slim and Temple code for that.
For developers who know more about Slim and Temple architecture it is possible to override default options at different positions. Temple uses an inheritance mechanism to allow subclasses to override options of the superclass. The option priorities are as follows:
Slim::Template
options passed at engine instantiationSlim::Template.options
Slim::Engine.thread_options
, Slim::Engine.options
thread_options
, options
(e.g Slim::Parser
, Slim::Compiler
)It is also possible to set options for superclasses like Temple::Engine
. But this will affect all temple template engines then.
Slim::Engine < Temple::Engine
Slim::Compiler < Temple::Filter
Slim currently provides plugins for logic less mode, includes and I18n. See the plugin documentation.
Slim uses Tilt to compile the generated code. If you want to use the Slim template directly, you can use the Tilt interface.
Tilt.new['template.slim'].render(scope)
Slim::Template.new('template.slim', optional_option_hash).render(scope)
Slim::Template.new(optional_option_hash) { source }.render(scope)
The optional option hash can have to options which were documented in the section above. The scope is the object in which the template code is executed.
require 'sinatra'
require 'slim'
get('/') { slim :index }
__END__
@@ index
doctype html
html
head
title Sinatra With Slim
body
h1 Slim Is Fun!
Rails generators are provided by slim-rails. slim-rails is not necessary to use Slim in Rails though. Just install Slim and add it to your Gemfile with gem 'slim'
. Then just use the .slim extension and you're good to go.
HTTP streaming is enabled by default if you use a Rails version which supports it. However you have to be aware that streaming only improves the perceived performance. The rendering time in total will increase. If you want to disable it use:
Slim::RailsTemplate.set_options streaming: false
Slim now supports Angular2 syntax. But you need to set some configuration options:
splat_prefix
optionThis option tells parser what syntax to use for splat attributes. Default value is asterisk: splat_prefix: '*'
Asterisk is also used in Angular2 for structural directives such as *ngIf
and others, so default configuration causes a conflict between slim and angular2 syntax.
There are two ways to resolve it:
splat_prefix
to any custom value, double asterisk, for example: splat_prefix: '**'
. Now structural directives should work as expected. Remember that now splat attributes should be written with new custom prefix before them.Angular and slim both uses brackets in their syntax. So there are also two ways:
bind-...
and so on)code_attr_delims: {
'{' => '}',
},
attr_list_delims: {
'{' => '}',
},
Now you can use something like this:
h1{ #var (bind1)="test" [bind2]="ok" [(bind3)]="works?" *ngIf="expr" *ngFor="expression" } {{it works}}
Will be compiled to:
<h1 #var="" (bind1)="test" [bind2]="ok" [(bind3)]="works?" *ngIf="expr" *ngFor="expression">
{{it works}}
</h1>
The gem 'slim' comes with the small tool 'slimrb' to test Slim from the command line.
$ slimrb --help Usage: slimrb [options] -s, --stdin Read input from standard input instead of an input file --trace Show a full traceback on error -c, --compile Compile only but do not run -e, --erb Convert to ERB --rails Generate rails compatible code (Implies --compile) -r, --require library Load library or plugin with -r slim/plugin -p, --pretty Produce pretty html for debugging purposes -o, --option name=code Set slim option -l, --locals Hash|YAML|JSON Set local variables -h, --help Show this message -v, --version Print version
Start 'slimrb', type your code and press Ctrl-d to send EOF. In Windows Command Prompt press Ctrl-z, Enter to send EOF. Example usage:
$ slimrb markdown: First paragraph. Second paragraph. * one * two * three //Enter Ctrl-d <p>First paragraph </p> <p>Second paragraph </p> <ul> <li>one</li> <li>two</li> <li>three</li> </ul>
There are plugins for various text editors (including the most important ones - Vim, Emacs and Textmate):
slimrb
or `Slim::ERBConverter' which are both included in the Slim gemYes, Slim is one of the fastest Ruby template engines out there! In production mode Slim is nearly as fast as Erubis (which is the fastest template engine). But we would be happy if you chose Slim also for any other reason, we assure you performance will not be an obstacle.
Run the benchmarks with rake bench
. You can add the option slow
to run the slow parsing benchmark which needs more time. You can also increase the number of iterations.
$ rake bench slow=1 iterations=1000
We run the benchmarks for every commit on Travis-CI. Take a look at the newest benchmarking results: http://travis-ci.org/slim-template/slim
Slim provides an extensive test-suite based on minitest. You can run the tests with 'rake test' and the rails integration tests with 'rake test:rails'.
We are currently experimenting with human-readable literate tests which are written as markdown files: TESTS.md
Travis-CI is used for continuous integration testing: http://travis-ci.org/slim-template/slim
Slim is working well on all major Ruby implementations:
If you'd like to help improve Slim, clone the project with Git by running:
$ git clone git://github.com/slim-template/slim
Work your magic and then submit a pull request. We love pull requests!
Please remember to keep the compatibility with Ruby versions 2.0.0, 2.1.0, 2.2.0 and 2.3.0.
If you find the documentation lacking, help us out and update this README.md. If you don't have the time to work on Slim, but found something we should know about, please submit an issue.
Slim is released under the MIT license.
If you want to support this project please visit the Gittip and Flattr pages.
Currently the donations will be used to cover the hosting costs (domain name etc).
Template compilation framework:
Framework support:
Syntax highlighting:
Static code analysis:
Template Converters (HAML, ERB, ...):
Language ports/Similar languages:
Author: slim-template
Source code: https://github.com/slim-template/slim
License: MIT license
1659510720
私のプロジェクトでは、ドキュメントを作成して、作成中の Web サイトからドキュメントを表示およびダウンロードできるユーザーと共有するための管理インターフェイスを開発しています。
ただし、管理プラットフォームは、さまざまな国の複数のチーム専用です。お互いのドキュメントを表示したり操作したりできるようにしたくありません。その上、それらのチームは変化することを意図しており、自分自身を管理する必要があります。チームごとに、チーム メンバーのみの権限を作成、削除、および変更できるスーパー管理者アカウントを作成します。
Django で Okta を使用して管理者の認証とアクセス許可を簡単かつ迅速に処理する方法を紹介します。
この記事では、次の 3 つのポイントを取り上げます。
Django の貴重な機能の 1 つは、さまざまなユーザーのアクセス許可の管理です。ただし、ユーザーを個別の独立したグループに分割し、一部のユーザーが他のユーザーを確認せずにその一部のみを管理できるようにすることは、必ずしも簡単ではありません。さらに、管理者が自分の管理者アカウントを使用して Django プラットフォームに接続できるシステムが必要でした。
このアプリケーションの場合、認証およびユーザー管理システムは次のことを行う必要があります。
これらの要件に対処するために、私たちは Okta ツールを使用することにしました。Oktaは 2009 年に設立されたクラウド ソフトウェアを提供する会社です。このソフトウェアを使用すると、ユーザー ID とアクセス管理を管理および保護できます。Okta の CEO は、2019 年の登録ユーザー数が 1 億人を超えたと発表しました。さらに、Okta は最新のセキュリティ対策と認証フローでトップクラスです。
Oktaの主な機能
以下のグラフに示すように、Oktaは 4 つの主要な機能を提供します。
Okta では、適切な権限を持つ管理者が他のユーザーを作成して適切なグループを付与するのは簡単です。このようにして、組織の各レベルで、ユーザーとその権限を簡単に管理できます。
Okta で作成されたユーザーとそのグループの例
Okta を Django admin と統合する方法と、それを使用してユーザーの権限を管理する方法について説明します。
Oktaとの管理者接続を Django 管理者に追加するために、私たちのチームはmozilla-django-oidcライブラリを使用しました。「OpenID Connect 対応の認証サービスと統合するための軽量の認証およびアクセス管理ライブラリです。」OIDC とも呼ばれる OpenId Connect は、OAuth 2.0 プロトコル上の ID レイヤーです。認可サーバーのおかげで、認証によってエンドユーザーの身元を確認できます。OpenID Connect は の概念を導入していますid_token
。これは、クライアントがユーザーの ID を検証できるようにするセキュリティ トークンです。はid_token
、ユーザーに関する基本的なプロファイル情報も取得します。これは、ユーザーに関する情報を返す API である UserInfo エンドポイントを導入します。
使用されるサインイン プロトコルは、次の図で説明されている手順に従います。
サインイン プロトコル図
でコールバック URL を構成し、設定にclient_id
を追加しclient_secret
て、ライブラリのドキュメントに記載されているように、Okta からトークンを取得しました。この場合、RS256 アルゴリズムを使用しました。
# In settings.py
# Okta
OKTA_DOMAIN = os.environ.get("OKTA_DOMAIN")
OKTA_TOKEN = os.environ.get("OKTA_TOKEN")
# User information
USER_CRM_ID = None
USER_EMAIL = None
# Okta Admin
OKTA_ADMIN_DOMAIN = OKTA_DOMAIN
OIDC_RP_SIGN_ALGO = "RS256"
OIDC_OP_JWKS_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/keys"
OIDC_OP_AUTHORIZATION_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/authorize"
OIDC_OP_TOKEN_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/token"
OIDC_OP_USER_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/userinfo"
OIDC_RP_SCOPES = "openid profile email groups"
OIDC_RP_CLIENT_ID = os.environ.get("OKTA_ADMIN_CLIENT_ID")
OIDC_RP_CLIENT_SECRET = os.environ.get("OKTA_ADMIN_CLIENT_SECRET")
OIDC_VERIFY_SSL = True
LOGIN_REDIRECT_URL = f"{BASE_URL}/admin/"
OIDC_REDIRECT_URL = f"{BASE_URL}/admin/oidc/callback/"
OIDC_AUTH_REQUEST_EXTRA_PARAMS = {"redirect_uri": OIDC_REDIRECT_URL}
ログイン テンプレートをオーバーライドできるようになりました。ユーザーが自分の Okta アカウントに接続できるボタンを追加しました。
# In templates/admin/login.html
# Admins can also log in through the usual credentials flow
{% extends "admin/login.html" %}
{% block extrastyle %}
{{ block.super }}
<style>
#content-main {
float: none !important;
}
.okta_login_container {
margin-top: 15px;
display: flex;
justify-content: center;
}
</style>
{% endblock %}
{% block content %}
{{ block.super }}
<div class="okta_login_container">
<a href="{% url 'oidc_authentication_init' %}">Or Login With Okta</a>
</div>
{% endblock %}
Okta でログインするための新しいボタン
Okta を介して Django Admin に接続する方法を追加したら、ユーザーを保存して更新する必要があります。Okta から情報を取得し、Django に追加しています。そのために、mozilla-django-oidc のクラス OIDCAuthenticationBackend をオーバーライドします。ユーザーの検証済みの電子メールに関する情報を取得し、Django で作成または更新できます。現時点では、アクセス許可はありません。
class OktaAdminAuthenticationBackend(OIDCAuthenticationBackend):
def verify_claims(self, claims: OktaClaim) -> bool:
return (
super().verify_claims(claims)
and claims.get("email_verified", False)
)
@transaction.atomic
def create_user(self, claims: OktaClaim) -> User:
user: User = self.UserModel.objects.create_user(
claims.get("email"),
None, # password
first_name=claims["given_name"],
last_name=claims["family_name"],
)
user.save()
return user
@transaction.atomic
def update_user(self, user: User, claims: OktaClaim) -> User:
"""Update existing user with new claims, if necessary save, and return user"""
user.first_name = claims["given_name"]
user.last_name = claims["family_name"]
user.save()
return user
管理者は、Okta 資格情報を使用してアプリケーションにログインできます。Okta と同期して権限を追加する方法を紹介します。
ユーザーを Django admin に追加したら、顧客の Web サイトを管理するための適切な権限を付与する必要があります。私のプロジェクトでは、各チームに 2 種類の管理者がいました。
基本権限を持つ管理者。チームのユーザー向けにドキュメントを作成できますが、公開することはできません。
Okta で名前を付けましAdmin - [Group Name]
た。
コントローラー。彼らは、チームのユーザーのためにドキュメントを検証して公開できる管理者です。
Okta で名前を付けましAdmin - [Group Name] Controller
た。
Okta の 2 つのグループの例
Django Admin では、2 種類のグループを作成することにしました。1 つ目は、基本的な権限を持つ各チームのグループです。もう 1 つは、ドキュメントを検証して公開するためのより多くの権限を持つ、Administrator Controller と呼ばれる一般的なグループです。以下のグラフは、グループを管理者に割り当てるまでの流れを示しています。
ユーザーとグループの作成の流れ
これらの権限を処理するために、ユーザー グループを含む Okta レスポンスからユーザー情報を取得します。上記のビジネス ルールに従って、これらのグループを分離できます。
def handle_controller_groups(self, groups):
groups_with_controller = set()
for group in groups:
# remove Controllers groups and add generic 'Administrator Controller'
if bool(re.search("[Cc]ontroller", group)):
groups_with_controller.add(ADMINISTRATOR_CONTROLLER)
else:
groups_with_controller.add(group)
return groups_with_controller
def get_user_groups(self, claims: OktaClaim) -> QuerySet:
claim_groups = claims.get("groups")
assert claim_groups
groups = [group[8:] for group in claim_groups] # remove `Admin - ` prefix
groups_with_controllers = self.handle_controller_groups(groups)
return Group.objects.filter(name__in=groups_with_controllers)
最後に、これらの関数を使用して、作成および更新時にユーザーのアクセス許可を取得します。
def verify_claims(self, claims: OktaClaim) -> bool:
return (
super().verify_claims(claims)
and claims.get("email_verified", False)
and claims.get("groups") is not None
)
@transaction.atomic
def create_user(self, claims: OktaClaim) -> User:
user: User = self.UserModel.objects.create_user(
claims.get("email"),
None, # password
first_name=claims["given_name"],
last_name=claims["family_name"],
)
user.groups.set(self.get_user_groups(claims))
user.save()
return user
@transaction.atomic
def update_user(self, user: User, claims: OktaClaim) -> User:
"""Update existing user with new claims, if necessary save, and return user"""
user.first_name = claims["given_name"]
user.last_name = claims["family_name"]
user.groups.set(self.get_user_groups(claims))
user.save()
return user
管理者は適切な権限でドキュメントを作成でき、チーム メンバーだけがドキュメントを見ることができます。さらに、コントローラー管理者はチームを管理し、ドキュメントをレビューして公開できます。
この実装により、管理者はチームを管理するために私たちに電話する必要がなくなり、さまざまなジョブを実行するために Okta 資格情報のみが必要になります。
制限の 1 つは、新しいグループが作成された場合、ユーザーがログイン時にアクセス許可を取得できるように、そのグループを Okta と Django に追加する必要があることです。認識できない場合はグループを作成しないことにしました。管理者は機密情報をアップロードできるため、アクセス許可の問題を回避するために Django でそれらを使用します。
この記事をお読みいただき、Okta と Django admin を使用して管理者のアクセス許可を処理する新しい方法を学んでいただければ幸いです。ぜひお試しください!
ソース: https://blog.theodo.com/2021/03/okta-sso-with-django-admin/
1659510540
No meu projeto, estamos desenvolvendo uma interface administrativa para criar e compartilhar documentos com usuários que podem vê-los e baixá-los do site que estamos criando.
No entanto, a plataforma de administração é dedicada a várias equipes de vários países. Não queremos que eles possam ver ou interagir com os documentos uns dos outros. Além disso, essas equipes devem mudar e devem gerenciar a si mesmas. Para cada equipe, queremos criar uma conta de superadministrador capaz de criar, excluir e alterar permissões apenas para os membros da equipe.
Mostrarei como lidamos com autenticação e permissões de administrador no Django com Okta com uma solução rápida e sem esforço.
Neste artigo, desenvolverei três pontos principais:
Um dos recursos valiosos do Django é o gerenciamento de permissões para vários usuários. No entanto, nem sempre é simples separar os usuários em grupos independentes distintos e permitir que alguns deles gerenciem apenas uma fração dele sem ver os outros usuários. Além disso, queríamos um sistema que permitisse aos administradores se conectarem na plataforma Django com sua conta de administrador.
Para nossa aplicação, o sistema de autenticação e gerenciamento de usuários deve:
Para lidar com esses requisitos, decidimos usar as ferramentas Okta. Okta é uma empresa fundada em 2009 fornecendo um software em nuvem. Este software permite que você gerencie e proteja a identidade do usuário e o gerenciamento de acesso. O CEO da Okta anunciou que tinha mais de 100 milhões de usuários registrados em 2019. Além disso, a Okta é excelente em medidas de segurança atualizadas e fluxos de autenticação.
Principais funcionalidades do Okta
Como visto no gráfico abaixo, o Okta oferece quatro funcionalidades principais:
No Okta, é simples para um administrador com os direitos corretos criar outros usuários e conceder a eles os grupos certos. Dessa forma, em cada nível da organização, os usuários e suas permissões são gerenciáveis sem esforço.
Exemplo de um usuário criado no Okta com seus grupos
Agora vou explicar como integramos o Okta com o Django admin e como o usamos para gerenciar as permissões de nossos usuários.
Para adicionar a conexão admin com Okta ao Django admin, nossa equipe usou a biblioteca mozilla-django-oidc . “Uma biblioteca leve de autenticação e gerenciamento de acesso para integração com serviços de autenticação habilitados para OpenID Connect.” OpenId Connect, também conhecido como OIDC, é uma camada de identidade sobre o protocolo OAuth 2.0. A identidade do usuário final pode ser verificada com a autenticação graças a um servidor de autorização. O OpenID Connect introduz o conceito de um id_token
, que é um token de segurança que permite ao cliente verificar a identidade do usuário. O id_token
também obtém informações básicas de perfil sobre o usuário. Ele apresenta o endpoint UserInfo, uma API que retorna informações sobre o usuário.
O protocolo de login usado segue as etapas descritas no próximo diagrama.
Diagrama de protocolo de login
Configuramos o URL de retorno de chamada com o client_id
e adicionamos o client_secret
em nossas configurações para adquirir o token do Okta conforme escrito na documentação da biblioteca. No nosso caso, usamos um algoritmo RS256.
# In settings.py
# Okta
OKTA_DOMAIN = os.environ.get("OKTA_DOMAIN")
OKTA_TOKEN = os.environ.get("OKTA_TOKEN")
# User information
USER_CRM_ID = None
USER_EMAIL = None
# Okta Admin
OKTA_ADMIN_DOMAIN = OKTA_DOMAIN
OIDC_RP_SIGN_ALGO = "RS256"
OIDC_OP_JWKS_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/keys"
OIDC_OP_AUTHORIZATION_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/authorize"
OIDC_OP_TOKEN_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/token"
OIDC_OP_USER_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/userinfo"
OIDC_RP_SCOPES = "openid profile email groups"
OIDC_RP_CLIENT_ID = os.environ.get("OKTA_ADMIN_CLIENT_ID")
OIDC_RP_CLIENT_SECRET = os.environ.get("OKTA_ADMIN_CLIENT_SECRET")
OIDC_VERIFY_SSL = True
LOGIN_REDIRECT_URL = f"{BASE_URL}/admin/"
OIDC_REDIRECT_URL = f"{BASE_URL}/admin/oidc/callback/"
OIDC_AUTH_REQUEST_EXTRA_PARAMS = {"redirect_uri": OIDC_REDIRECT_URL}
Agora é possível substituir o modelo de login. Adicionamos um botão que permite que os usuários se conectem com sua conta Okta.
# In templates/admin/login.html
# Admins can also log in through the usual credentials flow
{% extends "admin/login.html" %}
{% block extrastyle %}
{{ block.super }}
<style>
#content-main {
float: none !important;
}
.okta_login_container {
margin-top: 15px;
display: flex;
justify-content: center;
}
</style>
{% endblock %}
{% block content %}
{{ block.super }}
<div class="okta_login_container">
<a href="{% url 'oidc_authentication_init' %}">Or Login With Okta</a>
</div>
{% endblock %}
Novo botão para fazer login com Okta
Depois de adicionar uma maneira de conectar através do Okta ao Django Admin, devemos salvar e atualizar os usuários. Estamos obtendo suas informações do Okta e adicionando-as no Django. Para fazer isso, sobrescrevemos a classe OIDCAuthenticationBackend do mozilla-django-oidc. Podemos obter as informações sobre o email verificado do usuário e criá-lo ou atualizá-lo no Django, sem nenhuma permissão no momento.
class OktaAdminAuthenticationBackend(OIDCAuthenticationBackend):
def verify_claims(self, claims: OktaClaim) -> bool:
return (
super().verify_claims(claims)
and claims.get("email_verified", False)
)
@transaction.atomic
def create_user(self, claims: OktaClaim) -> User:
user: User = self.UserModel.objects.create_user(
claims.get("email"),
None, # password
first_name=claims["given_name"],
last_name=claims["family_name"],
)
user.save()
return user
@transaction.atomic
def update_user(self, user: User, claims: OktaClaim) -> User:
"""Update existing user with new claims, if necessary save, and return user"""
user.first_name = claims["given_name"]
user.last_name = claims["family_name"]
user.save()
return user
Os administradores podem fazer login no aplicativo com suas credenciais do Okta. Mostrarei como adicionar suas permissões sincronizando-as com o Okta.
Depois de adicionar usuários ao administrador do Django, devemos conceder a eles as permissões corretas para gerenciar o site do cliente. No meu projeto, tínhamos dois tipos de administradores para cada equipe:
Administradores com direitos básicos. Eles podem criar documentos para os usuários de sua equipe, mas não podem publicá-los.
Nós os Admin - [Group Name]
nomeamos em Okta.
Controladores. Eles são administradores que podem validar e publicar documentos para os usuários de sua equipe.
Nós os Admin - [Group Name] Controller
nomeamos em Okta.
Exemplo de dois grupos em Okta
No Django Admin, decidimos criar dois tipos de grupo. O primeiro é um grupo para cada equipe com permissão básica. O outro é um grupo geral chamado Administrator Controller com mais permissões para validar e publicar documentos. O gráfico abaixo mostra o fluxo para atribuir grupos aos administradores.
Fluxo de criação de usuários e grupos
Para lidar com essas permissões, obtemos informações do usuário da resposta do Okta que contém os grupos de usuários. Podemos separar esses grupos de acordo com nossas regras de negócios, conforme descrito acima.
def handle_controller_groups(self, groups):
groups_with_controller = set()
for group in groups:
# remove Controllers groups and add generic 'Administrator Controller'
if bool(re.search("[Cc]ontroller", group)):
groups_with_controller.add(ADMINISTRATOR_CONTROLLER)
else:
groups_with_controller.add(group)
return groups_with_controller
def get_user_groups(self, claims: OktaClaim) -> QuerySet:
claim_groups = claims.get("groups")
assert claim_groups
groups = [group[8:] for group in claim_groups] # remove `Admin - ` prefix
groups_with_controllers = self.handle_controller_groups(groups)
return Group.objects.filter(name__in=groups_with_controllers)
Por fim, usamos essas funções para obter permissões de usuários quando as criamos e atualizamos.
def verify_claims(self, claims: OktaClaim) -> bool:
return (
super().verify_claims(claims)
and claims.get("email_verified", False)
and claims.get("groups") is not None
)
@transaction.atomic
def create_user(self, claims: OktaClaim) -> User:
user: User = self.UserModel.objects.create_user(
claims.get("email"),
None, # password
first_name=claims["given_name"],
last_name=claims["family_name"],
)
user.groups.set(self.get_user_groups(claims))
user.save()
return user
@transaction.atomic
def update_user(self, user: User, claims: OktaClaim) -> User:
"""Update existing user with new claims, if necessary save, and return user"""
user.first_name = claims["given_name"]
user.last_name = claims["family_name"]
user.groups.set(self.get_user_groups(claims))
user.save()
return user
Nossos administradores podem criar seus documentos com as permissões certas e apenas os membros de sua equipe podem vê-los. Além disso, os administradores de controladores podem gerenciar sua equipe e revisar documentos para publicá-los.
Com essa implementação, os administradores não precisam nos chamar para gerenciar suas equipes e precisam apenas de suas credenciais Okta para realizar seus diversos trabalhos.
Uma das limitações é que se um novo grupo for criado, ele precisa ser adicionado no Okta e no Django para permitir que os usuários tenham suas permissões quando efetuarem login. Decidimos que não queríamos criar grupos quando não reconhecíamos eles no Django para evitar problemas com permissões, pois os administradores podem fazer upload de informações confidenciais.
Espero que você tenha gostado de ler este artigo e aprendido uma nova maneira de lidar com permissões de administradores com o Okta e o Django admin. Espero que você vai experimentá-lo!
Fonte: https://blog.theodo.com/2021/03/okta-sso-with-django-admin/
1659507300
Dans mon projet, nous développons une interface d'administration pour créer et partager des documents aux utilisateurs qui peuvent les voir et les télécharger à partir du site Web que nous créons.
Cependant, la plateforme d'administration est dédiée à plusieurs équipes de différents pays. Nous ne voulons pas qu'ils puissent voir ou interagir avec les documents des autres. De plus, ces équipes sont censées changer et elles doivent se gérer elles-mêmes. Pour chaque équipe, nous voulons créer un compte super administrateur capable de créer, supprimer et modifier les autorisations pour les membres de son équipe uniquement.
Je montrerai comment nous gérons l'authentification et les autorisations des administrateurs dans Django avec Okta avec une solution simple et rapide.
Dans cet article, je développerai trois points principaux :
L'une des fonctionnalités intéressantes de Django est la gestion des autorisations pour différents utilisateurs. Cependant, il n'est pas toujours simple de séparer les utilisateurs en groupes indépendants distincts et de permettre à certains d'entre eux de n'en gérer qu'une fraction sans voir les autres utilisateurs. De plus, nous voulions un système permettant aux admins de se connecter sur la plateforme Django avec leur compte admin.
Pour notre application, le système d'authentification et de gestion des utilisateurs doit :
Pour répondre à ces exigences, nous avons décidé d'utiliser les outils Okta. Okta est une société fondée en 2009 fournissant un logiciel cloud. Ce logiciel permet de gérer et de sécuriser la gestion des identités et des accès des utilisateurs. Le PDG d'Okta a annoncé qu'il comptait plus de 100 millions d'utilisateurs enregistrés en 2019. En outre, Okta est à la pointe des mesures de sécurité et des flux d'authentification à jour.
Fonctionnalités principales d'Okta
Comme le montre le graphique ci-dessous, Okta propose quatre fonctionnalités principales :
Dans Okta, il est simple pour un administrateur disposant des droits appropriés de créer d'autres utilisateurs et de leur attribuer les bons groupes. De cette façon, à chaque niveau de l'organisation, les utilisateurs et leurs autorisations sont gérables sans effort.
Exemple d'un utilisateur créé dans Okta avec ses groupes
Je vais maintenant vous expliquer comment nous avons intégré Okta avec Django admin et comment nous l'avons utilisé pour gérer les permissions de nos utilisateurs.
Pour ajouter la connexion d'administration avec Okta à Django admin, notre équipe a utilisé la bibliothèque mozilla-django-oidc . "Une bibliothèque légère d'authentification et de gestion des accès pour l'intégration avec les services d'authentification activés par OpenID Connect." OpenId Connect, également connu sous le nom d'OIDC, est une couche d'identité au-dessus du protocole OAuth 2.0. L'identité de l'utilisateur final peut être vérifiée avec l'authentification grâce à un serveur d'autorisation. OpenID Connect introduit le concept d'un id_token
, qui est un jeton de sécurité permettant au client de vérifier l'identité de l'utilisateur. Le id_token
obtient également des informations de base sur le profil de l'utilisateur. Il introduit le point de terminaison UserInfo, une API renvoyant des informations sur l'utilisateur.
Le protocole de connexion utilisé suit les étapes décrites dans le schéma suivant.
Schéma du protocole de connexion
Nous avons configuré l'URL de rappel avec le client_id
et ajouté le client_secret
dans nos paramètres pour acquérir le jeton d'Okta comme indiqué dans la documentation de la bibliothèque. Dans notre cas, nous avons utilisé un algorithme RS256.
# In settings.py# OktaOKTA_DOMAIN = os.environ.get("OKTA_DOMAIN")OKTA_TOKEN = os.environ.get("OKTA_TOKEN")# User informationUSER_CRM_ID = NoneUSER_EMAIL = None# Okta AdminOKTA_ADMIN_DOMAIN = OKTA_DOMAINOIDC_RP_SIGN_ALGO = "RS256"OIDC_OP_JWKS_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/keys"OIDC_OP_AUTHORIZATION_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/authorize"OIDC_OP_TOKEN_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/token"OIDC_OP_USER_ENDPOINT = f"{OKTA_ADMIN_DOMAIN}/oauth2/v1/userinfo"OIDC_RP_SCOPES = "openid profile email groups"OIDC_RP_CLIENT_ID = os.environ.get("OKTA_ADMIN_CLIENT_ID")OIDC_RP_CLIENT_SECRET = os.environ.get("OKTA_ADMIN_CLIENT_SECRET")OIDC_VERIFY_SSL = TrueLOGIN_REDIRECT_URL = f"{BASE_URL}/admin/"OIDC_REDIRECT_URL = f"{BASE_URL}/admin/oidc/callback/"OIDC_AUTH_REQUEST_EXTRA_PARAMS = {"redirect_uri": OIDC_REDIRECT_URL}
Il est désormais possible de remplacer le modèle de connexion. Nous avons ajouté un bouton permettant aux utilisateurs de se connecter avec leur compte Okta.
# In templates/admin/login.html# Admins can also log in through the usual credentials flow{% extends "admin/login.html" %}{% block extrastyle %} {{ block.super }} <style> #content-main { float: none !important; } .okta_login_container { margin-top: 15px; display: flex; justify-content: center; } </style>{% endblock %}{% block content %} {{ block.super }} <div class="okta_login_container"> <a href="{% url 'oidc_authentication_init' %}">Or Login With Okta</a> </div>{% endblock %}
Nouveau bouton pour se connecter avec Okta
Après avoir ajouté un moyen de se connecter via Okta à Django Admin, nous devons enregistrer et mettre à jour les utilisateurs. Nous obtenons leurs informations d'Okta et les ajoutons à Django. Pour ce faire, nous redéfinissons la classe OIDCAuthenticationBackend de mozilla-django-oidc. Nous pouvons obtenir les informations sur l'e-mail vérifié de l'utilisateur et le créer ou le mettre à jour dans Django, sans aucune autorisation pour le moment.
class OktaAdminAuthenticationBackend(OIDCAuthenticationBackend): def verify_claims(self, claims: OktaClaim) -> bool: return ( super().verify_claims(claims) and claims.get("email_verified", False) ) @transaction.atomic def create_user(self, claims: OktaClaim) -> User: user: User = self.UserModel.objects.create_user( claims.get("email"), None, # password first_name=claims["given_name"], last_name=claims["family_name"], ) user.save() return user @transaction.atomic def update_user(self, user: User, claims: OktaClaim) -> User: """Update existing user with new claims, if necessary save, and return user""" user.first_name = claims["given_name"] user.last_name = claims["family_name"] user.save() return user
Les administrateurs peuvent se connecter à l'application avec leurs identifiants Okta. Je vais vous montrer comment ajouter leurs autorisations en les synchronisant avec Okta.
Après avoir ajouté des utilisateurs à l'administrateur de Django, nous devons leur accorder les autorisations appropriées pour gérer le site Web du client. Dans mon projet, nous avions deux types d'administrateurs pour chaque équipe :
Administrateurs avec droits de base. Ils peuvent créer des documents pour les utilisateurs de leur équipe mais ne peuvent pas les publier.
Nous les avons nommés Admin - [Group Name]
dans Okta.
Contrôleurs. Ce sont des administrateurs qui peuvent valider et publier des documents pour les utilisateurs de leur équipe.
Nous les avons nommés Admin - [Group Name] Controller
dans Okta.
Exemple de deux groupes dans Okta
Dans Django Admin, nous avons décidé de créer deux types de groupe. Le premier est un groupe pour chaque équipe avec une autorisation de base. L'autre est un groupe général appelé Administrator Controller avec plus d'autorisations pour valider et publier des documents. Le graphique ci-dessous montre le flux pour attribuer des groupes aux administrateurs.
Flux de création d'utilisateurs et de groupes
Pour gérer ces autorisations, nous obtenons des informations sur l'utilisateur à partir de la réponse Okta qui contient les groupes d'utilisateurs. Nous pouvons séparer ces groupes selon nos règles commerciales décrites ci-dessus.
def handle_controller_groups(self, groups): groups_with_controller = set() for group in groups: # remove Controllers groups and add generic 'Administrator Controller' if bool(re.search("[Cc]ontroller", group)): groups_with_controller.add(ADMINISTRATOR_CONTROLLER) else: groups_with_controller.add(group) return groups_with_controllerdef get_user_groups(self, claims: OktaClaim) -> QuerySet: claim_groups = claims.get("groups") assert claim_groups groups = [group[8:] for group in claim_groups] # remove `Admin - ` prefix groups_with_controllers = self.handle_controller_groups(groups) return Group.objects.filter(name__in=groups_with_controllers)
Enfin, nous utilisons ces fonctions pour obtenir les autorisations des utilisateurs lorsque nous les créons et les mettons à jour.
def verify_claims(self, claims: OktaClaim) -> bool: return ( super().verify_claims(claims) and claims.get("email_verified", False) and claims.get("groups") is not None )@transaction.atomicdef create_user(self, claims: OktaClaim) -> User: user: User = self.UserModel.objects.create_user( claims.get("email"), None, # password first_name=claims["given_name"], last_name=claims["family_name"], ) user.groups.set(self.get_user_groups(claims)) user.save() return user@transaction.atomicdef update_user(self, user: User, claims: OktaClaim) -> User: """Update existing user with new claims, if necessary save, and return user""" user.first_name = claims["given_name"] user.last_name = claims["family_name"] user.groups.set(self.get_user_groups(claims)) user.save() return user
Nos administrateurs peuvent créer leurs documents avec les bonnes autorisations et seuls les membres de leur équipe peuvent les voir. De plus, les administrateurs du contrôleur peuvent gérer leur équipe et réviser les documents pour les publier.
Avec cette implémentation, les administrateurs n'ont pas besoin de nous appeler pour gérer leurs équipes et ils n'ont besoin que de leurs identifiants Okta pour effectuer leurs différentes tâches.
L'une des limitations est que si un nouveau groupe est créé, il doit être ajouté dans Okta et Django pour permettre aux utilisateurs d'avoir leurs autorisations lorsqu'ils se connectent. Nous avons décidé que nous ne voulions pas créer de groupes lorsque nous ne reconnaissions pas dans Django pour éviter les problèmes d'autorisations, car les administrateurs peuvent télécharger des informations sensibles.
J'espère que vous avez apprécié la lecture de cet article et que vous avez appris une nouvelle façon de gérer les autorisations des administrateurs avec Okta et Django admin. J'espère que vous allez essayer!
Source : https://blog.theodo.com/2021/03/okta-sso-with-django-admin/