Giter VIP home page Giter VIP logo

frappe_docs's Introduction

Frappe Docs

This GitHub repository is archived since we now use a different contribution pipeline.

You can directly contribute to the documentation through frappeframework.com. For new contribution guidelines, refer to frappeframework.com/contribute.

This is the repository for the Frappe Framework Documentation. Learn more about Frappe Framework on the official website and the GitHub repository.

This documentation is hosted on https://frappeframework.com/docs.

Local Setup

To create a local working copy of the documentation (primarily for purposes of contributing to the documentation):

  1. Install frappe-bench and setup a bench directory by following the Installation Steps.
  2. Start the server by running bench start.
  3. In a separate terminal window, create a new site by running bench new-site frappeframework.test.
  4. Run bench get-app frappe_docs.
  5. Run bench --site frappeframework.test install-app frappe_docs.
  6. Now open the URL http://frappeframework.test:8000/docs in your browser, you should see the Frappe Framework Documentation.

Contributing

  1. Go to the apps/frappe_docs directory of your installation and execute git pull --unshallow to ensure that you have the full git repository. Also fork the frappe/frappe_docs repository on GitHub.
  2. Check out a working branch in git (e.g. git checkout -b my_doc_update).
  3. Make your proposed changes to the documentation sources.
  4. Run your local version of the documentation server (e.g. bench start in your bench installation). Make sure that your changes appear the way you want them to.
  5. Commit your changes to your branch. Make sure to use a semantic commit message.
  6. Push your branch to your fork on Github, and issue a pull request.

License

MIT

frappe_docs's People

Contributors

abhishekbalam avatar adityahase avatar ankush avatar barredterra avatar chillaranand avatar clarkejj avatar deepeshgarg007 avatar fhenry avatar gavindsouza avatar hasnain2808 avatar kennethsequeira avatar nabinhait avatar nagariahussain avatar netchampfaris avatar nextchamp-saqib avatar pm-at avatar prssanna avatar revant avatar rmehta avatar sagarvora avatar sahil28297 avatar saurabh6790 avatar saxenabhishek avatar scdanieli avatar scmmishra avatar shariquerik avatar shridarpatil avatar surajshetty3416 avatar thunderbottom avatar turkertunali 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

Watchers

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

frappe_docs's Issues

Docs at frappeframework website return Uncaught Server Exception

Trying to see the docs for hooks and gets Uncaught Server Exception.

at url --> https://frappeframework.staging.frappe.cloud/docs/user/en/guides/basics/hooks

Traceback (most recent call last):
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/utils/jinja.py", line 84, in render_template
    return get_jenv().from_string(template).render(context)
  File "/home/frappe/benches/bench-version-13-f-16/env/lib/python3.6/site-packages/jinja2/environment.py", line 941, in from_string
    return cls.from_code(self, self.compile(source), globals, None)
  File "/home/frappe/benches/bench-version-13-f-16/env/lib/python3.6/site-packages/jinja2/environment.py", line 638, in compile
    self.handle_exception(source=source_hint)
  File "/home/frappe/benches/bench-version-13-f-16/env/lib/python3.6/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/home/frappe/benches/bench-version-13-f-16/env/lib/python3.6/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "<unknown>", line 357, in template
jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got ':'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/website/render.py", line 50, in render
    data = render_page_by_language(path)
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/website/render.py", line 177, in render_page_by_language
    return render_page(path)
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/website/render.py", line 193, in render_page
    return build(path)
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/website/render.py", line 200, in build
    return build_page(path)
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/website/render.py", line 218, in build_page
    html = frappe.render_template(context.source, context)
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/utils/jinja.py", line 86, in render_template
    throw(title="Jinja Template Error", msg="<pre>{template}</pre><pre>{tb}</pre>".format(template=template, tb=get_traceback()))
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/__init__.py", line 396, in throw
    msgprint(msg, raise_exception=exc, title=title, indicator='red', is_minimizable=is_minimizable)
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/__init__.py", line 375, in msgprint
    _raise_exception()
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/__init__.py", line 326, in _raise_exception
    raise raise_exception(msg)
