Coder Social home page Coder Social logo

radiate-framework / framework Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 0.0 517 KB

A WordPress plugin and theme framework

Home Page: https://radiate-framework.github.io/

License: MIT License

PHP 99.21% CSS 0.79%
wordpress theme plugin framework radiate radiate-framework wordpress-plugin wordpress-theme theme-framework plugin-framework

framework's Introduction

framework's People

Contributors

benrutlandweb avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

framework's Issues

Gate/Policy

Is your feature request related to a problem? Please describe.
Determining if a user has capabilities involves using the WordPress user_can method.

Describe the solution you'd like
A Gate or Policy implementation like Laravel to create and check user capabilities.

Describe alternatives you've considered
user_can, current_user_can

Additional context
https://wordpress.stackexchange.com/questions/345902/want-to-know-parameters-that-can-be-passed-to-user-can-for-access-control-by-u on mapping new capabilities

Cache improvements

Is your feature request related to a problem? Please describe.
Getting multiple values from the cache involves lots of copy pasta.

Describe the solution you'd like
Methods to get/set multiple cache values Cache::many() etc.

Describe alternatives you've considered
Loops are a bit ugly.

Additional context
Laravel has (poorly documented) multiple methods to handle many cache keys. many, putMany

The ability to add a prefix to cache keys would also be cool:

Cache::prefix('users')->putMany([
  'ben'   => User::find(1), // users.ben
  'jerry' => User::find(2), // users.jerry
]);

$ben = Cache::get('users.ben');
$jerry = Cache::prefix('users')->get('jerry');

Option set/delete multiple

Is your feature request related to a problem? Please describe.
When activating/deactivating a plugin, it would be great to set/delete multiple global options.

Describe the solution you'd like
Additional methods on the Option facade to add and delete (and maybe get?) options.

Option::addMany([
  'option_1' => 1,
  'option_2' => 2,
]);

Option::deleteMany(['option_1', 'option_2']);

[$option_1, $option_2] = Option::getMany(['option_1', 'option_2']);

Describe alternatives you've considered
Manually looping over options.

Additional Facades

Is your feature request related to a problem? Please describe.
I can't statically call the request object

Describe the solution you'd like
Additional facades for Request and any other bindings in the container

Additional context
Currently App, Arr, Event, Route, Str, View... Can add Auth, File, Request as these exist within the current framework

Console run other commands

Is your feature request related to a problem? Please describe.
I can't call other commands from a command

Describe the solution you'd like
I'd like a way to call other commands so I do things like generate a bunch of countrollers in one go

Describe alternatives you've considered
Manually calling each command

Additional context
WP_CLI::runcommand() will allow this - a nice way to pass along arguments and handle errors will be needed.

Event dispatch requires second parameter

Describe the bug
The event dispatch method requires a second parameter to be passed.

To Reproduce
Steps to reproduce the behavior:

  1. Attempt to dispatch an event without a second parameter
  2. See error

Expected behavior
The event to dispatch regardless of the presence of the second variable

Screenshots

Event::dispatch('wp_loaded');

Additional context
Unlike do_action, apply_filters requires this to be set. Setting the second value to null is a workaround.

Pass existing WP_User to Auth::login()

Is your feature request related to a problem? Please describe.
Auth login only accepts credentials

Describe the solution you'd like
The ability to login a user by the WP_User instance

Describe alternatives you've considered
extracting the credentials from the user but the password is already hashed so not possible

Additional context

<?php

use Radiate\Support\Facades\Auth;
use WP_User as User;

Auth::login(new User(1));

Model has __create method

Describe the bug
The model has a __create method. This looks to be a legacy/mistake method.

Additional context
The create method is present on the query builder so it shouldn't be required on the model.

Shortcodes

Describe the solution you'd like
Generate shortcodes make:shortcode

DI Container

Is your feature request related to a problem? Please describe.
Restricted to what parameters are passed to controllers

Describe the solution you'd like
Add dependency injection to container

Additional context
Illuminate\Container is light on dependencies and should swap in quite easily

Pagination

Is your feature request related to a problem? Please describe.
The WordPress pagination is limited and tricky to use consistently.

