Coder Social home page Coder Social logo

wordpress-fontawesome's Introduction

wordpress-fontawesome

Font Awesome 6 Official WordPress Package

This guide is for developers seeking to use wordpress-fontawesome as a package in a WordPress plugin or theme.

WordPress users should consult the plugin's description in the WordPress plugin directory for guidance on using Font Awesome in WordPress.

Contents

Description

This package adds to your plugin or theme the following abilities:

  • use Font Awesome SVG, Web Font, Free or Pro, with version 4 compatibility, loading from the Font Awesome CDN.
  • use Font Awesome Kits
  • an [icon] shortcode
  • detection and resolution of Font Awesome version conflicts introduced by other themes or plugins
  • coordination of configuration preferences by any number of plugins or theme that may be using this package on the same WordPress site.
  • management of Font Awesome account authorization via API Token
  • management of Font Awesome releases metadata (available versions and related metadata)
  • Font Awesome GraphQL API queries authorized by the site owner's API Token

Why Use a Package?

If you're a WordPress developer, then you already know how to use wp_enqueue_style or wp_enqueue_script to load assets like Font Awesome. So why take a dependency on another package to do that for you?

Compatibility and Troubleshooting

Because Font Awesome is so popular among themes and plugins, and because it's so easy for a developer to enqueue the Font Awesome assets, it's become a jungle out there for our users.

Some WordPress site owners have been known to have a theme and three different plugins installed, each trying to load its own self-hosted version of Font Awesome:

  • mixing version 4 or 5 with version 6
  • mixing SVG with Web Font
  • sometimes even Font Awesome version 3

This package provides sophisticated conflict detection, resolution, and error reporting, empowering our users to solve their compatibility problems quickly.

Enabling Font Awesome Pro

Also, back when many themes and plugins began including Font Awesome, there was no Pro version. Now there is, and there's a constant stream of new icons, styles, and features being added.

Font Awesome Pro subscribers should be able to use their Pro goodies in your theme or plugin. But since Font Awesome's licensing doesn't allow you to distribute Font Awesome Pro, you'd have to rely on the user to do some kind of setup on their end to enable it. Why reinvent that wheel?

And even if you do, you'd still have those compatibility problems with other themes and plugins, which you may be making even worse by giving the user yet another way to add another conflicting version of Font Awesome to their WordPress site.

Staying Current

Some WordPress developers have solvd the Pro problem by not shipping the Font Awesome assets, but shipping the Pro metadata to drive their icon choosers. That locks you into whatever version of Font Awesome Pro you happened snapshot when you release. But again, there's a constant flow of new icons and features being added to Font Awesome Pro. Font Awesome Pro subscribers love having access to those new icons when they come out, so let's help them stay current.

This package allows the user to manage the version of Font Awesome, while giving you, the developer, runtime access to all metadata for whatever version the user chooses.

Icon Search

Power-up those icon choosers with integrated Algolia search--the same icon search that powers the Icon Gallery on fontawesome.com. With 7,000+ icons and growing, search makes finding the right icon--by name, category, or conceptual similarity--much easier for users. Why re-invent that wheel?

Future Features

We can't say much right now, but there some big stuff coming to Font Awesome Pro that will only be accessible through an authenticated Font Awesome account.

You could manage everything related to authorizing Font Awesome accounts to access those features (which your users are definitely going to want to use on their WordPress sites!) But again, why re-invent that wheel?

Adding as a Composer Package

composer require fortawesome/wordpress-fontawesome

In your code, requiring this package's index.php will cause the version of the package as bundled by your theme or plugin to be added to the list of possible versions to be loaded by the FontAwesome_Loader. The loader coordinates among potentially multiple installations of the plugin, ensuring that the latest available version of the package is loaded and used at run time.

require_once __DIR__ . '/vendor/fortawesome/wordpress-fontawesome/index.php';

# optional, for conveniece
use function FortAwesome\fa;

Register your code as a client

You should register your code as a client of Font Awesome, even if you have no configuration preferences to specify, because the Font Awesome Troubleshoot tab will show the WP admin a listing of which plugins or themes are actively using Font Awesome, what their preferences are, and what conflicts there may be.

Do not register any preferences if you don't really need to. It will be a better experience for the WP admin user if your theme or plugin can adapt to their changes of Font Awesome preferences without complaint from your code.

See the API documentation for the preferences schema.

add_action(
    'font_awesome_preferences',
    function() {
        fa()->register(
            array(
                'name' => 'plugin foo'
                // other preferences would be registered here
            )
        );
    }
);

Register Hooks for Initialization and Cleanup

There are basic principles for initialization and cleanup that apply in either case, but the implementation details will vary depending on whether you're building a theme or a plugin.

Activation

When your theme or plugin is activated, it should invoke FortAwesome\FontAwesome_Loader::initialize.

This will ensure that Font Awesome is initialized without interfering with any existing Font Awesome configuration that may already be present from some other theme's or plugin's use of this package. In other words initialize() can be called multiple times, but subsequent invocations will not overwrite or reset prior saved settings.

Plugin Activation

Your plugin code should do something like this:

register_activation_hook(
	__FILE__,
	'FortAwesome\FontAwesome_Loader::initialize'
);

Theme Activation

Your theme code should do something like this:

add_action('after_switch_theme', 'FortAwesome\FontAwesome_Loader::initialize');

Deactivation

When your theme or plugin is deactivated, it should invoke FortAwesome\FontAwesome_Loader::maybe_deactivate.

This will ensure that the Font Awesome deactivation logic is run if your theme or plugin is the last known client of Font Awesome. Otherwise, the state of the database is left alone, for the sake of any remaining Font Awesome clients.

Plugins have a specific deactivation hook that is separate from an uninstall hook. There are different things to clean up in each case.

Themes don't have the same lifecyle hooks as plugins. In your theme, you might want to handle deactivation and uninstallation differently than the examples below, but these will get the job done.

Plugin Deactivation

Your plugin code should do something like this:

register_deactivation_hook(
	__FILE__,
	'FortAwesome\FontAwesome_Loader::maybe_deactivate'
);

Theme Deactivation