frappe.exceptions.ValidationError: <pre>{% extends "templates/doc.html" %}
			{% block page_content %}<div class="from-markdown"><!-- add-breadcrumbs -->

<h1 id="hooks">Hooks</h1>

<!-- TODO: Add tables for quick reference -->

<p>Hooks are the duct tape of the Frappe system. Hooks allow you to "hook" in to
functionality and events of other parts of the Frappe system. Following are the
official hooks from Frappe.</p>

<h3 id="application-name-and-details">Application Name and Details</h3>

<ol>
<li><code>app_name</code> - slugified name with underscores e.g. "shopping_cart"</li>
<li><code>app_title</code> - full title name e.g. "Frappe"</li>
<li><code>app_publisher</code></li>
<li><code>app_description</code></li>
<li><code>app_version</code></li>
<li><code>app_icon</code> - font-awesome icon or image url</li>
<li><code>app_color</code> - hex colour background of the app icon</li>
</ol>

<h3 id="install-events">Install Events</h3>

<ol>
<li><code>before_install</code></li>
<li><code>after_install</code></li>
</ol>

<p>The above hooks are called before and after installation of the app they are in.
For example, <a href="/apps/erpnext">ERPNext</a>'s hooks contains a line,</p>

<pre><code>after_install = "erpnext.setup.install.after_install"
</code></pre>

<p>So, the function after_install is imported and called after ERPNext is installed.</p>

<p>Note, the <code>before_install</code> and <code>after_install</code> hooks are called with no arguments.</p>

<h3 id="boot-session">Boot Session</h3>

<p>After a successful login, the Frappe JS Client requests for a resource called
<code>bootinfo</code>. The <code>bootinfo</code> is available as a global in Javascript via
<code>frappe.boot</code>. By default, the <code>bootinfo</code> contains</p>

<ul>
<li>System defaults</li>
<li>Notification status</li>
<li>Permissions</li>
<li>List of icons on desktop</li>
<li>User settings</li>
<li>Language and timezone info</li>
</ul>

<p>If your app wants to modify bootinfo, it can declare a hook <code>boot_session</code>. The
value is assumed to be a dotted path to a function and is called with one
argument, bootinfo which it can modify and return.</p>

<p>Eg,</p>

<pre><code>boot_session = "erpnext.startup.boot.boot_session"
</code></pre>

<h3 id="notification-configurations">Notification configurations</h3>

<p>The notification configuration hook is expected to return a Python dictionary.</p>

<pre><code>{
    "for_doctype": {
        "Issue": {"status":"Open"},
        "Customer Issue": {"status":"Open"},
    },
    "for_module_doctypes": {
        "ToDo": "To Do",
        "Event": "Calendar",
        "Comment": "Messages"
    },
    "for_module": {
        "To Do": "frappe.core.notifications.get_things_todo",
        "Calendar": "frappe.core.notifications.get_todays_events",
        "Messages": "frappe.core.notifications.get_unread_messages"
    }
}
</code></pre>

<p>The above configuration has three parts,</p>

<ol>
<li><code>for_doctype</code> part of the above configuration marks any "Issue"
or "Customer Issue" as unread if its status is Open</li>
<li><code>for_module_doctypes</code> maps doctypes to module's unread count.</li>
<li><code>for_module</code> maps modules to functions to obtain its unread count. The
functions are called without any argument.</li>
</ol>

<h3 id="javascript-css-assets">Javascript / CSS Assets</h3>

<p>The following hooks allow you to bundle built assets to your app for serving.
There are two types of assets, app and web. The app assets are loaded in the
Desk and web assets are loaded in the website.</p>

<ol>
<li><code>app_include_js</code></li>
<li><code>app_include_css</code></li>
<li><code>web_include_js</code></li>
<li><code>web_include_css</code></li>
</ol>