Describe the solution you'd like
A Laravel-esque paginator with useful methods and iterable for simple looping in a template file.

Describe alternatives you've considered
Using the WordPress pagination or manually outputting the pagination links.

Additional context
https://laravel.com/docs/8.x/pagination#introduction

JsonResource toArray doesn't have Request passed through

Describe the bug
When running make:resource command, the stub generated has the Request object passed as the only method parameter. In reality, the JsonResource doesn't actually get the request passed, so the method signature doesn't match the parent class.

To Reproduce
Steps to reproduce the behavior:

  1. run wp radiate make:resource TestResource
  2. inspect the newly created resource
  3. attempt to dump the $request parameter

Expected behavior
The dumped $request parameter to output a Radiate\Http\Request instance

Additional context
The JsonResource::toArray method doesn't get passed the Request. It should in order to replicate the same functionality of Laravel, or the stub shouldn't include the parameter if the resource is deemed to not require it.

IMO the resource should get an instance of the request, or even have all dependencies resolved from the container. This would give great flexibility when building the resource.

API Resources

Is your feature request related to a problem? Please describe.
Creating a REST route to return posts - the posts are returned as WP_Post instances, which when encoded as JSON are ugly and full of superfluous data, increasing the response size.

Describe the solution you'd like
It would be nice to have a transformer like laravel's JsonResource class to easily convert WP_Query results into a tidy API response. It would also be simple to create API resources with the cli make:resource. The resource class would have attribute accessors so you can write $post->title instead of $post->post_title. This would open up scope to apply filters to API responses in an OOP manner.

Define a resource:

class PostResource extends JsonResource
{
    public function toArray()
    {
        return [
            'id'          => $this->ID,
            'title'       => $this->title,
            'description' => $this->content,
            'slug'        => $this->slug,
            'created_at'  => $this->created_at,
            'updated_at'  => $this->updated_at,
        ];
    }
}

This would be used in a controller like so:

public function index()
{
  $query = WP_Query(['post_type' => 'post']);

  return PostResource::collection($query->posts);
}

This would also be usable in a non-api context, pretty much wherever WP_Query might be used.

Describe alternatives you've considered
Manually looping through WP_Query responses and passing them into a class. This pattern is highly repeatable and would be better suited in the framework to simplify dev.

Additional context
Until the framework has Eloquent or a similar, nice API for querying the database, specifically the posts table, using WP_Query is the most efficient way to retrieve data. Currently there is no way to change the underlying class used (WP_Post) meaning accessing properties is ugly, and processing for an API response a hefty manual task.

Change Cpt namespace to PostType

Is your feature request related to a problem? Please describe.
Cpt is too abstract

Describe the solution you'd like
PostType is more declarative so easier for beginners to understand the link between wp and radiate

Describe alternatives you've considered
CustomPostType is too verbose, Type too generic

Additional context
Should taxonomies be in the post type directory?

Perhaps
.

  • WordPress
    +- PostTypes
    +- Taxonomies
    ..etc

Meta save/update/delete methods

Is your feature request related to a problem? Please describe.
The HasMeta trait allows for the object meta to be fetched. Nice enough. But it would be cool if you could update/delete the meta data too.

Describe the solution you'd like
A method or getter/setter to update and delete the meta data attached to the particular post. E.g.

// new method to update multiple attributes
User::find(1)->meta->update([
  'first_name' => 'changed',
]);

$meta = User::find(1)->meta;
$meta->first_name = 'changed'; // this already works, but doesn't persist in the db
$meta->save(); // new method to persist the entire Meta object

// new method to delete a single property
Post::find(1)->meta->delete('meta_description');

Describe alternatives you've considered
Using update_metadata and delete_metadata

Additional context
The Meta model already exists, additional methods would need to be added to use update_metadata and delete_metadata under the hood.

Named routes

Is your feature request related to a problem? Please describe.
There's no easy way to reference API routes other than their URL which may not be simple to remember.

Describe the solution you'd like
Named routes and the ability to get the URL with the name.

Route::get('posts/{id}/categories', CategoryController::class)->name('post.categories');

