1598900160
Service workers enable web sites to work offline using the Cache API. Developers need to design the logic to manage how site assets are persisted in storage.
This can lead to many challenges for developers to solve when planning their caching strategies.
How much is too much? And what is the minimum my application needs?
Page assets come in many forms, HTML, CSS, JavaScript, images and font files are obvious. These are all classified as URL addressable. This means you can type a URL in the browser address bar and retrieve the file.
Your origin (domain name) is given a certain amount of free space to do what it wants with. That free space is shared between all origin storage: LocalStorage, IndexedDB, Filesystem, and of course Caches. The amount available to service worker caching isn’t defined in the specification. The amount varies by browser depending on device and storage conditions.
Files are not the only content that can be cached. localStorage is great to persist key value pairs where the values are strings. IndexedDB is more robust and can store many more types of data efficiently. I think of it a a light weight document database in the browser. appCache and service worker cache persist files, URL addressable resources to be technically correct.
But service worker cache is not the only browser storage medium you need to monitor. In addition to the service worker cache size limit you should also ask the following questions:
You could add appCache to the mix, but of course that is moot when a service worker is registered. Plus appCache is being deprecated by all browsers today.
How much space do you get and what happens when that space runs out?
#progressive web app
1624445068
As a small business owner, you should never think that SEO services are not for you. The search engine optimization services India from this digital marketing agency offer SEO services for small businesses and enterprises to make sure that they get in competition with bigger websites. They deliver on-page, off-page, local SEO and ecommerce SEO services.
#search engine optimization services india #seo services india #affordable seo services india #seo services provider #website seo services #outsource seo services india
1623408615
With the advancement in technology, many products have found a dire need to showcase their product virtually and to make the virtual experience as clear as actual a technology called 3D is used. The 3D technology allows a business to showcase their products in 3 dimensions virtually.
Want to develop an app that showcases anything in 3D?
WebClues Infotech with its expertise in mobile app development can seamlessly connect a technology that has the capability to change an industry with its integration in the mobile app. After successfully serving more than 950 projects WebClues Infotech is prepared with its highly skilled development team to serve you.
Want to know more about our 3D design app development?
Visit us at
https://www.webcluesinfotech.com/3d-design-services/
Visit: https://www.webcluesinfotech.com/3d-design-services/
Share your requirements https://www.webcluesinfotech.com/contact-us/
View Portfolio https://www.webcluesinfotech.com/portfolio/
#3d design service provide #3d design services #3d modeling design services #professional 3d design services #industrial & 3d product design services #3d web design & development company
1619096139
Having a multi-services app would help you to excel in your on-demand services business. An on-demand app solution empowers entrepreneurs to offer multiple on-demand services in a single app. In short, this is an efficient app to run a business successfully. If you are an entrepreneur who plans to start a business with the multi-services app, go forward with the multi-service app development.
What are the multiple services offered in the on-demand multi-services app?
Services are categorized as follows.
Ride services – Taxi ride, Moto ride, Car rental, and Moto rental.
Delivery services – Food delivery, Courier delivery, Logistics delivery, Grocery delivery, Medicine delivery, Flower delivery, Fuel delivery, and Plant delivery.
Other services – Plumber, Electrician, Car wash, Fitness, Handyman, Car repair, and beauty services.
Apart from these, you can consider integrating several other services while developing your app.
3 Significant reasons to invest in the on-demand multi-services app
The first and foremost reason why customers use this app is the on-demand multi-service on one platform. Usually, people do not like to install so many apps for availing various services. Instead, they can have a single app for that. This is the reason why the demand for such apps is high.
Next, the incurred cost is less in this app when compared to the single service app. With the seamless navigation feature, customers can easily avail of any services with just a few taps.
Thirdly, they feel more convenient in availing themselves various services in one platform.
Future scope of the multi-service industry
There are 7.6 million users for the multi-service apps in 2019. Recently, the demand for such apps is high considerably due to the covid-19 pandemic. It is expected to flourish more in the future. By 2023, this industry will hit 161.74 billion. This is so inspiring and so many entrepreneurs plan to propel into this industry in 2021.
Consider the following aspects for multi-service app development
Integrate the Multilingual and Multiple currencies features
Never let language be a barrier to your business. Therefore, incorporate the multilingual feature so that customers can use the app in their languages.
The global launch will help you to have a more extensive user base for your app. Just like language, do not let the currency restrict you from launching your app across many countries.
User-friendly design
The UI/UX of the app has to be simple and appealing. This plays a vital role in gaining more customers. If the design is not user-friendly and unimpressive, they won’t prefer your app for the next time. Instead, they prefer using your competitors’ app for availing multiple services. To gain new customers and to retain the existing customers, focus on the app design.
App platform
To cover all the audiences, consider launching the app on both the Android and iOS platforms. Decide on which platform you will launch the app based on your target audience.
White-label solution
It is a known fact that making an app from scratch needs more time and requires a considerable amount of money. On the counter side, creating the app using the white-label solution is budget-friendly and time-conserving. Because, it is a readily available solution. Upon making modifications, you can launch the app instantly. Being the customizable solution, any new features can be incorporated based on the requirements.
The decision of starting a business with the on-demand multi-services app is good as the market will flourish further in the upcoming days. Take away the points from this blog to withstand in the highly competitive market. Reach out to Uberlikeapp for multi-services app development. We provide a customizable app solution that is scalable based on your needs.
#on demand multi services app #multi services app development #multi service booking app #on-demand service app clone #on-demand multi-services app solution
1659852060
Curly is a template language that completely separates structure and logic. Instead of interspersing your HTML with snippets of Ruby, all logic is moved to a presenter class.
Installing Curly is as simple as running gem install curly-templates
. If you're using Bundler to manage your dependencies, add this to your Gemfile
gem 'curly-templates'
Curly can also install an application layout file, replacing the .erb file commonly created by Rails. If you wish to use this, run the curly:install
generator.
$ rails generate curly:install
In order to use Curly for a view or partial, use the suffix .curly
instead of .erb
, e.g. app/views/posts/_comment.html.curly
. Curly will look for a corresponding presenter class named Posts::CommentPresenter
. By convention, these are placed in app/presenters/
, so in this case the presenter would reside in app/presenters/posts/comment_presenter.rb
. Note that presenters for partials are not prepended with an underscore.
Add some HTML to the partial template along with some Curly components:
<!-- app/views/posts/_comment.html.curly -->
<div class="comment">
<p>
{{author_link}} posted {{time_ago}} ago.
</p>
{{body}}
{{#author?}}
<p>{{deletion_link}}</p>
{{/author?}}
</div>
The presenter will be responsible for providing the data for the components. Add the necessary Ruby code to the presenter:
# app/presenters/posts/comment_presenter.rb
class Posts::CommentPresenter < Curly::Presenter
presents :comment
def body
SafeMarkdown.render(@comment.body)
end
def author_link
link_to @comment.author.name, @comment.author, rel: "author"
end
def deletion_link
link_to "Delete", @comment, method: :delete
end
def time_ago
time_ago_in_words(@comment.created_at)
end
def author?
@comment.author == current_user
end
end
The partial can now be rendered like any other, e.g. by calling
render 'comment', comment: comment
render comment
render collection: post.comments
Curly components are surrounded by curly brackets, e.g. {{hello}}
. They always map to a public method on the presenter class, in this case #hello
. Methods ending in a question mark can be used for conditional blocks, e.g. {{#admin?}} ... {{/admin?}}
.
Curly components can specify an identifier using the so-called dot notation: {{x.y.z}}
. This can be very useful if the data you're accessing is hierarchical in nature. One common example is I18n:
<h1>{{i18n.homepage.header}}</h1>
# In the presenter, the identifier is passed as an argument to the method. The
# argument will always be a String.
def i18n(key)
translate(key)
end
The identifier is separated from the component name with a dot. If the presenter method has a default value for the argument, the identifier is optional – otherwise it's mandatory.
In addition to an identifier, Curly components can be annotated with attributes. These are key-value pairs that affect how a component is rendered.
The syntax is reminiscent of HTML:
<div>{{sidebar rows=3 width=200px title="I'm the sidebar!"}}</div>
The presenter method that implements the component must have a matching keyword argument:
def sidebar(rows: "1", width: "100px", title:); end
All argument values will be strings. A compilation error will be raised if
You can define default values using Ruby's own syntax. Additionally, if the presenter method accepts arbitrary keyword arguments using the **doublesplat
syntax then all attributes will be valid for the component, e.g.
def greetings(**names)
names.map {|name, greeting| "#{name}: #{greeting}!" }.join("\n")
end
{{greetings alice=hello bob=hi}}
<!-- The above would be rendered as: -->
alice: hello!
bob: hi!
Note that since keyword arguments in Ruby are represented as Symbol objects, which are not garbage collected in Ruby versions less than 2.2, accepting arbitrary attributes represents a security vulnerability if your application allows untrusted Curly templates to be rendered. Only use this feature with trusted templates if you're not on Ruby 2.2 yet.
If there is some content you only want rendered under specific circumstances, you can use conditional blocks. The {{#admin?}}...{{/admin?}}
syntax will only render the content of the block if the admin?
method on the presenter returns true, while the {{^admin?}}...{{/admin?}}
syntax will only render the content if it returns false.
Both forms can have an identifier: {{#locale.en?}}...{{/locale.en?}}
will only render the block if the locale?
method on the presenter returns true given the argument "en"
. Here's how to implement that method in the presenter:
class SomePresenter < Curly::Presenter
# Allows rendering content only if the locale matches a specified identifier.
def locale?(identifier)
current_locale == identifier
end
end
Furthermore, attributes can be set on the block. These only need to be specified when opening the block, not when closing it:
{{#square? width=3 height=3}}
<p>It's square!</p>
{{/square?}}
Attributes work the same way as they do for normal components.
Sometimes you want to render one or more items within the current template, and splitting out a separate template and rendering that in the presenter is too much overhead. You can instead define the template that should be used to render the items inline in the current template using the collection block syntax.
Collection blocks are opened using an asterisk:
{{*comments}}
<li>{{body}} ({{author_name}})</li>
{{/comments}}
The presenter will need to expose the method #comments
, which should return a collection of objects:
class Posts::ShowPresenter < Curly::Presenter
presents :post
def comments
@post.comments
end
end
The template within the collection block will be used to render each item, and it will be backed by a presenter named after the component – in this case, comments
. The name will be singularized and Curly will try to find the presenter class in the following order:
Posts::ShowPresenter::CommentPresenter
Posts::CommentPresenter
CommentPresenter
This allows you some flexibility with regards to how you want to organize these nested templates and presenters.
Note that the nested template will only have access to the methods on the nested presenter, but all variables passed to the "parent" presenter will be forwarded to the nested presenter. In addition, the current item in the collection will be passed, as well as that item's index in the collection:
class Posts::CommentPresenter < Curly::Presenter
presents :post, :comment, :comment_counter
def number
# `comment_counter` is automatically set to the item's index in the collection,
# starting with 1.
@comment_counter
end
def body
@comment.body
end
def author_name
@comment.author.name
end
end
Collection blocks are an alternative to splitting out a separate template and rendering that from the presenter – which solution is best depends on your use case.
While collection blocks allow you to define the template that should be used to render items in a collection right within the parent template, context blocks allow you to define the template for an arbitrary context. This is very powerful, and can be used to define widget-style components and helpers, and provide an easy way to work with structured data. Let's say you have a comment form on your page, and you'd rather keep the template inline. A simple template could look like:
<!-- post.html.curly -->
<h1>{{title}}</h1>
{{body}}
{{@comment_form}}
<b>Name: </b> {{name_field}}<br>
<b>E-mail: </b> {{email_field}}<br>
{{comment_field}}
{{submit_button}}
{{/comment_form}}
Note that an @
character is used to denote a context block. Like with collection blocks, a separate presenter class is used within the block, and a simple convention is used to find it. The name of the context component (in this case, comment_form
) will be camel cased, and the current presenter's namespace will be searched:
class PostPresenter < Curly::Presenter
presents :post
def title; @post.title; end
def body; markdown(@post.body); end
# A context block method *must* take a block argument. The return value
# of the method will be used when rendering. Calling the block argument will
# render the nested template. If you pass a value when calling the block
# argument it will be passed to the presenter.
def comment_form(&block)
form_for(Comment.new, &block)
end
# The presenter name is automatically deduced.
class CommentFormPresenter < Curly::Presenter
# The value passed to the block argument will be passed in a parameter named
# after the component.
presents :comment_form
# Any parameters passed to the parent presenter will be forwarded to this
# presenter as well.
presents :post
def name_field
@comment_form.text_field :name
end
# ...
end
end
Context blocks were designed to work well with Rails' helper methods such as form_for
and content_tag
, but you can also work directly with the block. For instance, if you want to directly control the value that is passed to the nested presenter, you can call the call
method on the block yourself:
def author(&block)
content_tag :div, class: "author" do
# The return value of `call` will be the result of rendering the nested template
# with the argument. You can post-process the string if you want.
block.call(@post.author)
end
end
If you find yourself opening a context block just in order to use a single component, e.g. {{@author}}{{name}}{{/author}}
, you can use the shorthand syntax instead: {{author:name}}
. This works for all component types, e.g.
{{#author:admin?}}
<p>The author is an admin!</p>
{{/author:admin?}}
The syntax works for nested contexts as well, e.g. {{comment:author:name}}
. Any identifier and attributes are passed to the target component, which in this example would be {{name}}
.
Although most code in Curly presenters should be free of side effects, sometimes side effects are required. One common example is defining content for a content_for
block.
If a Curly presenter class defines a setup!
method, it will be called before the view is rendered:
class PostPresenter < Curly::Presenter
presents :post
def setup!
content_for :title, post.title
content_for :sidebar do
render 'post_sidebar', post: post
end
end
end
In order to have {{
appear verbatim in the rendered HTML, use the triple Curly escape syntax:
This is {{{escaped}}.
You don't need to escape the closing }}
.
If you want to add comments to your Curly templates that are not visible in the rendered HTML, use the following syntax:
{{! This is some interesting stuff }}
Presenters are classes that inherit from Curly::Presenter
– they're usually placed in app/presenters/
, but you can put them anywhere you'd like. The name of the presenter classes match the virtual path of the view they're part of, so if your controller is rendering posts/show
, the Posts::ShowPresenter
class will be used. Note that Curly is only used to render a view if a template can be found – in this case, at app/views/posts/show.html.curly
.
Presenters can declare a list of accepted variables using the presents
method:
class Posts::ShowPresenter < Curly::Presenter
presents :post
end
A variable can have a default value:
class Posts::ShowPresenter < Curly::Presenter
presents :post
presents :comment, default: nil
end
Any public method defined on the presenter is made available to the template as a component:
class Posts::ShowPresenter < Curly::Presenter
presents :post
def title
@post.title
end
def author_link
# You can call any Rails helper from within a presenter instance:
link_to author.name, profile_path(author), rel: "author"
end
private
# Private methods are not available to the template, so they're safe to
# use.
def author
@post.author
end
end
Presenter methods can even take an argument. Say your Curly template has the content {{t.welcome_message}}
, where welcome_message
is an I18n key. The following presenter method would make the lookup work:
def t(key)
translate(key)
end
That way, simple ``functions'' can be added to the Curly language. Make sure these do not have any side effects, though, as an important part of Curly is the idempotence of the templates.
Both layouts and content blocks (see content_for
) use yield
to signal that content can be inserted. Curly works just like ERB, so calling yield
with no arguments will make the view usable as a layout, while passing a Symbol will make it try to read a content block with the given name:
# Given you have the following Curly template in
# app/views/layouts/application.html.curly
#
# <html>
# <head>
# <title>{{title}}</title>
# </head>
# <body>
# <div id="sidebar">{{sidebar}}</div>
# {{body}}
# </body>
# </html>
#
class ApplicationLayout < Curly::Presenter
def title
"You can use methods just like in any other presenter!"
end
def sidebar
# A view can call `content_for(:sidebar) { "some HTML here" }`
yield :sidebar
end
def body
# The view will be rendered and inserted here:
yield
end
end
In order to make a Rails helper method available as a component in your template, use the exposes_helper
method:
class Layouts::ApplicationPresenter < Curly::Presenter
# The components {{sign_in_path}} and {{root_path}} are made available.
exposes_helper :sign_in_path, :root_path
end
Presenters can be tested directly, but sometimes it makes sense to integrate with Rails on some levels. Currently, only RSpec is directly supported, but you can easily instantiate a presenter:
SomePresenter.new(context, assigns)
context
is a view context, i.e. an object that responds to render
, has all the helper methods you expect, etc. You can pass in a test double and see what you need to stub out. assigns
is the hash containing the controller and local assigns. You need to pass in a key for each argument the presenter expects.
In order to test presenters with RSpec, make sure you have rspec-rails
in your Gemfile. Given the following presenter:
# app/presenters/posts/show_presenter.rb
class Posts::ShowPresenter < Curly::Presenter
presents :post
def body
Markdown.render(@post.body)
end
end
You can test the presenter methods like this:
# You can put this in your `spec_helper.rb`.
require 'curly/rspec'
# spec/presenters/posts/show_presenter_spec.rb
describe Posts::ShowPresenter, type: :presenter do
describe "#body" do
it "renders the post's body as Markdown" do
assign(:post, double(:post, body: "**hello!**"))
expect(presenter.body).to eq "<strong>hello!</strong>"
end
end
end
Note that your spec must be tagged with type: :presenter
.
Here is a simple Curly template – it will be looked up by Rails automatically.
<!-- app/views/posts/show.html.curly -->
<h1>{{title}}<h1>
<p class="author">{{author}}</p>
<p>{{description}}</p>
{{comment_form}}
<div class="comments">
{{comments}}
</div>
When rendering the template, a presenter is automatically instantiated with the variables assigned in the controller or the render
call. The presenter declares the variables it expects with presents
, which takes a list of variables names.
# app/presenters/posts/show_presenter.rb
class Posts::ShowPresenter < Curly::Presenter
presents :post
def title
@post.title
end
def author
link_to(@post.author.name, @post.author, rel: "author")
end
def description
Markdown.new(@post.description).to_html.html_safe
end
def comments
render 'comment', collection: @post.comments
end
def comment_form
if @post.comments_allowed?
render 'comment_form', post: @post
else
content_tag(:p, "Comments are disabled for this post")
end
end
end
Caching is handled at two levels in Curly – statically and dynamically. Static caching concerns changes to your code and templates introduced by deploys. If you do not wish to clear your entire cache every time you deploy, you need a way to indicate that some view, helper, or other piece of logic has changed.
Dynamic caching concerns changes that happen on the fly, usually made by your users in the running system. You wish to cache a view or a partial and have it expire whenever some data is updated – usually whenever a specific record is changed.
Because of the way logic is contained in presenters, caching entire views or partials by the data they present becomes exceedingly straightforward. Simply define a #cache_key
method that returns a non-nil object, and the return value will be used to cache the template.
Whereas in ERB you would include the cache
call in the template itself:
<% cache([@post, signed_in?]) do %>
...
<% end %>
In Curly you would instead declare it in the presenter:
class Posts::ShowPresenter < Curly::Presenter
presents :post
def cache_key
[@post, signed_in?]
end
end
Likewise, you can add a #cache_duration
method if you wish to automatically expire the fragment cache:
class Posts::ShowPresenter < Curly::Presenter
...
def cache_duration
30.minutes
end
end
In order to set any cache option, define a #cache_options
method that returns a Hash of options:
class Posts::ShowPresenter < Curly::Presenter
...
def cache_options
{ compress: true, namespace: "my-app" }
end
end
Static caching will only be enabled for presenters that define a non-nil #cache_key
method (see Dynamic Caching.)
In order to make a deploy expire the cache for a specific view, set the version
of the view to something new, usually by incrementing by one:
class Posts::ShowPresenter < Curly::Presenter
version 3
def cache_key
# Some objects
end
end
This will change the cache keys for all instances of that view, effectively expiring the old cache entries.
This works well for views, or for partials that are rendered in views that themselves are not cached. If the partial is nested within a view that is cached, however, the outer cache will not be expired. The solution is to register that the inner partial is a dependency of the outer one such that Curly can automatically deduce that the outer partial cache should be expired:
class Posts::ShowPresenter < Curly::Presenter
version 3
depends_on 'posts/comment'
def cache_key
# Some objects
end
end
class Posts::CommentPresenter < Curly::Presenter
version 4
def cache_key
# Some objects
end
end
Now, if the version
of Posts::CommentPresenter
is bumped, the cache keys for both presenters would change. You can register any number of view paths with depends_on
.
Curly integrates well with the caching mechanism in Rails 4 (or Cache Digests in Rails 3), so the dependencies defined with depends_on
will be tracked by Rails. This will allow you to deploy changes to your templates and have the relevant caches automatically expire.
Thanks to Zendesk for sponsoring the work on Curly.
Author: zendesk
Source code: https://github.com/zendesk/curly
1608125898
French translation services are very much adequate for the people who want to convey their brand reports, information, and other essentials to the French clients or audience. If the businesses can convey with the clients in their native language, then probably the business will experience a progressive hike.
French is one of the best known European languages, and more than 80 million people across the globe speak this language. Therefore, if you are running an MNC, then you might need to leverage the opportunity for seeking sales or business from those 80 million people across the globe.
For better clarity, you must know that French is the second language for more than 100 million people across the globe. If you are wondering why you need the French translation services, then follow this article till the end to get the proper guide on how the professional French translation services can help you out.
At NNB Transtech, we provide All Foreign Language Translation Services.
Hiring Professional French Translation Services!
The professional French translation services offered by the major companies are to help the new and established companies reach out to the French-speaking audience or clients for better business. There are professional firms that are dedicated to offering the best translation services to the top MNCs with the help of subject matter translation experts.
The best part about hiring professionals is that they have a team of French experts who are proficient in different backgrounds. For instance, the professional French translators working in a firm are knowledgeable about Finance, healthcare, automobile, business, and other such niches. Therefore, accuracy is its prime commitment. So, the first step to avail the perfect French translation is to hire the best firm that is offering you ideal French translation services as per your needs and requirements within the specified budget.
The top corporations & organizations are very commonly in touch with clients and consumers all across the globe. Therefore, getting the documents and essentials translated into French is important for the companies to establish healthy communication with the French-speaking audience or clients.
Explain Your French Translation Project to the Professionals
The French translation service providers will assign a project manager for your translation needs. They are trained to understand and pen down everything you need and want to be mentioned in the translated document or promotional media.
Whether you seek French translation for websites or documents, you need to elaborate on the business or field it is related to. Once you do that, you will be asked for giving details on the facts and figures that you don’t want to be altered and should be present in the final output compulsorily.
The medical documents and accounting papers need to be perfectly accurate in terms of figures and facts. No business or individual will want it altered! The skilled employees are well aware of the facts and figures as they are subject matter experts.
But even then, they prefer taking instructions from the clients to overlook the work done before delivering it to the client.
After you explain your project, you will be given a deadline, and the work will begin. Irrespective of the complexity of the document, the professional translators will get it done without much hassle. The professional firms have the right certifications to handle your diverse translation projects.
Start of the Translation Project
After you have handed over your important document or other essential for the French translation, the experts will commence with the work. They have the right tools and expertise to start with quality translation work.
The professional French translation firms make sure to do the translation humanly. It is so because the machines are not accurate and it takes a lot of time to review the machine-translated documents. Therefore, to promote perfection in terms of the French translation, the professionals get it done by humans for utmost accuracy on priority.
Whether you have a medical, technical, financial, or legal document for translation, the experts are certified professionals in the respective background to handle your project. They will start as per your instructions that you stated in the previous step.
You can get the translated document in the desired format such as Adobe in Design, PowerPoint, MSWord, PDF, and others. If you are willing to get your documents translated from English to French without compromising on quality and at affordable pricing, seeking help from professionals is the best option for you.
Delivery of the Translated French Document
After the document has been translated, it is then sent to the review team to look at the accuracy of all the facts and figures. It is the job of the professionals to look after the accuracy of the documents to make them convey the right information to the French clients and consumers.
They are determined to offer you excellent quality, and for that, a proper review is highly demanded before the delivery of the work to the clients. Along with that, the professional firms are open for any type of edits as per the request from the clients.
The professionals leave no loopholes for bringing up the chances of edits. But even if you need more perfection, you can always reach out to your outsourced team to get the edits done without any additional charges. Therefore, the professionals are highly preferred for French translation overdoing it on your own.
Conclusion
These are the steps that act as the guide for you as well as the professional French translation firms to help you offer the best services at affordable pricing. You might be wondering whether to take the help of professional firms or hire an individual language expert.
An amateur language expert might not be proficient with tools and essentials to handle your multiple needs in the French translation project. You might be limited on the outputs by hiring individuals for your projects.
Therefore, it is better to seek help from professionals to help your business get the best benefits by putting up the best French translated documents for healthy communication with French-speaking clients or consumers across the globe.
#french translation services #spanish translation services #japanese translation services #german translation services #translation services