<p>Eg,</p>

<pre><code>app_include_js = "assets/js/erpnext.min.js"
web_include_js = "assets/js/erpnext-web.min.js"
</code></pre>

<p>Note: to create an asset bundle (eg, assets/js/erpnext.min.js) the target file
should be in build.json of your app.</p>

<h3 id="customizing-web-forms">Customizing Web Forms</h3>

<blockquote>
  <p>Introduced in Version 13</p>
</blockquote>

<p>In order to modify the client-side validations and stylesheets for existing web forms for a given DocType in the system, you can use the following hooks:</p>

<ol>
<li><code>webform_include_js</code></li>
<li><code>webform_include_css</code></li>
</ol>

<p>Eg,</p>

<pre><code>webform_include_js = {
    "Issue": "public/js/issue.js",
    "Address": "public/js/address.js"
}
</code></pre>

<h3 id="configuring-reports">Configuring Reports</h3>

<p>In the report view, you can force filters as per doctype using <code>dump_report_map</code>
hook. The hook should be a dotted path to a Python function which will be called
without any arguments. Example of output of this function is below.</p>

<pre><code>"Warehouse": {
    "columns": ["name"],
    "conditions": ["docstatus < 2"],
    "order_by": "name"
}
</code></pre>

<p>Here, for a report with Warehouse doctype, would include only those records that
are not cancelled (docstatus < 2) and will be ordered by name.</p>

<h3 id="modifying-website-context">Modifying Website Context</h3>

<p>Context used in website pages can be modified by adding
a <code>update_website_context</code> hook. This hook should be a dotted path to a function
which will be called with a context (dictionary) argument.</p>

<h3 id="customizing-email-footer">Customizing Email footer</h3>

<p>By default, for every email, a footer with content, "Sent via Frappe" is sent.
You can customize this globally by adding a <code>mail_footer</code> hook. The hook should
be a dotted path to a variable.</p>

<h3 id="session-creation-hook">Session Creation Hook</h3>

<p>You can attach custom logic to the event of a successful login using
<code>on_session_creation</code> hook. The hook should be a dotted path to a Python
function that takes login_manager as an argument.</p>

<p>Eg,</p>

<pre><code>def on_session_creation(login_manager):
    """make feed"""
    if frappe.session['user'] != 'Guest':
        # log to timesheet
        pass
</code></pre>

<h3 id="website-clear-cache">Website Clear Cache</h3>

<p>If you cache values in your views, the <code>website_clear_cache</code> allows you to hook
methods that invalidate your caches when Frappe tries to clear cache for all
website related pages.</p>

<h3 id="document-hooks">Document hooks</h3>

<h4 id="permissions">Permissions</h4>

<h4 id="query-permissions">Query Permissions</h4>

<p>You can customize how permissions are resolved for a DocType by hooking custom
permission match conditions using the <code>permission_query_conditions</code> hook. This
match condition is expected to be fragment for a where clause in an sql query.
Structure for this hook is as follows.</p>

<pre><code>permission_query_conditions = {
    "{doctype}": "{dotted.path.to.function}",
}
</code></pre>

<p>The output of the function should be a string with a match condition.
Example of such a function,</p>

<pre><code>def get_permission_query_conditions():
    return "(tabevent.event_type='public' or tabevent.owner='{user}'".format(user=frappe.session.user)
</code></pre>

<p>The above function returns a fragment that permits an event to listed if it's
public or owned by the current user.</p>

<h4 id="document-permissions">Document permissions</h4>

<p>You can hook to <code>doc.has_permission</code> for any DocType and add special permission
checking logic using the <code>has_permission</code> hook. Structure for this hook is,</p>

<pre><code>has_permission = {
    "{doctype}": "{dotted.path.to.function}",
}
</code></pre>

<p>The function will be passed the concerned document as an argument. It should
True or a falsy value after running the required logic.</p>

<p>For Example,</p>