echo route('post.categories', ['id' => 1234]); // https://example.com/wp-json/api/posts/1234/categories

Describe alternatives you've considered
Trying to remember API routes, and having to interpolate/concatenate URL parameters. hard-coding endpoints.

Additional context
Routes are stored in the Router, it should be possible to assign names to each route, and then look these up from the router. There will also need to be a way to "build" a URL from the route and the given URL parameters.

Auth controller generators

Is your feature request related to a problem? Please describe.
generating/publishing multiple controllers for lost password, login, register etc takes time

Describe the solution you'd like
vendor:publish --tag=auth would speed this up

Describe alternatives you've considered
make:auth command but that isn't as descriptive of it's function and would re-implement vendor:publish

Additional context
It's a niche case to want generate as wp already has auth covered however, it would be nice for implementing custom login pages or an API signup

AuthManager return a User model

Is your feature request related to a problem? Please describe.
The AuthManager::user method only returns a WP_User. I want to return a custom class instead.

Describe the solution you'd like
Config to set the type of model returned by the AuthManager like how Laravel works.

Additional context
Laravel let's you choose what model to return from the auth facade so the framework should have the option as the WP_User model isn't great.

UrlGenerator

Is your feature request related to a problem? Please describe.
WordPress has many URL functions such as home_url, rest_url, wp_login_url.

Describe the solution you'd like
It would be nice to have these accessible from a facade: Url::login(). Bringing these functions under one class would make it easier to remember the functions. It could also be used in future to get named ajax and rest route URLs.

Describe alternatives you've considered
WordPress helper functions scattered through the code base

Additional context
Laravel has a Routing\UrlGenerator class and facade. The class methods would be simple wrappers around core WordPress functions.

<?php

namespace Radiate\Routing;

use Radiate\Http\Request;

class UrlGenerator
{
    /**
     * The request instance
     *
     * @var \Radiate\Http\Request
     */
    protected $request;

    /**
     * Assign the request object to the instance.
     *
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    /**
     * Get the current URL without query parameters.
     *
     * @return string
     */
    public function current(): string
    {
        return $this->request->url();
    }

    /**
     * Get the current URL including query parameters.
     *
     * @return string
     */
    public function full(): string
    {
        return $this->request->fullUrl();
    }

    /**
     * Get the URL for the previous request.
     *
     * @param string|null $fallback The fallback URL
     * @return string
     */
    public function previous(?string $fallback = null): string
    {
        if ($previous = wp_get_referer()) {
            return $previous;
        }

        if ($fallback) {
            return $fallback;
        }

        return $this->home();
    }

    /**
     * Return the registration URL
     *
     * @param string $redirect The Redirect URL
     * @return string
     */
    public function register(string $redirect = ''): string
    {
        if ($redirect) {
            return add_query_arg('redirect_to', urlencode($redirect), wp_registration_url());
        }

        return wp_registration_url();
    }

    /**
     * Return the login URL
     *
     * @param string $redirect The redirect URL
     * @return string
     */
    public function login(string $redirect = '/'): string
    {
        return wp_login_url($redirect);
    }

    /**
     * Return the logout URL
     *
     * @param string $redirect The redirect URL
     * @return string
     */
    public function logout(string $redirect = '/'): string
    {
        return wp_logout_url($redirect);
    }

    /**
     * Return the home URL
     *
     * @param string $path The path to append to the home URL
     * @return string
     */
    public function home(string $path = ''): string
    {
        return home_url($path);
    }

    /**
     * Return the URL to the path specified
     *
     * @param string $path The path to append to the home URL
     * @return string
     */
    public function to(string $path): string
    {
        return $this->home($path);
    }

    /**
     * Redirect to another page, with an optional status code
     *
     * @param string  $url    The URL to redirect to
     * @param integer $status The status code to send
     * @return void
     */
    public function redirect(string $url, int $status = 302): void
    {
        die(wp_redirect($url, $status));
    }

    /**
     * Return the admin URL
     *
     * @param string $path The path to append to the admin URL
     * @return string
     */
    public function admin(string $path = ''): string
    {
        return admin_url($path);
    }