A theme is deactivated when some other theme is activated instead. At that time, the switch_theme action is fired. This is an opportunity for your theme to run both the deactivation and uninstallation logic. Both should probably be run from that one callback, since there's no separate, subsequent uninstall hook for themes as there is for plugins.

(NOTE: if you're a theme developer who knows a better pattern for us to use here, please open an issue on this repo with a suggestion.)

add_action('switch_theme', function() {
	FortAwesome\FontAwesome_Loader::maybe_deactivate();
	FortAwesome\FontAwesome_Loader::maybe_uninstall();
});

Uninstallation

When your theme or plugin is uninstalled, it should invoke FortAwesome\FontAwesome_Loader::maybe_uninstall.

Similarly, this will ensure that the Font Awesome uninstall logic is run if your theme or plugin is the last known client of Font Awesome. Otherwise, the state of the database is left alone, for the sake of other themes or plugins.

Plugin Uninstall

Your code should do something like this:

register_uninstall_hook(
	__FILE__,
	'FortAwesome\FontAwesome_Loader::maybe_uninstall'
);

Theme Uninstall

There's no hook for themes that's analogous to the register_uninstall_hook for plugins. For themes, our last chance to run uninstall logic is on the switch_theme action hook, as noted above under Theme Deactivation.

Installing as a Separate Plugin

This package is also available as a plugin in the WordPress plugin directory.

You could instruct your users to install that plugin separately. Once activated, using the PHP API works the same as if you had included this package via composer.

API References

Here are some relevant APIs:

  • PHP API: any theme or plugin developer probably needs this
  • GraphQL API: you may need this if you write code to query for metadata about icons, such as when building an icon chooser
  • JavaScript API: you may need this if you are working directly with the JavaScript objects, such as when for doing some custom SVG rendering in Gutenberg blocks
  • react-fontawesome component: you might prefer this instead of doing low-level JS/SVG rendering

Usage in Pages, Posts, and Templates

<i> tags

Your templates can use standard <i> tags in the all the ways described in the Font Awesome quick start.

If Font Awesome is configured to use SVG technology, you can also use all of the SVG-only features, like Power Transforms.

[icon] shortcode

[icon name="stroopwafel" prefix="fal"]

The name attribute is just the name of the icon, not the CSS class name.

The prefix attribute defaults to fas, but must be specified for other styles.

Avoid :before pseudo-elements

Many themes and plugins use CSS Pseudo-elements to do things like adding icons :before the <li> elements in menus.

This was a common practice for users of Font Awesome 4 and earlier and tends to work fine as long as the font-family in your CSS rules is known and never changes, and as long as the Font Awesome technology is always CSS with Web Font, and not SVG.

You should not make any of those assumptions. It's one of the most causes of "my icons are broken" when WordPress users attempt to change the version of Font Awesome loaded on their site.

Font Awesome 5 & 6 do not use the same font-family as Font Awesome 4 did. It uses multiple different font-family values that vary by icon style.

Also, while pseudo-elements perform nicely with CSS and Web Font technology, getting them to work with the SVG technology requires a lot of extra processing that can cause significant performance problems in the browser. It's really only provided as an accommodation when pseudo-elements can't be avoided. This is why pseudo-elements are not enabled by default when configured for SVG technology.

Your plugin can register a preference for Web Font technology or pseudo-elements, if you must. But the WordPress site owner ultimately determines the configuration of Font Awesome. They may have to negotiate the requirements of multiple plugins or themes, some of which may not be playing nice. It can be a difficult balancing act.

Ease their pain by using a flexible and maximally compatible approach in your code.

Simply using <i> tags or [icon] shortcodes avoids the potential compatibility or performance problems that come with pseudo-elements.

Usage in Gutenberg (Blocks)

There are several ways one might incorporate Font Awesome icons in Gutenberg development.

Here are some considerations for you as you determine your approach:

i2svg auto-replaces <i> elements with <svg> elements

The default configuration of the SVG with JavaScript technology that is loaded by this package, whether via CDN or Kit, is autoReplaceSvg: true. This means that:

  1. When the DOM loads, any <i> tags that look like Font Awesome icons are replaced with their correspoding <svg> elements.
  2. Any time the DOM is mutated to insert an <i> element dynamically, that <i> element is also replaced with its corresponding <svg>.

So, if your Gutenberg code renders icons as <i> tags, and the active Font Awesome technology is SVG, then your rendered <i> tags will be immediately replaced with <svg> elements. That may or may not be what you want.

If the autoReplaceSvg behavior is not what you want, you should not disable it if there's any chance that other themes, plugins or content creators may be relying on it. Instead, consider one of the alternatives to <i> tags below.

Font Awesome might be configured for Web Font

The WordPress admin may have enabled Web Font technology instead of SVG.

This is not necessarily a problem, as long as your Gutenberg code is only rendering icons <i> elements anyway, and you're not using any SVG-only features like Power Transforms, or Text, Layers, or Counters.

It just means that your rendred <i> elements will remain <i> elements in the DOM and not replaced by <svg> elements.

The Web Font technology does not replace the <i> elements, it matches their CSS classes with the appropriate glyph lookups in the associated web fonts loaded by the Font Awesome CSS.

<i> elements should work under both SVG and Web Font configurations

This point can be inferred from the previous two. If your Gutenberg code works by rendering <i> elements, it would be best to ensure that it works equally well when Font Awesome is configured either for SVG or Web Font.

Insisting on SVG technology

You could make it an error to run your code with Font Awesome technology as Web Font. If you know that your code absolutely must have the SVG with JavaScript technology to work properly, you could detect the presence of that feature and have your code respond accordingly.

In the WordPress server PHP code, you can call fa()->technology() and expect it to return "svg".

In the browser, the Font Awesome JavaScript API will be present on the global FontAwesome object only when SVG with JavaScript is loaded.

You should also register a preference for SVG in your font_awesome_preferences action hook:

add_action(
	'font_awesome_preferences',
	function() {
		fa()->register(
			array(
                'name'       => 'plugin foo',
                'technology' => 'svg'
			)
		);
	}
);

This approach comes at the cost of limiting compatibility, though. It either limits when your code can run, or it creates a potential mutual exclusion with other themes or plugins that work better with Web Font technology.

Generally, our goal is to maximize compatibility and thus minimize pain for the WordPress user.

Using the JavaScript API directly instead of <i> tags

If all.js is loaded, and it is when fa()->technology() === "svg" and fa()->using_kit() is false, then the IconDefinition objects for all icons in the installed version of Font Awesome may be looked up with findIconDefinition().

If fa()->pro() is also true then the fal style prefix will also be available. So the following would get the IconDefinition object for the coffee icon in the Light style.

const faLightCoffee = FontAwesome.findIconDefinition({ prefix: 'fal', iconName: 'coffee' })

The faLightCoffee object can then be used with icon(), for example, to get an html rendering of the icon as an <svg> element:

FontAwesome.icon(faLightCoffee).html

would produce something like:

[
  '<svg data-prefix="fal" data-icon="coffee" class="svg-inline--fa fa-coffee fa-w-18"  ...>...</svg>
]

This html could be stored directly as page content.

Or an abstract object could be generated that you could use to create your own DOM elements or store in the attributes of your Block:

FontAwesome.icon(faLightCoffee).abstract

would produce something like:

[
  {
    "tag": "svg",
    "attributes": {
      "aria-hidden": "true",
      "focusable": "false",
      "data-prefix": "fal",
      "data-icon": "coffee",
      "class": "svg-inline--fa fa-coffee fa-w-18",
      "role": "img",
      "xmlns": "http://www.w3.org/2000/svg",
      "viewBox": "0 0 512 512"
    },
    "children": [
      {
        "tag": "path",
        "attributes": {
          "fill": "currentColor",
          "d": "M517.9...64z"
        }
      }
    ]
  }
]

Using react-fontawesome

react-fontawesome is another alternative to <i> tags.

When you already have an IconDefinition object, it's easy:

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
// ...
const lightCoffeeComponent = <FontAwesomeIcon icon={ faLightCoffee } />

Font Awesome CSS Required

While icons may be pre-rendered as HTML or rendered as DOM objects using abstracts, as in the above examples, they still depend upon the Font Awesome CSS being inserted into the DOM separately.

This is done automatically when the SVG with JavaScript technology is loaded via CDN or Kit. However, there's currently no built-in way to ensure that the Font Awesome CSS is inserted when Font Awesome is configured for Web Font technology.

The workarounds risk compatibility problems with other clients, and one of the main goals of this package is to solve such compatibility problems.

Workaround 1: bundle the fontawesome-svg-core npm

npm install --save @fortawesome/fontawesome-svg-core
import { dom } from '@fortawesome/fontawesome-svg-core'

if ( !window.FontAwesome ) {
    dom.insertCss(dom.css())
}

If your bundler does tree-shaking, then this should result in a pretty slim addition to your bundle--mostly the CSS content itself.

This approach is also susceptible to problems caused by differences in Font Awesome versions between the version of that npm package and the version used for generating the abstract with its classes.

Workaround 2: fetch the CSS appropriate for the version

Get the Font Awesome version currently loaded: fa()->version().

Fetch the required CSS from the CDN, replacing the version number appropriately and set its contents as the text of a new <style> node, like this:

fetch('https://use.fontawesome.com/releases/v5.12.1/css/svg-with-js.css')
.then(response => response.ok ? response.text() : null)
.then(css => {
    if( css ) {
        const faCssStyle = document.createElement('STYLE')
        faCssStyle.appendChild(document.createTextNode(css))
        document.head.appendChild(faCssStyle)
    } else {
        // handle error
    }
})
.catch(error => {
    // handle error
})

You might also query the DOM first to make sure some other similar CSS hasn't already been added before adding this to the DOM yourself.

Detecting Configured Features

You may you want to use features like Power Transforms that are only available when SVG technology is configured, or icon styles like Duotone that are only available when Font Awesome Pro is configured, or some icons that are only available in newer releases of Font Awesome. You can detect those configurations using accessor methods on the FontAwesome instance from your PHP code.

The FortAwesome\fa function provides convenient access to the FontAwesome singleton instance. The following examples assume that you've done a use function FortAwesome\fa;

  • fa()->technology() (svg or webfont)
  • fa()->pro() (boolean)
  • fa()->pseudo_elements() (boolean)
  • fa()->v4_compatibility() (boolean)
  • fa()-version() ("latest" or something concrete like "5.12.0")

You can use these accessors when or after the font_awesome_enqueued action hook has been been triggered.

Refer to the PHP API documentation for details on these accessors and any others that be available.

What Gets Enqueued

What gets enqueued depends upon whether the WordPress site owner has configured Font Awesome to use the CDN or Kits. (A bit of a misnomer, since kits are loaded from CDN as well, just differently.)

Use CDN

A number of <script> or <link> resources are loaded, depending whether the site owner configures for SVG or Web Font technology, and enables version 4 compatibility.

  • main resource: all.js (SVG) or all.css (Web Font)
  • v4 compatibility shims : v4-shims.js (SVG) or v4-shims.css (Web Font) These shims are what version 4 icon classes to version 5 equivalents

Some additional inline resources may be added, depending on configuration:

  • an inline <script> is added to enable pseudo-element support when SVG technology is configured.
  • an inline <style> is added to enable additional v4 compatibility support: shimming the v4 font-family name

If conflict detection is enabled, an additional <script> is enqueued that loads the conflict detector from the CDN.

Use a Kit

When configured to use a kit, only the kit's loader <script> is enqueued. While the conflict scanner is enabled, an additional inline <script> is added to configure the conflict detector within the kit.

The kit loader script subsequently handles the insertion of various <script> or <link> elements, based on the kit's configuration, but that all happens outside of WordPress semantics. As far as WordPress is concerned, it's just a single wp_enqueue_script on the kit loader.

Loading Efficiency and Subsetting

Long-term Disk Cache

The URLs loaded from the Font Awesome CDN are specific to a given release, so their contents don't change, and therefore, they can be long-term cached in the browser.

For example, suppose Font Awesome is configured for Free Web Font, version 5.12.1, then this will be the main resource loaded:

https://use.fontawesome.com/releases/v5.12.1/css/all.css

It's loaded as 56KB over the network, but on subsequent loads, it does not hit the network but loads from the browser's disk cache.

(The CSS also causes the underlying webfont files to be loaded. The story is the same, subsequent loads will normally use the browser's disk cache and not use the network.)

All Icons vs Subset in WordPress

Given the large and growing number of icons availble in Font Awesome, it's natural to ask whether one might be able to load only the subset actually used.

In the WordPress ecosystem, though, it's common for site owners to install more than one theme or plugin that each uses Font Awesome icons, and tries to load its own version of Font Awesome. This causes conflicts across those various themes or plugins when activated on the same WordPress site.

A primary goal of this plugin package is to ease the pain for site owners to get those themes and plugins working with a single loaded version of Font Awesome that works for all concerned. And especially if it's a Font Awesome Pro user, they should be able to use Pro icons in their pages and posts, even while other installed plugins only use Free icons from version 4.

In that case where the site owner, their theme, and any number of installed plugins each use Font Awesome icons directly, it would be very difficult to determine what minimal subset could be created that would include all of the icons required by any of those clients.

Simply making all of them available for a given version of Font Awesome allows for every client to be satisfied.

Pro Kits Do Auto-Subsetting

Font Awesome Pro Kits (but not Free kits) have some built-in loading optimization that results in fewer resources being loaded, only as they are required by the browser.

Again, those resources will normally be long-term cached in the browser and loaded from the browser's disk cache on subsequent loads.

Pro SVG Kits are super-optimized. They auto-subset icon-by-icon. If a given web site only used one icon out of the 7,000+ in Font Awesome Pro, then only that one single icon would be fetched--except on subsequent loads when it would probably be pulled from disk cache.

How to Subset When You Know You Need To: Or, When Not To Use This Package

Suppose you're in a situation like this:

  • you are a developer
  • you're also the WordPress site owner
  • you control what themes or plugins are active on that site now and in the future
  • you are comfortable working directly in source code to manage which version and technology of Font Awesome is loaded
  • in the event that you do encounter an unexpected conflict, you are comfortable with investigating the WordPress resource queue and/or inspecting the browser DOM to identify and resolve the problem
  • the advantages of creating a subset are more important to you than the advantages of loading all.css or all.js from the Font Awesome CDN, or loading via Kit

In that case, then you might prefer to do a manual installation instead of using this plugin package.

You could either load exactly the resources you want from the Font Awesome CDN, or you could create your own subset of resources to load locally from your WordPress server or from your own CDN.

How to Make Pro Icons Available in Your Icon Chooser

Font Awesome's Pro icon licensing does not allow theme or plugin vendors to distribute Font Awesome Pro to their users. However, if your user has enabled Font Awesome Pro on their WordPress site, then you can provide whatever functionality you like to aid the user's use of those Pro icons.

Some ways you could accomplish this:

  1. In your marketing materials, make it clear that your product enables a design experience with a Font Awesome Pro installation provided by the user
  2. Using this package, register a preference for pro in your font_awesome_preferences action hook. This will remind the user in the Font Awesome settings UI that your product wants Pro to be enabled.
  3. Your code could detect that fa()->pro() is false and post an admin notice or other messaging in your own WordPress admin UI.

Once the site owner enables Pro, fa()->pro() will be true and your code can then rely on the presence of Font Awesome Pro for the version indicated by fa()->version().

(See the PHP API docs for how to resolve the symbolic "latest" version as a concrete version like "5.12.0".)

Query the Font Awesome GraphQL API

The Font Awesome GraphQL API allows you to query and search icon metadata.

See also documentation in PHP API on the FontAwesome::query() method.

public scope queries on api.fontawesome.com

When you only need to query public fields, you can issue queries directly against api.fontawesome.com.

You could paste this into your browser's JavaScript console right now and get a list of all icon names in the 5.12.0 release:

fetch(
  'https://api.fontawesome.com',
  {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: '{"query": "query Icons($ver: String!) { release(version:$ver) { icons { id } } }", "variables": { "ver": "6.x" } }'
  }
)
.then(response => response.ok ? response.json() : null)
.then(json => console.log(json))
.catch(e => console.error(e))

querying fields with non-public scopes

Queries that include field selections on fields requiring scopes more privileged than public require authorization with a Font Awesome account-holder's API Token.

There are some current and future Font Awesome features that require higher privileged scopes.

Currently, to query the kits on an account requires an API Token with the kits_read scope. Normally, a plugin or theme you develop probably wouldn't need that particular information, but it will serve as an example for how authorized queries can be issued through the API REST controller provided by this package.

The following examples assume that you're using the apiFetch() available on the global wp object in Gutenberg, or that you're using an apiFetch() that you've bundled and imported from @wordpress/api-fetch, and configured it with an appopriate REST root URL) and nonce.

If you open your browser to a window in Gutenberg, such as on a new post, you could copy and paste these samples into the JavaScript console as-is.

First, for comparison, here's the same all-public query like we issued above, but this time through the Font Awesome REST API endpoint:

wp.apiFetch( {
    path: '/font-awesome/v1/api',
    method: 'POST',
    body: 'query { release(version:"5.12.0") { icons { id } } }'
} ).then( res => {
    console.log( res );
} )

Now this query requires no extra authentication work on your part, yet it allows you to issue a query that is authorized by the WordPress site owner's API Token, if configured:

wp.apiFetch( {
    path: '/font-awesome/v1/api',
    method: 'POST',
    body: 'query { me { kits { token name } } }'
} ).then( res => {
    console.log( res );
} )

Examples

There are several clients in this GitHub repo that demonstrate how your code can use this package:

Component Description
integrations/themes/theme-alpha Theme accepts default requirements, but also conditionally uses Pro icons when available. It expects Font Awesome to be installed as a plugin by the site owner, rather than including it as a composer package.
integrations/plugins/plugin-beta Plugin requires version 4 compatibility, webfont technology, and a specific version. Uses some version 4 icon names. Assumes this package is already installed as a plugin.
integrations/plugins/plugin-sigma A plugin that requires this package via composer.

Contributing Development to this Package

See DEVELOPMENT.md for instructions on how you can set up a development environment to make contributions.

wordpress-fontawesome's People

Contributors

ej2 avatar frrrances avatar kemitchell avatar kramerc avatar masteradhoc avatar mlwilkerson avatar pavelthq avatar pross avatar robmadole avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wordpress-fontawesome's Issues

i tags should not contain protected space

This plugin writes a protected space " " for every icon used with shortcodes. The problem is, that the space take some place which is not needed. Especially when centering the icon, the icon never gets centered exactly because the space is also part of the i-Tag.
The icon

<div style="text-align: center">
  <i class="fas fa-7x fa-mouse-pointer">&nbsp;</i>
  <p>Here is a little text</p>
</div>

results in
image
while the icon

<div style="text-align: center">
  <i class="fas fa-7x fa-mouse-pointer"></i>
  <p>Here is a little text</p>
</div>

is displayed completely centered:
image

Is there a reason why the protected space is used in docs/files/includes/class-fontawesome.php.txt#L1838 and includes/class-fontawesome.php#L1838?

Set font-display rule to block to make Lighthouse happy

Hi!
It seems that the issue (FortAwesome/Font-Awesome#16077 that seem to be fixed in the mail repo) still persists when using Font Awesome Wordpress plugin (https://wordpress.org/plugins/font-awesome/). I am using that plugin (with the latest version of font - 5.15.2) and I get Leverage the font-display CSS feature... in the report from Lighthouse. This warning displays fonts from urls like https://use.fontawesome.com/releases/v5.15.2/webfonts/fa-** as affected.
I checked the code of that plugin and it seems like there is no font-display set. I did not find any issue tracking for that plugin so I decided to write here.
Is it possible to fix that? Thanks!

Add PUT verb requirement to documentation

In a few cases, users have reported that the plugin can't save changes. There are a range of root causes that have led to this, but they all have to do with unexpected server conditions which result in this plugin's browser code (the admin React app) from being able to communicate with the back end code via the WordPress REST API.

One of those reasons has been some web servers not configured to allow the PUT HTTP verb. I've seen this at least a couple of times on IIS servers, in particular.

This may result in a 405 Method Not Allowed error.

In the modern era of WordPress, with Gutenberg--the default editor--relying entirely on the REST API, it should be standard that web servers allow the PUT verb. The usage docs on wordpress.org indicate that POST should be used for creating new resources while PUT should be used for updating resources. That's standard for REST APIs, but the world may still be catching up with the increasing reliance of WordPress core, and plugins like ours, on the WordPress REST API and related server configuration requirements. So it makes sense that some web servers may not yet be allowing the PUT verb by default for WordPress installs.

Let's add a note to our docs about it.

Trying to use FA from plugin using JQuery accordion

I've created a plugin in wordpress that creates a jquery accordion.

It's working fine, however, now I'm trying to add icons using font-awesome, but I don't seem to be able to get the icons to show.

I've added the 'font-awesome' plugin and have verified that icons show up elsewhere simply by specifying the icon class in an empty element (i, div, span). So, I know it is there and working.

I'm instantiating the accordion like so:

let expanderWidgets = $('.article-sidebar-column .expander')
if (expanderWidgets.length > 0) {
  expanderWidgets.accordion({
    icons: {header: "fas fa-caret-right", activeHeader: "fas fa-caret-down"},
    collapsible: true, active: false, heightStyle: "content"
  })

In the inspector, I can see it inserts the 'fa*' classes in a span in the h3 header, so they are there, however their width is 0, so it doesn't look like the icons are getting loaded.

Is there some extra enqueue or other initialization I need to do in the plugin to get the fa icons to show?

(I'd rather use the fa icons than the jquery icons - don't want to load a jq ui theme and I don't want yet another font set in the wp install - it's bloated enough, already)

(I've posted this same question on stackoverflow ) with no response. Can answer there, if you'd rather.

Thanks,
rickb

Getting it to work.

Hey

I made this issue: Using Font Awesome with WordPress
FortAwesome/Font-Awesome#18819

I am working on updating older WordPress tutorials that use Font Awesome. At the moment the old code is not working, so that I am working on figuring out the correct approach these days.

SVG+JS runs in entire WP Admin (not just the Editor)

Hey @mlwilkerson ,

I have almost finished adjusting my theme to (optionally) use the SVG Kit (for max performance purposes) by refactoring my pseudo-elements icon instances.

However, I noticed that the SVG+JS runs in the entire WP Admin (not just the Editor) which then breaks other pseudo FA icon instances from other Plugins and custom admin pages.

I was wondering your thoughts to overcome this?

Note that I don't want to use SVG+JS and Pseudo-elements options, as performance is my goal here. Cheers!

No icon chooser in latest version

Hey @mlwilkerson

I just updated to latest 4.0.2 running latest WP 5.8 but I cannot see the Icon Chooser in editor on Page/Post.

I even switched to TwentyTwentyOne theme and still wasn't showing.

Any ideas?

Regards

Can not update settings

When I try to save the settings I get an error "Update failed". In the console log I get the following:

Failed to load resource: the server responded with a status of 405 ()
/wp-json/font-awesome/v1/config:1

Wich is odd since I am logged in with an admin.

Please advice

Feature Request: Allow disabling of Icon Chooser

From the support forum:

In the new version, as noted in this thread there’s now an Add Font Awesome button that shows up on the post edit screen.

Is it possible to remove this? I’m fine with using a filter but as far as I can tell there doesn’t seem to be one. I’ve noticed the should_icon_chooser_be_enabled method, but it says it’s not part of the plugin’s public API.

Feature Request: enable Icon Chooser in block-based widget editor

WordPress 5.8 introduced block editing to the widget editing interfaces.

Unfortunately, this plugin currently does not support it because that particular editing interface involves the possibility of legacy widgets that may rely on the ability to instantiate the classic Tiny MCE editor. This is specifically called out in that feature announcement:

Don’t use @wordpress/editor
Many legacy widgets call the wp.editor.initialize() JavaScript function to instantiate a TinyMCE editor. If a plugin or block uses the @wordpress/editor package and enqueues wp-editor as a script dependency, this will re-define the wp.editor global, often resulting in a wp.editor.initialize is undefined error.

But this was the same root cause of a problem we previously had with this plugin, when depending on wp-editor for block editor integration, and being loaded in a context where another plugin relies on the availability of that wp.editor.initialize global for instantiating TinyMCE. The RankMath plugin was the initial reported case in the support forum.

To make this feature work would require some further investigation as to whether it is even possible for us to add the Icon Chooser to that block editor's format bar within the widget editor without depending on @wordpress/editor.

How is anyone else accomplishing this?

Even if we find a solution, it seems likely that some other component will make this mistake. Seems like a foot gun that will be claiming a lot of toes.

Heads Up: Two Paths with Different Properties

As the feature announcement indicates, there are two different ways that this feature is encountered:

  1. Appearance → Widgets
    In initial exploration, this can be enabled by simply adding widgets.php to the list of screens for which the icon chooser should be enabled.

    protected $icon_chooser_screens = array( 'post.php', 'post-new.php' );

    This is because (if I recall, correctly), our is_gutenberg_page() returns true in this scenario. Thus it satisfies the constraint we put in previously: only enable the Icon Chooser with block editor integration when it's clearly a Gutenberg page.

    But this doesn't rule out the possibility of the error condition called about above. It will end up assigning to the wp.editor global, and thus possibly creating a problem for any legacy widgets that try to invoke the global wp.editor.initialize().

  2. Appearance → Customize → Widgets

    In initial exploration, even though the address bar looks like customize.php, there's also an iframe involved. So the current screen that is active when our code runs still ends up being widgets.php. However, is_gutenberg_page() is false in this context.

So making this work will require not just turning it on (because that's not too difficult), but finding a way to turn it on that doesn't break others.

See also:

Allow developers to select which user permissions are necessary to authenticate API calls

This is somewhat related to this closed issue.

I noticed that the Font Awesome plugin's REST API route (defined in class-fontawesome-api-controller.php) uses the following to authenticate calls to its API endpoint

return current_user_can( 'manage_options' ) || current_user_can( 'edit_posts' );

While this allows admins and post editor/authors to access the FA menu in Gutenberg when authoring site content, it has some unfortunate restrictions. To illustrate, here is my scenario:

A WordPress site I am working on has a number of custom content types (events, news stories, magazine issues) and corresponding custom user roles for each custom content type (so we have users who can only edit event posts, or only edit news story posts, e.g.). These custom content type specific authors are not admins, so none of them have the manage_options capability. Moreover, since each custom role is siloed off into editing just content of a specific type (i.e. not posts), they do not have the edit_posts capability either.

For cases like these, it would be useful to be able to specify additional capabilities that could authenticate API calls. As it stands, it looks like manage_options and edit_posts are hard-coded.

Is there a way to override this authentication logic? If not, do you think this would be a good feature to add?

Modifying currently active theme to add this package throws error and fails to initialize.

Version: 4.0.0-rc22

I am working on a theme purpose-built for a client site - the site does not have any other themes installed and we are not switching to the theme - rather, it's the default active on installation, and is the only theme installed, so it might never be deactivated. It currently cannot even be deactivated since no other themes are installed on the site.

When I add the code to the theme to register with FA as per the guide and the theme-mu example integration, I receive an error in the wp-admin panel:

The Font Awesome plugin caught a fatal error.

When trying to load Font Awesome, the plugin's configuration was invalid. Try deactivating, uninstalling, and re-activating the Font Awesome plugin.

This is the code I am including in my theme:

use FortAwesome\FontAwesome_Loader;
use function FortAwesome\fa;

[...excerpted...]

include_once __DIR__ . '/../../vendor/fortawesome/wordpress-fontawesome/index.php';

add_action('font_awesome_preferences', function () {
    fa()->register([
        'name' => '[theme name]',
    ]);
});
add_action('after_switch_theme', function () {
    FontAwesome_Loader::initialize();
});
add_action('switch_theme', function () {
    FontAwesome_Loader::maybe_deactivate();
    FontAwesome_Loader::maybe_uninstall();
});

I tried adding FontAwesome_Loader::initialize(); via add_action('init', ... but that still throws the same error.

Is there a way to get this to work in the active theme without having to install another theme so that it can be disabled/re-enabled? Having to switch away from the currently active theme is not currently something that would be simple to do, so I need to be able to use the FA package without doing that.

At the same time, we never know what the client may do in the future, so it will still need to work if one day in the future the theme is disabled/re-enabled - I don't want to break this functionality of course.

I am not dead-set on including the package as a dependency of the theme - we could use it as a normal wordpress plugin, except that we are controlling plugins via composer, and this package will not install correctly as a plugin using composer/installers because it does not have its type defined. But even then, I don't think this package is meant to be used this way, since configuring the package as a wordpress-plugin for composer/installers would probably break existing usage for many people. So I am not sure what I can do other than abandon use of this package and instead install FA via some other means.

Integration problem with theme

Hello,
I have some problems with the integration of wordpress-fontawesome, via composer, in my theme.
Once downloaded via composer, in the function.php file insert:

require_once __DIR__ . '/vendor/fortawesome/wordpress-fontawesome/index.php';

use function FortAwesome\fa;
register_activation_hook(__FILE__, 'FortAwesome\FontAwesome_Loader::initialize');

register_deactivation_hook(__FILE__, 'FortAwesome\FontAwesome_Loader::maybe_deactivate');

register_uninstall_hook(__FILE__, 'FortAwesome\FontAwesome_Loader::maybe_uninstall');

add_action(
'font_awesome_preferences',
function() {
fa()->register(
array(
'name' => 'test',
)
);
}
);

but unfortunately it doesn't load the menu item and I don't see any icon in the front end

I don't understand why. I'm not getting any errors.
If I try to activate the pligin-sigma, which as an integration is identical to my theme, this problem does not arise. I display the menu item on the back-end side, and my theme is shown in the list of "Other Theme or Plugin Preferences" and in the front-end I display the test icon of both the plugin and my theme.

Thanks for all

Confused Error: Whoops! You found a corner case

The error message being display as a wp admin notice is:

The Font Awesome plugin has experienced a fatal error : Whoops! You found a corner case here. Version 4 compatibility for our webfont method was not introduced until Font Awesome 5.1.0. Try using a newer version, disabling version 4 compatibility, or switch your method to SVG.

To reproduce:

  1. delete the font-awesome options key from the db using wp option delete font-awesome
  2. re-load the plugin's admin settings page

This is being thrown from FontAwesome_Release_Provider::get_resource_collection

Need to improve the error handling here.

Feature Request: WYSIWYG preview in TinyMCE visual pane

Cases to consider:

  1. when there is an [icon] shortcode
  2. when there is an <i> tag
  3. when the CSS defines pseudo-elements

The TinyMCE visual pane is rendered within its own <iframe>, which does not include Font Awesome.

To make this feature work would require:

  1. installing the currently configured Font Awesome that's active in the outer DOM into that TinyMCE visual preview <iframe>
  2. converting any [icon] shortcodes into the corresponding <i> tags (just for preview, not in the stored post content)

CAVEAT on pseudo-elements: pseudo-elements support is disabled by default for SVG/JS. That would need be additionally enabled within the Tiny MCE <iframe> when it's enabled in the outer DOM.

Re-enable Icon Chooser on WP4

In the process of fixing editor integration bugs for release 4.0.1, the Icon Chooser integration with the Classic Editor in WordPress 4 was disabled. This issue is to track re-enabling it.

Icons do not render in post excerpts

To reproduce:

  1. configure the plugin with default configuration (CDN, Free, Webfont)
  2. create a post with the block editor, using shortcodes for the icons (same result if <i> or <span> is used)
  3. add a few icons in blocks, small enough content such that the automated excerpt would include the region of content that has the icons
  4. use a theme that lists post excerpts on the home page, like the default Twenty Twenty-two theme in the standard WP 5.9.3 docker image
  5. publish and view that front page

Actual results:

image

Inspecting the DOM, we see:

<p class="wp-block-post-excerpt__excerpt">beer: star: android: </p>

Expected results: showing the icons

image

Use the plugin's icon picker modal elsewhere

Hi, I have a Pro License of FA, and was hoping to utilise the Icon Picker Modal on a custom admin editor metabox text field.

I've worked out how to call the icon picker on a custom button by using the same onclick event:
onclick="__FontAwesomeOfficialPlugin__openIconChooserModal()"
but I can't workout how to add the selected icon's value (shortcode or class) into my custom metabox text field.

Any ideas if this is possible with the WP Plugin?

Cheers!

PHPCs codestyle fails

Please ensure that your selected codestyle works. Now when I run
phpcs --standard=phpcs.xml.dist it shows a lot of errors

phpcs.txt

Add specific diagnostics for when the PUT method is disallowed

A common problem is when the user's browser tries to send a PUT request to the /api route and receives a 405 Method Not Allowed response. Some web servers are configured to disallow PUT but shouldn't be. We could provide more useful, specific information about that in the error message.

Make the top level admin menu item a sub item

The Font Awesome plugin adds a top level item to the WordPress admin menu. This menu gets cluttered easily, especially when one installs many plugins which all add top level items to it. I believe the need for such a top level menu item should therefore be carefully considered. Settings pages that need to be visited very frequently should be on the top level. Pages that are visited rarely should, IMHO, be sub pages.

Most of the time, I only visit the Font Awesome menu page once: after I activate the plugin. When everything is set up correctly, I never visit it again. That is why I think it should be a sub page of the 'Settings' page.

I am aware that this is a minor issue, but every time I install this plugin, it comes to my mind again, so I thought I'd start a discussion about it. I'd be happy to submit a PR.

Icon chooser in ACF not working

Hello,

Most of the issues seem to be fixed. But when I try to click on the Icon Chooser button within ACF WYSIWYG field nothing happens.
No console error or whatsoever.

The ACF WYSIWYG is inside a repeater field.

Hope you guys can figure this out.

Kind regards
Dennis

Use 'manage_options' as the permission check for /api route

Our ConfigController has a permissions check for:

current_user_can( 'manage_options' )

But the API Controller has:

current_user_can( 'edit_posts' )

We should use the same in both places, probably changing the latter to use manage_options

FEATURE: option to serve locally

From the WordPress support forum, there is a request to self-host Font Awesome Pro, rather than using the CDN.

This idea is currently moving in quite a different direction from our intent for the plugin, so it currently doesn't seem like a feature we'll be adding. But I'll leave it open for now to collect additional feedback that the community may have for us.

Pseudo-Elements Error

Just noticed that when you are on the Font Awesome Settings page, under the section labelled Technology, if you do the following:

  1. Select SVG
  2. Make sure "Enable CSS Pseudo-elements with SVG" is unticked
  3. Select Web Font (do all this without Saving Changes)
  4. Save Changes

It results in the following error being displayed:
Pseudo-elements cannot be disabled with webfont technology.

Annotation 2020-05-18 184046

Looks like your form validation isn't quite right. Everything appears to save fine though.

If you repeat what I mentioned above, but add an extra step, you don't see that validation error:

  1. Select SVG
  2. Make sure "Enable CSS Pseudo-elements with SVG" is unticked
  3. Save Changes <-- extra step
  4. Select Web Font
  5. Save Changes

FA WP plugin 4.1.0 with WP 5.9 crash on update

Upon install of 4.1.0, on a WP 5.9 site, the site blocked. Went in via recovery mode, deactivated and reactivated the plugin and it worked. Repeated and still had same problem. So now works, but only because I went in via recovery mode. Hope this helps.

Error in a third-party's library takes down the hole website

I installed this Font Awesome Official WordPress Plugin and keep getting this error that doesn't let me access neither the website nor the administration panel.
If I delete the plugin directory (/wp-content/plugins/font-awesome-official) then I can access again to both the website and the administration panel.
Sometimes it works, sometimes it doesn't. I don't know what is the cause.

image

Thanks in advance.

Font Awesome library is loaded for every admin page load

I only have the FA plugin installed in my site, and if you go into any admin page - for example the users page wp-admin/users.php, the FA library is loaded. Ideally, this should only be loaded when necessary.

Here's what I see in the page source:

<script defer="" crossorigin="anonymous" integrity="sha384-somestring" 
src="https://use.fontawesome.com/releases/v5.13.0/js/all.js" id="font-awesome-official-js"></script>

Functionality to get all available icons

I'm writing plugin right now. There will be icon picker where Website Admin can select Font Awesome icons for use.

This plugin already loads corresponding version of Font Awesome which meets clients' requirements (with pro icons option where Website Admin can enable it).

So, wouldn't it be great if there was a method to list all the available icons with plugin's current settings, whether svg or webfont method, free or pro icons? Similar to get_available_versions().

But this method must return full css classes such as far fa-address-card, fas fa-ad etc. Not just icon names but fas, far, fal, fad, fab indicating exact style.

Feature Request: Add "Insert Icon" button to TinyMCE editor (alongside Insert Media & others) for icon picker

I switched over from Better Font Awesome (https://wordpress.org/plugins/better-font-awesome/) and things are great (official, more up-to-date, more regular updates, etc.) However, I have people wanting a button added to the editor that allows for an icon picker to be used to insert an icon rather than needing to remember the shortcode, look up the specific icon name and/or prefix, etc. (which is something BFA has & I mention just as a reference.)

It seems like one could implement https://github.com/itsjavi/fontawesome-iconpicker (or equivalent) without too much trouble to make things much more usable for everyone (just want to pick & insert an icon right then & there... especially for those less savvy.) Also, it could be done in a way where it's specifically from the same library used by the plugin, and maybe even making sure the specific icons available on the site are what's offered by the picker (per it allowing the icons to be listed when initializing the picker for fontawesome-iconpicker, at least.)

For reference (and not saying it could be a direct copy of BFA), but it seems like the fontawesome-iconpicker library could be included on the site admin where TinyMCE might be present, https://github.com/MickeyKay/better-font-awesome-library/blob/master/better-font-awesome-library.php shows how the button could be added, https://github.com/MickeyKay/better-font-awesome-library/blob/master/js/admin.js shows how the button could trigger the picker & insert into the editor when chosen, and https://github.com/MickeyKay/better-font-awesome-library/blob/master/css/admin-styles.css shows how the picker may be styled to work a bit better in the admin. Again, this is just one way this feature could be implemented.

It'd be great to see this added, because sites that used to have this provided with Better Font Awesome have people asking for it back and those that never had it have people asking how they add icons within their content (or just quietly not using Font Awesome's icons [instead, using lesser graphics, not using enough visuals overall, etc.])

I'd hate to have people request that we switch to BFA just for the icon picker when everything else is effectively a downgrade from what's being provided here.

Btw, I've also posted this at https://wordpress.org/support/topic/feature-request-add-insert-icon-button-to-tinymce-editor-for-icon-picker/, but I wanted to mention it here for visibility of different audiences looking in different places that might want to discuss/support this all the same.

Feature request: add option to include "defer" on any <script> tag added by the plugin

We've had some customers that run a performance auditing tool (similar to Lighthouse perhaps?) that reports the <script> tags that the plugin adds are "blocking". Now while this is technically true it doesn't paint the whole picture.

The script that loads a Kit is small and generally pretty fast. But it is blocking. Once it finishes loading the rest of the Font Awesome assets are loaded asynchronously and do not block anything.

I'm not sure if we need this in other areas or not. This would probably also be beneficial for using the Pro CDN.

Proposed solution: add an option to adddefer to the <script> tags.

Selectively register REST API

The main entry point for page loads invokes initialize_rest_api().

But most REST API endpoints are only valid for admin scenarios.

Can we just avoid registering these routes unless we're being loaded in admin mode?

One that we may need to still load would be the FontAwesome_Conflict_Detection_Controller, when fa()->detecting_conflicts() is true, because that's needed for the conflict scanner to report its results.

Fatal Exception when creating new network

WordPress multi-site mode allows not only for creating multiple sites within a network, but also creating multiple networks, each of which may have multiple sites.

When creating a new network, such as with the WP Multi-Network plugin, when the Font Awesome plugin is activated, a Fatal Exception is thrown:

Eek! We're missing the information we need to load the version of Font Awesome you have selected. Go to your Font Awesome plugin settings page, re-select a version, and save. If that doesn't work, try deactivating and then re-activating the plugin. If that doesn't work either, you might need to delete and re-install the plug-in.

Reported in plugin support form here.

Provide a Recovery Mode

Recent issues in the support forum indicate scenarios where upgrading, downgrading, and fallback among multiple installations of the plugin--sometimes by various themes or plugins shipping it as a library--results in a ConfigCorruptionException fatal error. The user sees something like:

When trying to load Font Awesome, the plugin's configuration was invalid. Try deactivating, uninstalling, and re-activating the Font Awesome plugin.

The plugin's Loader is designed to accommodate the possibility of multiple simultaneous instances of this plugin being present on a site. It simply elects the newest version available.

When any version of the plugin runs, it looks to see if upgrade logic needs to run, to update the configuration schema in the database.

If a newer version does update the configuration schema in the database, it may render the configuration schema incompatible with one of the earlier versions of the plugin. This is fine as long as that newer version is the one that continues to run.

But if that newer version were removed for any reason--say a theme using a newer version of this plugin is uninstalled--then if some other plugin continues to depend on the Font Awesome plugin, the uninstallation of that theme will not result in the clean up of the Font Awesome configuration in the database. This is by design, so as not to "pull the rug" out from any other clients that continue to depend on the presence of the plugin.

However, the trouble case here is: when falling back to an earlier version of the plugin that is not compatible with the newer configuration schema, you would get a ConfigCorruptionException.

It may not be easy to discern which themes or plugins are involved (see support forum topics here and here).

What might be useful here is a utility for just resetting the configuration for whatever version of the plugin is currently running.

An alternative would seem to be: install a newer version of the plugin and allow it to run its normally automatic upgrade logic to put the configuration into a valid state.

Optimization: avoid autoloading all release metadata on every page load

See my comments on this support forum topic.

Currently, the release provider metadata is stored in the non-expiring transient named after FontAwesome_Release_Provider::RELEASES_TRANSIENT. This is to avoid making a network request for the release metadata on each page load. However, it's not necessary to load all of this metadata on each page. Once a particular release is made active, it would suffice for only that one release's metadata to be loaded on each page load.

So one approach could be to store the currently active release metadata separately for normal page loads. The full release metadata could be loaded only when loading the admin settings page.

All of this may change, depending on how this plugin enables kits in the future. That is because the releases metadata in question is largely required for loading Font Awesome from the non-kits CDNs. If when adding kits support we decide to drop non-kits CDN support, this releases metadata may become obsolete altogether.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.