<pre><code>def has_permission(doc):
    if doc.event_type=="Public" or doc.owner==frappe.session.user:
        return True
</code></pre>

<p>The above function permits an event if it's public or owned by the current user.</p>

<h4 id="crud-events">CRUD Events</h4>

<p>You can hook to various CRUD events of any doctype, the syntax for such a hook
is as follows,</p>

<pre><code>doc_events = {
    "{doctype}": {
        "{event}": "{dotted.path.to.function}",
    }
}
</code></pre>

<p>To hook to events of all doctypes, you can use the follwing syntax also,</p>

<pre><code> doc_events = {
    "*": {
        "on_update": "{dotted.path.to.function}",
    }
 }
</code></pre>

<p>The hook function will be passed the doc in concern as the only argument.</p>

<h5 id="list-of-events">List of events</h5>

<ul>
<li><code>validate</code></li>
<li><code>before_save</code></li>
<li><code>autoname</code></li>
<li><code>before_insert</code></li>
<li><code>after_insert</code></li>
<li><code>before_submit</code></li>
<li><code>before_cancel</code></li>
<li><code>before_update_after_submit</code></li>
<li><code>on_update</code></li>
<li><code>on_submit</code></li>
<li><code>on_cancel</code></li>
<li><code>on_update_after_submit</code></li>
<li><code>on_change</code></li>
<li><code>on_trash</code></li>
<li><code>after_delete</code></li>
</ul>

<p>Eg,</p>

<pre><code>doc_events = {
    "Cab Request": {
        "after_insert": "topcab.schedule_cab",
    }
}
</code></pre>

<h3 id="scheduler-hooks">Scheduler Hooks</h3>

<p>Scheduler hooks are methods that are run periodically in background. Structure for such a hook is,</p>

<pre><code>scheduler_events = {
    "{event_name}": [
        "{dotted.path.to.function}"
    ],
}
</code></pre>

<h4 id="events">Events</h4>

<ul>
<li><code>daily</code></li>
<li><code>daily_long</code></li>
<li><code>weekly</code></li>
<li><code>weekly_long</code></li>
<li><code>monthly</code></li>
<li><code>monthly_long</code></li>
<li><code>hourly</code></li>
<li><code>all</code></li>
<li><code>cron</code></li>
</ul>

<p>The scheduler events require RQ and redis (or a supported and
configured broker) to be running. The events with suffix '_long' are for long
jobs. The <code>all</code> event is triggered everytime (as per the RQ interval).</p>

<p>Example,</p>

<pre><code>scheduler_events = {
    "daily": [
        "erpnext.accounts.doctype.sales_invoice.sales_invoice.manage_recurring_invoices"
    ],
    "daily_long": [
        "erpnext.setup.doctype.backup_manager.backup_manager.take_backups_daily"
    ],
    "cron": {
        "15 18 * * *": [
            "frappe.twofactor.delete_all_barcodes_for_users"
        ],
        "*/6 * * * *": [
            "frappe.utils.error.collect_error_snapshots"
        ],
        "annual": [
            "frappe.utils.error.collect_error_snapshots"
        ]
    }
}
</code></pre>

<p>The asterisk (*) operator specifies all possible values for a field. For example, an asterisk in the hour time field would be equivalent to every hour or an asterisk in the month field would be equivalent to every month.</p>

<h3 id="override-whitelisted-methods">Override Whitelisted Methods</h3>

<p>Override whitelisted Python functions (server-side functions that are available to the client-side) using the <code>override_whitelisted_methods</code> hook.</p>

<p>An overriden function will be triggered during the following events:</p>

<ul>
<li>direct API call</li>
<li>document mapping</li>
</ul>

<p>Example,</p>

<pre><code>override_whitelisted_methods = {{
    "{dotted.path.to.whitelisted.frappe.function}": "{dotted.path.to.whitelisted.custom.function}"
}}
</code></pre>

<h3 id="jinja-customization">Jinja Customization</h3>