    /**
     * Return the ajax URL
     *
     * @param string $action The ajax action
     * @return string
     */
    public function ajax(string $action = ''): string
    {
        return $this->admin('admin-ajax.php' . ($action ? '?action=' . $action : ''));
    }

    /**
     * Return the REST URL
     *
     * @param string $path The path to append to the admin URL
     * @return string
     */
    public function rest(string $path = ''): string
    {
        return rest_url($path);
    }

    /**
     * Determine if the given path is a valid URL.
     *
     * @param  string  $path
     * @return bool
     */
    public function isValidUrl(string $path): bool
    {
        if (!preg_match('~^(#|//|https?://|(mailto|tel|sms):)~', $path)) {
            return filter_var($path, FILTER_VALIDATE_URL) !== false;
        }

        return true;
    }
}

CRON Scheduler

Is your feature request related to a problem? Please describe.
The ability to simply create scheduled tasks.

Describe the solution you'd like
A CRON-like scheduler to wrap wp_schedule_event.

Describe alternatives you've considered
Native WP functions, custom CRON tasks

Additional context

Models

Describe the solution you'd like
Models such as a Post or User model that can be extended for CPTs and such. A Model class would provide an expressive interface for interacting with the WordPress tables rather than using the fragmented and inconsistent APIs provided by core.

For example:

// current way
$post = get_post(1);

echo $post->post_title; // title
echo get_permalink($post->ID); // permalink
echo get_the_post_thumbnail_url($post->ID, 'post-thumbnail'); // featured image

// new way
$post = new Post(1);

echo $post->title; // title
echo $post->permalink; // permalink
echo $post->featuredImage('post-thumbnail'); // featured image

