plank / laravel-metable Goto Github PK
View Code? Open in Web Editor NEWA package for handling arbitrary data in Laravel 5 applications
License: MIT License
A package for handling arbitrary data in Laravel 5 applications
License: MIT License
Hey,
is the possibility of using this package without pulling in the full laravel package an option for you?
It would be nice to be able to use the package when only using the illuminate/database because you just need eloquent. It currently fails trying to get the config() since there is no service provider loaded when outside of the laravel scope.
Or is there any workaround for this?
Would be nice to hear from you.
Marcus
I added a column team_id to the meta table, which I'm filling using an observer. That works fine.
But how can you add a global scope to add a filter on team_id on each getMeta() and getAllMetas() request, without changing the package code?
Hey,
there is a lack of use ($key)
in src/Metable.php on line 265, so because of it whereMetaIn fails. Would be great if some of the contributors will fix it.
And of course, thanks for so good package!
Regards,
Giorgi
I have a "Settings" form that will be used to update Meta details about a model.
If a field is left blank, rather than store a NULL value I would prefer to unset the Meta using $model->removeMeta($key)
so that later I can use the default value option.
It would be great if I could do $model->removeMeta($key)
on a model where the meta has not been set yet, without it throwing an error: Call to a member function delete() on null
from line 138 of Metable: $this->getMetaCollection()->pull($key)->delete();
I know I can first check if the Meta exists, but that adds a lot of extra database calls when looping over a long form.
I use multiple databases and I ran into an issue where it was looking for my meta table on the wrong database. I've had this happen to me before as I often use multiple databases in my projects, and the easy fix is usually to just prefix the database name (not the connection name, but the actual database name) in front of the table.
So in my Meta model
<?php
namespace MyApp\Api\Models\Data;
use Plank\Metable\Meta;
class ProfileMeta extends Meta
{
protected $connection = 'data';
protected $table = 'api_data.profile_meta';
public function __construct(array $attributes = [])
{
$this->setConnection('data');
parent::__construct($attributes);
}
}
I appended api_data.
in front of profile_meta
.
I've done this countless times for models and it usually fixes my JOINS
that way. In this case it also worked and it fixed all my JOIN
issues between two models on two different databases.
However, surprisingly it completely broke laravel-metable and I could not longer setMeta
When trying to setMeta
it would always result in my value / key
being lost and being set to null.
I was very puzzled by this was this happening.
After some debugging I narrowed it down to the makeMeta
method inside the Metable
trait.
Specifically due to the way you create the model, by passing the attributes to the constructor, when you've appended the database name in front of the table the setValueAttribute
method does not get called ??
I have no idea why.
But I found a fix that works.. I am overriding the makeMeta
method on my model that uses Metable
and I changed it
from
protected function makeMeta(string $key = '', $value = ''): Meta
{
$className = $this->getMetaClassName();
$meta = new $className([
'key' => $key,
'value' => $value,
]);
$meta->metable_type = $this->getMorphClass();
$meta->metable_id = $this->getKey();
return $meta;
}
to
protected function makeMeta(string $key = '', $value = ''): Meta
{
$className = $this->getMetaClassName();
$meta = new $className();
$meta->key = $key;
$meta->value = $value;
$meta->metable_type = $this->getMorphClass();
$meta->metable_id = $this->getKey();
return $meta;
}
And then setValueAttribute
gets called and my joins work and everything works.
I don't know if you understand why this is happening? Or if you would mind modifying your makeMeta
to the way I set it up?
Would love to know more.
Many thanks!
At least in my usecase, I use this tool to store attributes which only apply to a few users (otherwise, I'd just add it to the main table). I use this for an intranet app to store when users are out of office - it only ever applies to a small subset of users, and after it is set back, there's no reason to continue to store the value.
Many times, I find myself writing code like this:
// default = true
if(is_null($artist->artistactive)) {
$out['active'] = true;
} else {
$out['active'] = $artist->artistactive;
}
I'd love a way to specify default values in the model. This would be implemented in two parts:
This would reduce the code down to:
$out['active'] = $artist->artistactive;
This would also help catch more logical errors and be more DRY, as if an implied default state ever changes, it would involve changing all these checks.
Just a thought, I might even submit a PR myself if I have time.
I've been really scratching my head for well over an hour trying to figure this one out.. so I figured it might be best to ask because I'm at a loss.
I have a meta key that holds simple arrays of 1 to 4 strings.
Then I've isolated my query entirely, only applying a single condition. I want to count the number of models that have friendship
within their array... which is thousands of them
$interests = ['friendship'];
$profiles = Profile::whereMetaIn('interested_in', $interests)->get();
dd($profiles->count());
This returns 0
every time ?? What am I doing wrong? Must be brain farting heavily here...
Ideally I want to return models that contain either friendship
or relationship
, you get the idea.. one or the other but not necessarily both.
Would appreciate a hint! This looks dead simple yet somehow..
Thanks!
we have Serious problem in our project , it's related to your package what can we do ?
public function hasMeta(string $key): bool
{
return $this->getMetaCollection()->has($key);
}
error:
Call to a member function has() on null
So let me describe this a bit more, as the title says. In previous versions when I returned the collection of a meta collection, it would be as the following:
` "meta" => Illuminate\Database\Eloquent\Collection {#2723 ▼
#items: array:5[▼
"source" => Plank\Metable\Meta {#2989 ▶}
"chamberofcommerce" => Plank\Metable\Meta {#2990 ▶}
"sbi" => Plank\Metable\Meta {#3551 ▶}
"telephone" => Plank\Metable\Meta {#3552 ▶}
"website" => Plank\Metable\Meta {#2727 ▶}
]`
As you can see, the keys are strings which relate to the Meta field 'key'. Now as of version 4.0 (previously 1.1), it is returned as:
` "meta" => Illuminate\Database\Eloquent\Collection {#761 ▼
#items: array:28 [▼
0 => Plank\Metable\Meta {#764 ▶}
1 => Plank\Metable\Meta {#765 ▶}
2 => Plank\Metable\Meta {#766 ▶}
3 => Plank\Metable\Meta {#767 ▶}
4 => Plank\Metable\Meta {#768 ▶}
]`
The meta collection is eager loaded through the model;
protected $with = ['meta'];
Any solution for this problem without major changes to the code, in our current project we have alot of links to the key of items in the meta collection.
I am running mariadb 10.0.19 but according to the MySQL docs https://dev.mysql.com/doc/refman/5.7/en/blob.html a BLOB/TEXT column is not allowed to have a default value.
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1101 BLOB/TEXT column 'value' can't have a default value (SQL: create table `meta` (`id` int unsigned not null auto_increment primary key, `metable_type` varchar(255) not null, `metable_id` int unsigned not null, `type` varchar(255) not null default 'null', `key` varchar(255) not null, `value` longtext not null default '') default character set utf8 collate utf8_unicode_ci)
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1101 BLOB/TEXT column 'value' can't have a default value
What are the impacts of removing the default on the rest of the code? I propose removing it, while some platforms throw a warning others throw an error. As of this writing the mode mysql is running at determines if an error will be thrown (STRICT MODE throws an error).
Hello,
are there plans for supporting Laravel 9 LTS?
I'm writing an artisan command that will identify duplicates (metable_type
+ metable_id
+ key
) and delete all but the most recent one (the highest id
).
I have a few to deal with. This is only 10 of the 33 keys with duplicates... 😳
Do you want me to send you the command when I'm done? I'm thinking it may be useful to those that are upgrading to version 5, considering that they'll be deleting them by hand otherwise.
Hello and many, many thanks for this Package (especially the DataTypesHandlers approach)
I would like to make a question:
You already provide the mechanism for default meta values per key, however is there any suggestion or mechanism, in case we want to enforce/validate the proper type/Handler for each Meta key inside Metable Models?
I am working in a project and this need came out, as we want to enforce specific types for some metas (ideally through configuration)
Is it possible to softdelete (with a deleted_at) meta?
Previously I was doing something like this
$this->where('matching_preferences->age->min', '<=', $profile->getMeta('age', null));
$this->where('matching_preferences->age->max', '>=', $profile->getMeta('age', null));
But now that I've moved matching_preferences.age
to a meta field. I don't know how to perform my lookup anymore.
I tried the below but that doesn't work.
$this->whereMeta('matching_preferences.age->min', '<=', $profile->getMeta('age', null));
A sample content of matching_preferences.age
is
{"min":22,"max":44}
I guess I could create two meta rows, one for matching_preferences.age.min
and one for matching_preferences.age.max
but if it's possible to query json inside meta records I would prefer to do that.
Any help would be greatly appreciated! Thank you!
Is it possible to utilize meta for a relationship with another table? For example, I have a "products" table and metadata where the "key" is "mistake" and the value is "1". So, if I want to retrieve the meta "mistake", then based on the key with "1", I want to retrieve data from the "mistakes" table where mistakes.id=1. Something similar to what Laravel has for hasOne()... Thank you.
Greetings,
Thank you for your efforts on this plugin, particularly with the documentation and the 0 issues count :)
I've just discovered an issue with some single table inheritance functionality I am putting together. I am overriding the getMorphClass
function in my Category model. This model has the Metable trait on it.
This getMorphClass override works everywhere except for functions that use the joinMetaTable function on line 379.
private function joinMetaTable(Builder $q, string $key, $type = 'left'): string
{
...
// Join the meta table to the query
...
->where($alias . '.' . $relation->getMorphType(), '=', get_class($this)); // < 379
this should ideally read
private function joinMetaTable(Builder $q, string $key, $type = 'left'): string
{
...
// Join the meta table to the query
...
->where($alias . '.' . $relation->getMorphType(), '=', $this->getMorphClass());
This resolves the issue with that getMorphClass function being customised (including with morphMaps etc).
So i have a html checkbox with the value of true
like this:
<input name="is_activated" type="checkbox" value="true"">
then use syncMeta
method and the type column saved as string
, it also applied with the setMeta
method unless i have to cast it as boolean as:
foreach ($request->meta as $key => $value) {
if ($key == 'is_activated') {
$post->setMeta($key, (bool) $value);
}
}
So, is there a better way of doing this?
When we are dispatching a job to the queue, and the job class contains a Model that uses the Metable trait, it will throw the following error:
Error: Cannot unpack array with string keys in /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Collection.php:605
As the error makes clear, this is possible:
$relations = [
0 => ['value'],
1 => ['value']
];
array_intersect(...$relations)
But this is not:
$relations = [
'key' => ['value'],
'another_key' => ['value'
]];
array_intersect(...$relations)
And this is happening due to the override of setRelation()
:
/**
* {@inheritdoc}
*/
public function setRelation($relation, $value)
{
if ($relation == 'meta') {
// keep the meta relation indexed by key.
/** @var Collection $value */
$value = $value->keyBy('key');
}
return parent::setRelation($relation, $value);
}
Removing the keyBy()
index fixes it.
Hello,
I have issues with insert array meta - setManyMeta()
.
I have:
$inorder->setManyMeta([
'inorder_price' => $request->price,
'customer_order' => $request->customer_order,
]);
and alert is:
BadMethodCallException
Call to undefined method Plank\Metable\Meta::getAttributesForInsert()
Please, help me :)
Hi,
I know this could a another problem; but i think it is related to the recordcount in meta since we have 5.121.049 records in that table. The message from MySQL:
Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction (SQL: insert into my-table-meta (key, metable_id, metable_type, type, value) values (somekey, 181308, App\Models\Model, string, 2022-01-29 07:05:55),
on duplicate key update type = values(type), value = values(value)) at file /home/myproject/vendor/laravel/framework/src/Illuminate/Database/Connection.php at line 712
Any thoughts on this?
Hello,
How to update only one meta? Is it possible?
Thanks.
Hi, without further a do, please see use-case below:
Versions
Example
$model->setManyMeta($metas = [
'title' => 'Pen-Pineapple-Apple-Pen',
'keywords' => [
'Pen-Pineapple-Apple-Pen',
'Pen-Pineapple',
'Pineapple-Apple',
'Apple-Pen',
'Pineapple',
'Pen',
'Apple',
],
]);
Error (Collision)
ErrorException
Array to string conversion
at vendor/laravel/framework/src/Illuminate/Support/Str.php:560
556▕
557▕ $result = array_shift($segments);
558▕
559▕ foreach ($segments as $segment) {
➜ 560▕ $result .= (array_shift($replace) ?? $search).$segment;
561▕ }
562▕
563▕ return $result;
564▕ }
Error (Web-Tinker)
PHP Warning: Array to string conversion in
/home/dev/www/cleanmypco/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 603
Temporary Solution (foreach)
foreach ($metas as $key => $value) {
$model->setMeta($key, $value);
}
Cheers! Please fix.
I followed your advice on how to rename the table and tried it out. I grabbed your migration file and copied it to my migration folder and kept the exact same name. However that did not result in my migration superseding yours because of the way I arrange my migration files in a separate subfolder.
It would be very useful then if you could add a mechanism which has become popular in many other packages such as https://laravel.com/docs/8.x/telescope#migration-customization
Either that or simply a new configuration option.
Alternatively, if you could allow us to specify both the table name, and database connection, in the config file that would also do the trick. Although I do prefer having full control over the migration as I may decide to add some columns or add an index that you aren't using.
Many thanks
I am testing this package in tinker
. This is what I did to set a meta for user model
$user = User::first();
$user->setMeta('city','Dhaka');
PHP Error: Class 'App/Meta' not found in D:/drivi-blade/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php on line 656
This is top of my user model
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Plank\Metable\Metable;
class User extends Authenticatable
{
use Notifiable;
use Metable;
Hi there,
I am trying to get all the keys and values used across my products that use Metable.
I'm trying to use this for a search/filter.
What I would like would be
-Key 1
-- Value 1
-- Value 2
-Key 2
-- Value 3
-- etc
Is this even possible?
$all_meta = Meta::where('metable_type', Product::class)
->where('key', 'LIKE', $format . '_%')
->get()
->unique(function ($item) {
return $item['key'].$item['value'];
})
->each(function ($item, $key) {
return $item->pluck('value','key');
});
This is what I have currently but I am getting the following error:
Type error: Argument 1 passed to Plank\Metable\DataType\Registry::getHandlerForType()
must be of the type string, null given, called in
/home/vagrant/code/store/vendor/plank/laravel-metable/src/Meta.php on line 69
I figure I am doing something dumb but can't seem to seem to see it...
TIA!
Hi guys
I'm trying to update my Laravel to 8.x
but I have this issue
https://share.getcloudapp.com/L1uJ2PYW
Would it be helpful (and would you consider merging) if I added or
methods for each of the query methods? orWhereMeta()
, orWhereHasMeta()
, and so on. They would be helpful to avoid having to do fun things like this:
->where(fn ($query) => $query->whereMeta('hidden_from_admin', false)
->orWhere(fn ($query) => $query->whereDoesntHaveMeta('hidden_from_admin'))
)
AKA "where the hidden_from_admin
meta is false
or it doesn't exist"
This instead could be:
->where(fn ($query) => $query->whereMeta('hidden_from_admin', false)
->orWhereDoesntHaveMeta('hidden_from_admin')
)
Or this:
->where(fn ($query) => $query->whereMeta('source_order_id', $searchValue)
->orWhere(fn ($query) => $query->whereMeta('source_order_number', $searchValue))
)
AKA "where the source_order_id
or source_order_number
meta is $searchValue
"
This instead could be:
->where(fn ($query) => $query->whereMeta('source_order_id', $searchValue)
->orWhereMeta('source_order_number', $searchValue)
)
The or
methods will essentially just be orWhere()
wrappers around the base query methods (like I'm doing above).
Let me know what you think. Thanks!
When I run the migrations, I get this error:
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes (SQL: alter table meta
add unique meta_metable_type_metable_id_key_unique
(metable_type
, metable_id
, key
))
I have the latest laravel version and my wamp server is set-up as follow:
It's surprising to discover this on my database but after soft deleting a row, all the meta associated with it got deleted.
After checking the code, I found the issue is here:
laravel-metable/src/Metable.php
Lines 39 to 45 in 141feb8
As a suggestion, I suggest changing it to
public static function bootMetable()
{
// delete all attached meta on deletion
static::deleted(function (self $model) {
if (!method_exists($model, 'forceDelete') || $model->isForceDeleting()) {
$model->purgeMeta();
}
});
}
Hope to see this fixed soon.
I get an error when trying to fetch all meta belonging to an object:
Plank\Metable\DataType\Registry::getHandlerForType(): Argument #1 ($type) must be of type string, null given, called in /var/www/html/vendor/plank/laravel-metable/src/Meta.php on line 76
I have the full error stack here: https://flareapp.io/share/oPRq3OAm#F63
Running:
php: 8.1.11
laravel: 9.37.0
metable: 5.3.0
Hi! Should I be able to use a trait in the Meta model? I would like to audit changes:
http://www.laravel-auditing.com/docs/4.1/getting-audits
Thanks!
Hi I am using your package for a sort of webshop with a couple of products. The products have multiple meta values. Is there a easy way to create some sort of product meta filtering?
Something like this:
Width:
Height:
Example:
A doctor can have none or many specialties:
$doctor1->setMeta('specialities', 'general practitioner')
$doctor1->appendToMeta('specialities','obstetrician') // How to append ?
$doctor2->setMeta('specialities', 'pediatrician')
$doctor2->appendToMeta('specialities','obstetrician') // How to append ?
How to query for all 'obstetrician' if the meta key 'specialities' is an Array converted to a json in the database ?
As you can currently add an array of key/values as new meta, it would be just as handy to be able to remove an array of meta columns in one go.
I can put this in a PR if of interest.
Hi,
First of all thanks for the great package with great documentation. you guys did a great job 😄 ❤️.
I'm trying to install this package on my Laravel 9 project but I'm getting this error by the composer:
I'm using Laravel 9.24.0 & PHP 8.1.8. and I'm using the latest composer 2.
Seems like vlucas/phpdotenv
(used by Laravel) which uses graham-campbell/result-type
and this uses "phpoption/phpoption": "^1.9"
. but this package uses "phpoption/phpoption": "1.8.1"
I am trying to require it with composer command
composer require plank/laravel-metable
But, an error is shown like below
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for plank/laravel-metable ^1.1 -> satisfiable by plank/laravel-metable[1.1.0].
- Conclusion: remove laravel/framework v6.0.1
- Conclusion: don't install laravel/framework v6.0.1
How to use it in laravel 6 ?
Hi Guys, I just want to ask, if it's good practise to have just one and only table to storage all metas for every model. For example if I will have 80 000 users and 80 000 products and every single user / post will have at least 5 meta stored in the "meta" table then this table will have more then 800 000 rows and I am not sure how fast will be getting required data for the specific user or post.
Also, please could you give me advice, how can I change the name of the table? E.g. change the table name from "meta" to "users_meta" and I do not want to update anything inside the vendor folder
Thank you for your help.
Hi,
I'm having an issue with ordering results based on a meta key.
The code:
public function candidates()
{
// user filters
$filters = request('filters', []);
// user ordering
$orderBy = request('orderby', 'updated');
$order = request('order', 'desc');
// candidates per page
$paginate = request('paginate', 100);
// lazy load relations
$candidate = Candidate::with(
'aircraft_types',
'nationalities',
'instructor_qualifications',
'instructor_aircraft_types',
'licenses',
'positions',
'meta'
);
// apply filters
if($filters) {
$candidate = (new CandidateFilter($filters, $candidate))->build(); // pass through a filter
}
if($orderBy === 'rating') {
$candidate = $candidate->orderByMetaNumeric($orderBy, $order, true);
} else {
$candidate = $candidate->orderBy($orderBy, $order);
}
return $candidate->paginate($paginate);
}
The exception I get:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'App\Candidate' in 'on clause' (SQL: select count(*) as aggregate from `candidates` inner join `meta` as `meta__rating` on `candidates`.`id` = `meta__rating`.`metable_id` and `meta__rating`.`metable_type` = `App\Candidate` and `meta__rating`.`key` = `rating`)
Any thoughts on what might be wrong?
Is there any particular reason that the meta model doesn't have created/updated timestamps? They would be useful to have available at times.
I can certainly add them to my own model, of course. I'm just curious what your thoughts are about adding them to the core package.
Thanks!
Firstly thanks for this great package! It saves time and helps keep things clean.
I've tried to query collection but always get an empty result.
Or am I do something wrong?
Collection saved in DB:
{"class":"Illuminate\\Database\\Eloquent\\Collection","items":
[
{"class":"App\\Models\\Currency","key":"TRY"},
{"class":"App\\Models\\Currency","key":"USD"},
{"class":"App\\Models\\Currency","key":"EUR"},
{"class":"App\\Models\\Currency","key":"GBP"}
]
}
Queries I've tried:
User::whereMeta('currencies', 'USD')->get();
User::whereMetaIn('currencies', ['USD'])->get();
Any chance to make such queries work?
After running php artisan schema:dump --prune
I am unable to boot my application due to a check taking place to see if the migration exists. This is done on the boot method
For now I have had to create an empty migration file, but is there a correct way to work around this?
Thanks
Rn I am using another packaged and I think I will switch it due to lack of updates. But before this, I have a question. How to query based on multiple meta values?
Let me give an example. Let's say we have some orders with 3 meta values. name, phone and email. How to get the orders which, simultaneously, contains 'a' in name, '1' in phone and 'b' in email?
Currently having a Model with $defaultMetaValues with no meta, $model->getAllMeta() returns an empty collection. Wouldn't it be great to merge those $defaultMetaValues with collection when using $model->getAllMeta()?
I'm using metable to power a form builder of sorts where users can build custom forms by creating various fields and then placing / re-arranging them via a UI
In order for the fields to be ordered properly I added two new fields to the meta table and am now overriding two methods from the Metable class in order to make it work
These fields are optional of course but I'm not sure you would consider this as a useful PR so I thought I would ask first and share the code here in case someone else has a similar problem.
Also if you think I could have achieved this in another way I'd love to hear your feedback
$table->smallInteger('order')->default(0);
$table->string('category')->nullable();
/**
* Relationship to the `Meta` model.
*
* @return MorphMany
*/
public function meta(): MorphMany
{
return $this->morphMany($this->getMetaClassName(), 'metable')
->orderBy('category')
->orderBy('order');
}
/**
* Add or update the value of the `Meta` at a given key.
*
* @param string $key
* @param mixed $value
*/
public function setMeta(string $key, $value, $order = 0, $category = null): void
{
if ($this->hasMeta($key)) {
$meta = $this->getMetaRecord($key);
$meta->setAttribute('value', $value);
$meta->order = $order;
$meta->category = $category;
$meta->save();
} else {
$meta = $this->makeMeta($key, $value);
$meta->order = $order;
$meta->category = $category;
$this->meta()->save($meta);
$this->meta[] = $meta;
$this->indexedMetaCollection[$key] = $meta;
}
}
Hi, I would like to ask if you have a trait or maybe you want to integrate this as the package feature. As the title states, pseudo below:
class User extends Model
{
use Metable;
/**
* Specific inputs, and save as meta.
* or... if method exists: `protected function metaFields(): array`
*
* If a Meta field is not on a listed, should be left alone.
*
* @var array
*/
protected array $meta_fields = [
'firstname',
'lastname',
'age',
'sex',
'address',
];
}
User::create([
'email' => '[email protected]',
'firstname' => 'Joe',
'lastname' => 'Foo',
'address' => ['street' => '...', 'city' => ..., ...]
]);
App\Models\User {
attributes: [
...
'email' => '[email protected]',
],
...
};
Retrieval:
$user->address;
// array() [ 'street' => '...', ... ]
$user->lastname;
// Foo
Saving:
$user->email = '[email protected]';
$user->lastname = 'Bar';
$user->firstname = 'Foo';
// bulk meta save as: `setManyMeta`, which is called when `saving/updating` or `saved` model event is triggered
// (not sure what's best), I am sure DB::transaction still captures in case.
$user->save();
$user->toArray() => [
'id' => ...
'email' => '[email protected]',
'meta' => [
'firstname' => 'Foo',
'lastname' => 'Bar',
],
];
Please add support for Laravel 5.7
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.