<p>Fetch custom methods and filters that are to be available globally in jinja environment.</p>

<h4 id="options">Options</h4>

<ul>
<li><code>methods</code></li>
<li><code>filters</code></li>
</ul>

<p>Example,</p>

<pre><code>jenv = {
    "methods": [
        "method_name:dotted.path.to.method_definition"
    ],
    "filters": [
        "filter_name:dotted.path.to.filter_function"
    ]
}
</code></pre>

<h3 id="exempt-doctypes">Exempt Doctypes</h3>

<p>Exempt documents of a specific DocType from being automatically cancelled on the cancellation of any linked documents.</p>

<p>Example,</p>

<pre><code>auto_cancel_exempted_doctypes = ["Payment Entry"]
</code></pre>

<p>In the above example, if any document that is linked with Payment Entry is cancelled, the system will skip the auto-cancellation of the linked Payment Entry document.</p>
</div>{% endblock %}</pre><pre>Traceback (most recent call last):
  File "/home/frappe/benches/bench-version-13-f-16/apps/frappe/frappe/utils/jinja.py", line 84, in render_template
    return get_jenv().from_string(template).render(context)
  File "/home/frappe/benches/bench-version-13-f-16/env/lib/python3.6/site-packages/jinja2/environment.py", line 941, in from_string
    return cls.from_code(self, self.compile(source), globals, None)
  File "/home/frappe/benches/bench-version-13-f-16/env/lib/python3.6/site-packages/jinja2/environment.py", line 638, in compile
    self.handle_exception(source=source_hint)
  File "/home/frappe/benches/bench-version-13-f-16/env/lib/python3.6/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/home/frappe/benches/bench-version-13-f-16/env/lib/python3.6/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "<unknown>", line 357, in template
jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got ':'
</pre>

autoname Controller method, when is it called

There's reference for the controller hook autoname, but there's no explanation when is it actually called. Think is a very important part. Line in the Documentation

This is an optional method which is called only when it is defined in the controller. Use this method to customize how the name property of the document is set.

CSS for the deployed docs getting 404

In the midst of predicting new version docs based on old documentation and github issues your docs lost its stylesheet making things even worse. Your framework which is supposed to speed up development is slowing things down drastically. Please for god sake help us with good docs.!!!!!!!!!!!!

"bench backup" doesn't now about the arguments "--only", "-i" or "--include"

Description of the issue

The documentation says that "bench backup" knows about the arguments "--only", "-i" or "--include".
https://frappeframework.com/docs/user/en/bench/reference/backup

These are no commands/arguments from bench itself, but I think should be defined by frappe.

All 3 arguments are not recognised.

Context information (for bug reports)

Output of bench version

erpnext 12.21.0
frappe 12.18.1

Steps to reproduce the issue

  1. bench backup --only 'Address'

Observed result

Output: Error: no such option: --only

Expected result

Working backup with only the stated DocTypes.

Stacktrace / full error message

Usage: bench  backup [OPTIONS]
Try "bench  backup --help" for help.

Error: no such option: --only

Additional information

OS version / distribution: Ubuntu 18.04

Frappe install method: Easy Installer

VM instructions incorrect

The address of "Localhost:8080" or http://localhost:8000 is incorrect, and just times out.

Localhost is only accessible on the server; using "localhost" on the HOST machine will result in a timeout unless bench is installed locally. Localhost won't work on the VM without installing a web browser, and (wisely of course) the O/S is a minimal text only setup.

mDNS appears to be installed on the seeded VM, and the host name is ubuntu.

The nginx.config in the VM I downloaded today has a listen 80; statement, so from the HOST machine the correct URL would be:

"http://ubuntu"

    == John ==

Unable to install working version of frappe_docs

I am interested in contributing a section to the Frappe Framework docs on using the DocFields of a DocType to tailor the Form view: how to break it into sections, how to make the sections collapsible, what column breaks do, how to set up the grid view of a child table, what the columns field means/does, that sort of thing, as I found it initially somewhat confusing, there are many questions about columns in the discussion forum, and I don't see this type of information in the Frappe Framework docs.