WP_User, WP_Term, WP_Post could all be expanded on in some way to reduce the need for global helper functions. A better naming convention could also be utilized ($post->post_name doesn't adequately describe "slug" for instance). Following from Laravel's Model class, accessors, mutators, casts and more could be utilized for simple development.

Describe alternatives you've considered
Using the WP APIs has some cognitive load to remember the names of functions, the accepted parameters (WP functions quite often accept multiple types for one parameter), the error handling and other quirks such as using global $post or requiring an ID to be passed. It is possible (obviously) to use the core functions but a Model class would be nicer to write.

Additional context
Custom tables could also possibly also extend the Model class. It may be required to have a base class and then WP "models" extending this so the underlying model is table-agnostic.

A DB query builder would be able to return results with the correct models, simplifying queries, result manipulation etc. For the sake of keeping the feature request a manageable size, I suggest building out the Model first - WP_Query can be piped through a transformer to hydrate the models in order to use the underlying models, and the a query builder can be implemented at a later date.

Request/Response

Extend WP_REST_Request and WP_REST_Response to improve integration with WP core

Call to undefined method Radiate\Auth\RadiateUserProvider::newUserInstance()

Describe the bug
Calling Auth::attempt() results in aCall to undefined method Radiate\Auth\RadiateUserProvider::newUserInstance() error.

To Reproduce
Steps to reproduce the behavior:

  1. Call Auth::attempt() with some credentials.
  2. See error

Expected behavior
Either the attempt to return true for success, or false if the credentials are incorrect.

Additional context
The newUserInstance method doesn't exist either on the provider, or the model.

Implement Illuminate Contracts

Is your feature request related to a problem? Please describe.
The framework is heavily influenced by Laravel but doesn't use any Illuminate\Contracts

Describe the solution you'd like
Where implementations allow, use the available contracts. This will make it easier to extend/use custom services. An example would be using the UserProvider interface for the WordPress/RadiateUserProvider classes.

Describe alternatives you've considered
¯_(ツ)_/¯

Additional context
There are other components of the framework that could implement contracts to make them easily swappable.

Use dependency injection for controllers

Is your feature request related to a problem? Please describe.
Currently I can only access the $request and $id parameter from the controller methods.

Describe the solution you'd like
I'd like the controller methods to be resolved from the container so I can type hint my dependencies.

Describe alternatives you've considered
Getting dependencies from within the controller using the facades but it would be neater to inject automatically.

Additional context
REST uri params should be type hinted by their name e.g.

// require params
Route::get('/create-file', function(Filesystem $files) {
  //
});
// require params
Route::get('/user/{user_id}/create', function(int $user_id) {
  //
});
// and optional params
Route::get('/user/{name?}', function(string $name = 'no name') {
  //
});

Enhanced HTTP error exceptions

Is your feature request related to a problem? Please describe.
Currently, the framework only throws HTTPResponseException.

Describe the solution you'd like
It would be useful to throw Auth, PageNotFound, etc exceptions to cater for more use cases

Describe alternatives you've considered
Catching exceptions and checking the status codes

Additional context
Improvements to the exception handler would improve API responses

Request has no `url` method

Describe the bug
the Request class has no url method.

To Reproduce
Steps to reproduce the behavior:

  1. var_dump(Request::url());
  2. See error

Expected behavior
The Request class to return the current URL.

Additional context
Bug discovered from UrlGenerator::current() which calls the url method on the underlying Request class.

HTTP Client

Is your feature request related to a problem? Please describe.
Using wp_remote_request is clunky.

Describe the solution you'd like
A fluent way of making HTTP requests like Laravel's wrapper around Guzzle HTTP

Describe alternatives you've considered
Using wp_remote_request or cURL

Additional context
Laravel's HTTP client is a wrapper around Guzzle HTTP library.

Auth guards

Is your feature request related to a problem? Please describe.
I want to authenticate with a JWT instead of the normal auth login

Describe the solution you'd like
A way to switch guards such as session/token

Describe alternatives you've considered
Custom middleware

Additional context
See Laravel

Add privacy link and posts page link to UrlGenerator

Is your feature request related to a problem? Please describe.
It's not easy to remember the functions to get the privacy and blog page links.

Describe the solution you'd like
Methods added to the UrlGenerator class to make acessing these links simple. E.g. url()->privacyPolicy(), url()->postsPage().
There are other links that could be added, such as archives, tag, category pages.

Describe alternatives you've considered
Using the built in functions get_post_type_archive_link, get_privacy_policy_url.

Additional context
The built in functions are difficult to remember and not always consistent. Adding the "special" pages to the UrlGenerator class will solve these issues.

Event listeners not resolved from container

Describe the bug
Event listeners constructor method is not resolved from the container.

To Reproduce
Steps to reproduce the behavior:

  1. Type hint a dependency in a listener constructor
  2. Refresh the page
  3. See error

Expected behavior
Dependencies to be resolved from the container.

Option facade

Is your feature request related to a problem? Please describe.
Using get_option and related functions is inconsistent with the Radiate framework.

Describe the solution you'd like
A facade for the wp_options table to give a consistent API for accessing.

Describe alternatives you've considered
Using the native functions.

Additional context

<?php

use Radiate\Support\Facades\Option;

$value = Option::get('key', 'default');

Option::set('value', 'updated_value');

if (Option::has('value')) {
  //
}

Option::delete('value');

Encrypter

Is your feature request related to a problem? Please describe.
WordPress doesn't have a build in encrypt/decrypt function. This seems like a useful thing to have for application development.

Describe the solution you'd like
A facade like Laravel to encrypt/decrypt data: https://laravel.com/docs/8.x/encryption

Describe alternatives you've considered
custom implementation but this can lead to inconsistencies.

Additional context
Laravel uses openssl_encrypt/decrypt. A secure key will also be needed. Could use one of the WordPress keys defined in wp-config.php:https://api.wordpress.org/secret-key/1.1/salt/ or create a custom key. a CLI command would be nice

wp radiate key:generate

Signed and temporary signed routes

Describe the solution you'd like
Laravel provides a simple way to generate and validate signed routes. The Url::signedRoute() method and Url::hasValidSignature() method make it simple to have signed routes. There are also temporary signed routes.

This would make securing URLs simpler,

Describe alternatives you've considered
Manually adding the URL signature, but this will lead to inconsistencies in implementations.

Additional context
https://laravel.com/docs/8.x/urls#signed-urls

HTTP Client Pool method

Is your feature request related to a problem? Please describe.
There is no easy way to make concurrent HTTP requests.

Describe the solution you'd like
A Http::pool() method as in Laravel which returns concurrent HTTP requests.

Describe alternatives you've considered
Requests::request_multiple(): https://developer.wordpress.org/reference/classes/requests/request_multiple/

Additional context
Laravel's pool method: https://laravel.com/docs/8.x/http-client#concurrent-requests

JsonResource toArray return type is restrictive

Describe the bug
Nested JsonResource's collection should be able to return any JSONable type, not just an array.

To Reproduce
Steps to reproduce the behavior:

  1. Make a new resource with a nested resource
  2. return a string. E.g.
// recipe resource
public function toArray()
{
    return [
        'ingredients' => IngredientResource::collection($this->ingredients),
    ];
}

// ingredient resource
public function toArray()
{
    return $this->name;
}
  1. This will cast the name to an array so the result is:
{
  "ingredients": [
    ["eggs"],
    ["milk"]
  ]
}

Expected behavior
The toArray method to return any JSONable type, string, int, bool, object, array E.g.

{
  "ingredients": [
    "eggs",
    "milk"
  ]
}

Additional context
The toArray method name implies the return will be an array but this seems restrictive in instances where the collection should return a simple array of strings.

Response object

Is your feature request related to a problem? Please describe.
Currently the REST/AJAX APIs only return raw data. REST responses are converted to JSON automatically.

Describe the solution you'd like
A consistent Response object to be able to return raw arrays and have them automatically converted into JSON etc.

Describe alternatives you've considered
Writing json_encode within the controllers

Additional context
Laravel returns a response object that automatically converts to JSON, HTML etc as required. Also a response helper method with the ability to add additional headers.

Cache

Is your feature request related to a problem? Please describe.
It would be nice to be able to cache things for a certain time.

Describe the solution you'd like
Like Laravel's implementation: https://laravel.com/docs/8.x/cache, a cache facade to get/set items in the cache.

Describe alternatives you've considered
Transients: https://developer.wordpress.org/apis/handbook/transients/ or Object cache: https://developer.wordpress.org/reference/classes/wp_object_cache/

Additional context
transients aren't deleted until the transient is called, so perhaps a wp_cron will need to be implemented to do this... Or just rely on the transient behaviour.

Extend illuminate collections and array

Is your feature request related to a problem? Please describe.
The illuminate package has few dependencies and will be better for supporting long term than radiate own collection class.

Describe the solution you'd like
Arr and collection classes to be replaced by illuminate package which is already present in framework as part of config

Describe alternatives you've considered
Improving collections and arr so full features can be carried. Ie. Arr::wrap

Additional context
Have Radiate\Support\Arr extend Illuminate\Support\Arr etc ... to prevent confusion when writing classes.

Model Traits

Is your feature request related to a problem? Please describe.
To get the post featured image requires adding boilerplate methods that could be used as a trait

Describe the solution you'd like
A trait for things such as the post featured image and author. HasFeaturedImage

Describe alternatives you've considered
Adding the methods to the base class

Additional context
Perhaps a trait for HasAuthor, HasFeaturedImage, HasAttachment etc.

Custom console commands

Is your feature request related to a problem? Please describe.
A user of the framework has no easy way to create their own commands

Describe the solution you'd like
The ability to create extra commands with the frameworks fluent builder

Describe alternatives you've considered
Writing custom commands with WP_CLI

Additional context
There will need to be a way of loading the commands on the fly or in a service provider. Laravel handles it with auto-discovery, possibly an option

Remove config directory

Is your feature request related to a problem? Please describe.
The config directory adds complexity despite the likelyhood of changes being slim.

Describe the solution you'd like
Remove the config directory. Required configurations can be made in the functions file with $app->config() like in lumen.

Additional context
Hard code the view and app configurations and remove the Auth driver for WordPress...

Migration scripts

Is your feature request related to a problem? Please describe.
It's not easy to create custom tables.

Describe the solution you'd like
A schema builder and migration commands.

Describe alternatives you've considered
Writing raw SQL queries.

Additional context
Laravel has migrations.

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.