So naturally, as with contributing to the ERPNext Documentation, per the page https://github.com/frappe/erpnext/wiki/How-To-Contribute-to-the-ERPNext-Documentation-(The-Lengthy-Version) , I wanted to install a working clone of the Frappe Framework documentation. So I created a new bench, and then in that bench I executed:

bench new-site mysub.mydomain.tld
bench get-app frappe_docs
bench get-app frappe_theme
bench --site mysub.mydomain.tld install frappe_docs
bench --site mysub.mydomain.tld install frappe_theme![Screenshot_2020-07-28_09-17-37](https://user-images.githubusercontent.com/3825429/88692676-34190600-d0b3-11ea-8936-734930ff767c.png)

bench start

But now when I navigate to http://mysub.mydoman.tld:8001 (not :8000 as there is a totally separate bench on the same machine already using :8000), I get a "Not Found" page pictured in the screen shot below, and the "Back to Home" button simply reproduces the same "Not Found" page.

How can I get my clone of frappe_docs working? I will be happy to put updated installation instructions into the README.md file in my PR as well, if I can get this working. Thank you for your help/advice.

Screenshot_2020-07-28_09-17-37

Please rename the primary/default branch to something more inclusive

I am filing this issue to request that this project abandon the old, typical name for the primary/default branch of the repository in favor of a more neutral name like "main" or "develop." This request is part of a general industry shift to using more inclusive language. I would file a pull request, but I am not sure that such a renaming can be done via pull request. Thanks very much for your consideration.

Ubuntu installation wasn't quite working

Running xubuntu 20.04, I had to do the following additional steps before proceeding with https://frappeframework.com/docs/user/en/installation#debian-ubuntu.

libssl1.0.0 is not part of the ubuntu repos after 18.04 anymore (https://askubuntu.com/a/1173621). It can be installed using

# https://packages.ubuntu.com/bionic/libssl1.0.0
wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl1.0/libssl1.0.0_1.0.2n-1ubuntu5.3_amd64.deb
sudo dpkg -i /home/tobias/Downloads/libssl1.0.0_1.0.2n-1ubuntu5.3_amd64.deb

And the installation of bench-repo didn't work because of "ERROR: launchpadlib 1.10.13 requires testresources, which is not installed", which can be solved by this

sudo apt install python3-testresources

Better documentation on the "Fetch From" doctype row option

When using a "select" type in DocType1 to pull in the name of another Doctype2.
image

We often want to collect other information from Doctype2 via the "Fetch From" feature.

image

The correct use of "Fetch From" is to use the "name" of the Doctype1 select field populated and not the name of the source Doctype
ie

  • stratigic_intent.period_version is wrong and will return no results
  • intent.period_version is correct and will work

This is not clear from the examples/documentation on the net. In many examples the DocType1 field name is the same as the docType2 doc name, this will always work but that's more good luck than knowledge.

"Edit this page" button

Hi,

there is no button/link on the website to contribute to the documentation, it's very hard to find this repository.

Relying on erpnext documentation?

If one is researching frappe first, before erpnext, it can be jarring when the frappe documentation links to erpnext documentation.

For example, on page https://frappeframework.com/docs/user/en/basics/doctypes/docfield the link Fieldtypes is to https://docs.erpnext.com/docs/user/manual/en/customize-erpnext/articles/field-types which suddenly talks about masters, Items, Sales Orders etc. which can be confusing at first.

I think it would be better to create a generic frappe documentation page about field types.

Security vulnerability disclosure

The documentation should include a page about Security vulnerability disclosure with an email address to privately disclose vulnerabilities.

Previous docs repo

Hi,

I had started working on the documentation months ago. Pleased to see it has improved considerably since then.
There were a number of issues I opened. This was the "master issue".

frappe/frappe_io#296

Could you take a look at it and tell me what you think?
David

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.