├── .github └── ISSUE_TEMPLATE │ ├── ---bug-report.md │ ├── ---feature-request.md │ └── bug_report.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── Lemon-Banner.png ├── Lemon ├── Server │ ├── __init__.py │ ├── middleware.py │ └── server.py ├── __init__.py ├── components.py ├── conftest.py ├── create_lemon_app.py ├── orm │ ├── DBManager.py │ ├── __init__.py │ └── migrations.py └── ui │ ├── __init__.py │ ├── buttons.py │ └── forms.py ├── README.md ├── contributing.md ├── docs ├── .babelrc ├── .gitignore ├── README.md ├── babel.config.js ├── blog │ ├── 2022-09-29-First-Post.md │ ├── 2022-10-01-Version-1-0-0-Update.md │ ├── 2022-10-04-Version-1-2-1-Update.md │ ├── 2022-10-07-Version-1-3-0-Update.md │ └── authors.yml ├── docs │ ├── Hello-World.md │ ├── api-reference │ │ ├── Lemon-Server-middleware.md │ │ ├── Lemon-Server-server.md │ │ ├── Lemon-Server.md │ │ ├── Lemon-components.md │ │ ├── Lemon-orm-DBManager.md │ │ ├── Lemon-orm-migrations.md │ │ └── Lemon-orm.md │ ├── lemon-in-3min.md │ ├── lemon-vs-react.md │ ├── table.md │ └── tutorial │ │ ├── images │ │ └── blog-page.PNG │ │ ├── intro-to-tutorial.md │ │ ├── tutorial-part-1.md │ │ ├── tutorial-part-2.md │ │ ├── tutorial-part-3.md │ │ ├── tutorial-part-4.md │ │ └── tutorial-part-5.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src │ ├── components │ │ ├── HomePageComponents │ │ │ ├── index.js │ │ │ └── styles.module.css │ │ └── HomepageFeatures │ │ │ ├── index.js │ │ │ └── styles.module.css │ ├── css │ │ └── custom.css │ └── pages │ │ ├── index.js │ │ └── index.module.css ├── static │ ├── .nojekyll │ └── img │ │ └── favicon.png ├── versioned_docs │ ├── version-1.0.0 │ │ ├── Hello-World.md │ │ ├── lemon-in-3min.md │ │ ├── lemon-vs-react.md │ │ ├── table.md │ │ └── tutorial │ │ │ ├── images │ │ │ └── blog-page.PNG │ │ │ ├── intro-to-tutorial.md │ │ │ ├── tutorial-part-1.md │ │ │ ├── tutorial-part-2.md │ │ │ ├── tutorial-part-3.md │ │ │ ├── tutorial-part-4.md │ │ │ └── tutorial-part-5.md │ ├── version-1.3.0 │ │ ├── Hello-World.md │ │ ├── api-reference │ │ │ ├── Lemon-Server-middleware.md │ │ │ ├── Lemon-Server-server.md │ │ │ ├── Lemon-Server.md │ │ │ ├── Lemon-components.md │ │ │ ├── Lemon-orm-DBManager.md │ │ │ ├── Lemon-orm-migrations.md │ │ │ └── Lemon-orm.md │ │ ├── lemon-in-3min.md │ │ ├── lemon-vs-react.md │ │ ├── table.md │ │ └── tutorial │ │ │ ├── images │ │ │ └── blog-page.PNG │ │ │ ├── intro-to-tutorial.md │ │ │ ├── tutorial-part-1.md │ │ │ ├── tutorial-part-2.md │ │ │ ├── tutorial-part-3.md │ │ │ ├── tutorial-part-4.md │ │ │ └── tutorial-part-5.md │ ├── version-1.3.5 │ │ ├── Hello-World.md │ │ ├── api-reference │ │ │ ├── Lemon-Server-middleware.md │ │ │ ├── Lemon-Server-server.md │ │ │ ├── Lemon-Server.md │ │ │ ├── Lemon-components.md │ │ │ ├── Lemon-orm-DBManager.md │ │ │ ├── Lemon-orm-migrations.md │ │ │ └── Lemon-orm.md │ │ ├── lemon-in-3min.md │ │ ├── lemon-vs-react.md │ │ ├── table.md │ │ └── tutorial │ │ │ ├── images │ │ │ └── blog-page.PNG │ │ │ ├── intro-to-tutorial.md │ │ │ ├── tutorial-part-1.md │ │ │ ├── tutorial-part-2.md │ │ │ ├── tutorial-part-3.md │ │ │ ├── tutorial-part-4.md │ │ │ └── tutorial-part-5.md │ └── version-1.3.6 │ │ ├── Hello-World.md │ │ ├── api-reference │ │ ├── Lemon-Server-middleware.md │ │ ├── Lemon-Server-server.md │ │ ├── Lemon-Server.md │ │ ├── Lemon-components.md │ │ ├── Lemon-orm-DBManager.md │ │ ├── Lemon-orm-migrations.md │ │ └── Lemon-orm.md │ │ ├── lemon-in-3min.md │ │ ├── lemon-vs-react.md │ │ ├── table.md │ │ └── tutorial │ │ ├── images │ │ └── blog-page.PNG │ │ ├── intro-to-tutorial.md │ │ ├── tutorial-part-1.md │ │ ├── tutorial-part-2.md │ │ ├── tutorial-part-3.md │ │ ├── tutorial-part-4.md │ │ └── tutorial-part-5.md ├── versioned_sidebars │ ├── version-1.0.0-sidebars.json │ ├── version-1.3.0-sidebars.json │ ├── version-1.3.5-sidebars.json │ └── version-1.3.6-sidebars.json └── versions.json ├── examples ├── Custom-Route-Id.py ├── Hello-World.py ├── Lemon-App │ ├── README.md │ ├── Tests │ │ ├── __init__.py │ │ └── test.py │ ├── app.py │ ├── base.py │ ├── models │ │ ├── __init__.py │ │ └── model.py │ ├── public │ │ ├── css │ │ │ └── style.css │ │ └── js │ │ │ └── script.js │ ├── requirements.txt │ └── routes │ │ ├── __init__.py │ │ └── route.py ├── Tests.py ├── django-routing.py ├── exception-handler.py ├── middleware-example.py ├── props.py ├── reactivity-example │ ├── app.py │ └── public │ │ └── script.js └── ui-demo.py ├── requirements.txt ├── setup.cfg └── setup.py /.github/ISSUE_TEMPLATE/---bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41B Bug report" 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: Sas2k 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Code** 21 | code that makes the breaking behavior 22 | 23 | **Expected behavior** 24 | A clear and concise description of what you expected to happen. 25 | 26 | **Screenshots** 27 | If applicable, add screenshots to help explain your problem. 28 | 29 | **Desktop (please complete the following information):** 30 | - OS: [e.g. iOS] 31 | - Browser [e.g. chrome, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/---feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F34B Feature request" 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: enhancement 6 | assignees: Sas2k 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | sas8.communication@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 Sasen Perera 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | 9 | -------------------------------------------------------------------------------- /Lemon-Banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/Lemon-Banner.png -------------------------------------------------------------------------------- /Lemon/Server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/Lemon/Server/__init__.py -------------------------------------------------------------------------------- /Lemon/Server/middleware.py: -------------------------------------------------------------------------------- 1 | """ 2 | Lemon.Server: Middleware 3 | By Sasen Perera 2023 4 | """ 5 | from webob import Request, Response 6 | 7 | 8 | class Middleware: 9 | """Middleware Class""" 10 | 11 | def __init__(self, app): 12 | """Middleware Init""" 13 | self.app = app 14 | 15 | def add(self, middleware_cls): 16 | """Add Middleware""" 17 | self.app = middleware_cls(self.app) 18 | 19 | def process_request(self, req): 20 | """Process Request""" 21 | pass 22 | 23 | def process_response(self, req, resp): 24 | """Process Response""" 25 | pass 26 | 27 | def handle_request(self, request): 28 | """Handle Request""" 29 | self.process_request(request) 30 | response = self.app.handle_request(request) 31 | self.process_response(request, response) 32 | 33 | return response 34 | 35 | def __call__(self, environ, start_response): 36 | """The code to run when the class is called as a function""" 37 | request = Request(environ) 38 | response = self.app.handle_request(request) 39 | return response(environ, start_response) 40 | -------------------------------------------------------------------------------- /Lemon/Server/server.py: -------------------------------------------------------------------------------- 1 | """ 2 | Lemon.Server: server 3 | By Sasen Perera 2022 4 | """ 5 | import inspect 6 | import webbrowser 7 | 8 | from parse import parse 9 | from webob import Request, Response 10 | from waitress import serve 11 | from whitenoise import WhiteNoise 12 | from .middleware import Middleware 13 | from requests import Session as RequestsSession 14 | from wsgiadapter import WSGIAdapter as RequestsWSGIAdapter 15 | 16 | from rich import print 17 | 18 | class Server: 19 | """Server Methods""" 20 | 21 | def __init__(self, static_dir="public"): 22 | self.routes = {} 23 | self.exception_handler = None 24 | self.whitenoise = WhiteNoise(self.wsgi_app, root=static_dir) 25 | self.middleware = Middleware(self) 26 | self.exception_handler = None 27 | 28 | def wsgi_app(self, environ, start_response): 29 | """WSGI App""" 30 | request = Request(environ) 31 | 32 | response = self.handle_request(request) 33 | 34 | return response(environ, start_response) 35 | 36 | def __call__(self, environ, start_response): 37 | """The code to run when the class is called as a function""" 38 | path_info = environ["PATH_INFO"] 39 | 40 | if path_info.startswith("/public"): 41 | environ["PATH_INFO"] = path_info[len("/public") :] 42 | return self.whitenoise(environ, start_response) 43 | 44 | return self.middleware(environ, start_response) 45 | 46 | def add_route(self, path, handler): 47 | "Django style Route Adding." 48 | assert path not in self.routes, "Such route already exists." 49 | 50 | self.routes[path] = handler 51 | 52 | def add_exception_handler(self, exception_handler): 53 | "Add Exception Handler" 54 | self.exception_handler = exception_handler 55 | 56 | def route(self, path): 57 | "route decorator: @server.route('/path')" 58 | assert path not in self.routes, "Such route already exists." 59 | 60 | def wrapper(handler): 61 | self.routes[path] = handler 62 | return handler 63 | 64 | return wrapper 65 | 66 | def default_response(self, response): 67 | "Default Response" 68 | response.status_code = 404 69 | response.text = "

404 Not Found


generated by Lemon

" 70 | 71 | def find_handler(self, request_path): 72 | "Find Handler" 73 | for path, handler in self.routes.items(): 74 | parse_result = parse(path, request_path) 75 | if parse_result is not None: 76 | return handler, parse_result.named 77 | 78 | return None, None 79 | 80 | def handle_request(self, request): 81 | """Handle Requests""" 82 | response = Response() 83 | 84 | handler, kwargs = self.find_handler(request_path=request.path) 85 | 86 | try: 87 | if handler is not None: 88 | if inspect.isclass(handler): 89 | handler = getattr(handler(), request.method.lower(), None) 90 | if handler is None: 91 | raise AttributeError("Method now allowed", request.method) 92 | 93 | handler(request, response, **kwargs) 94 | else: 95 | self.default_response(response) 96 | except Exception as e: 97 | if self.exception_handler is None: 98 | raise e 99 | else: 100 | self.exception_handler(request, response, e) 101 | 102 | return response 103 | 104 | def add_cookie( 105 | self, 106 | response, 107 | key, 108 | value, 109 | max_age=None, 110 | expires=None, 111 | path="/", 112 | domain=None, 113 | secure=False, 114 | httponly=False, 115 | samesite=None, 116 | ): 117 | "Add Cookie" 118 | response.set_cookie( 119 | key, 120 | value, 121 | max_age=max_age, 122 | expires=expires, 123 | path=path, 124 | domain=domain, 125 | secure=secure, 126 | httponly=httponly, 127 | samesite=samesite, 128 | ) 129 | 130 | def delete_cookie(self, response, key, path="/", domain=None): 131 | "Delete Cookie" 132 | response.delete_cookie(key, path=path, domain=domain) 133 | 134 | def get_cookie(self, request, key): 135 | "Get Cookie" 136 | return request.cookies.get(key) 137 | 138 | def add_middleware(self, middleware_cls): 139 | """Add Middleware""" 140 | self.middleware.add(middleware_cls) 141 | 142 | def test_session(self, base_url="http://testserver"): 143 | "Testing Session" 144 | session = RequestsSession() 145 | session.mount(prefix=base_url, adapter=RequestsWSGIAdapter(self)) 146 | return session 147 | 148 | def run(self, host="127.0.0.1", port=8000): 149 | "Runs app with waitress" 150 | host = host.lower() 151 | print( 152 | f"Running on [underline blue]http://localhost:{port} | http://127.0.0.1:{port}[/underline blue]" 153 | if host == "127.0.0.1" or host == "localhost" 154 | else f"Running on [underline blue]http://{host}:{port}[/underline blue]" 155 | ) 156 | print("To stop server press Ctrl+C") 157 | try: 158 | webbrowser.open( 159 | f"http://localhost:{port}" 160 | if host == "localhost" or "127.0.0.1" 161 | else f"http://{host}:{port}" 162 | ) 163 | try: 164 | serve(self, host=host, port=port) 165 | except Exception as e: 166 | print(f"[bold red]lemon.server: {e}[/bold red]") 167 | except Exception as e: 168 | print(f"[bold red]Lemon.Server: {e}[/bold red]") 169 | -------------------------------------------------------------------------------- /Lemon/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '1.3.9' -------------------------------------------------------------------------------- /Lemon/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from Server.server import Server 4 | 5 | @pytest.fixture 6 | def server(): 7 | return Server() 8 | 9 | 10 | @pytest.fixture 11 | def client(server): 12 | return server.test_session() 13 | -------------------------------------------------------------------------------- /Lemon/orm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/Lemon/orm/__init__.py -------------------------------------------------------------------------------- /Lemon/orm/migrations.py: -------------------------------------------------------------------------------- 1 | """ 2 | Lemon.orm: Migrations 3 | By Sasen Perera 2023 4 | """ 5 | 6 | from .DBManager import SQLConnectionManager 7 | 8 | class Migrate: 9 | """Migrate class""" 10 | 11 | def __init__(self, model_list): 12 | """Constructor for Migrate class""" 13 | 14 | self.model_list = model_list 15 | pass 16 | 17 | def migrate(self): 18 | """Migrate the database""" 19 | 20 | print("[green underline]Begin database Migration ...[/green underline]") 21 | for element in self.model_list: 22 | print() 23 | Elem = element() 24 | print(f"[yellow]{Elem.tablename}[/yellow] Migration") 25 | with SQLConnectionManager("model.db") as Connection: 26 | Connection.create_table(tablename=Elem.tablename, fields=Elem.fields) 27 | print() 28 | 29 | 30 | class MigrateCommand: 31 | """Migrate Command""" 32 | 33 | def __init__(self, model_list): 34 | """Constructor for MigrateCommand class""" 35 | 36 | self.model_list = model_list 37 | pass 38 | 39 | def migrate(self): 40 | """Migrate the database""" 41 | 42 | mig = Migrate(self.model_list) 43 | mig.migrate() 44 | -------------------------------------------------------------------------------- /Lemon/ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/Lemon/ui/__init__.py -------------------------------------------------------------------------------- /Lemon/ui/forms.py: -------------------------------------------------------------------------------- 1 | """ 2 | Lemon.ui: Forms 3 | By Sasen Perera 2022 4 | """ 5 | 6 | from ..components import Component 7 | 8 | 9 | class FormControl: 10 | def __init__(self) -> None: 11 | self.components = [self.Input, self.Select, self.Checkbox, self.Submit] 12 | 13 | class Input(Component): 14 | name = "Input" 15 | 16 | def item(props: dict): 17 | args = [ 18 | "type", 19 | "id", 20 | "placeholder", 21 | "value", 22 | "text", 23 | "rows", 24 | "cols", 25 | "disabled", 26 | "readonly", 27 | "required", 28 | "oninput", 29 | ] 30 | for arg in args: 31 | if arg not in list(props.keys()): 32 | if arg == "type": 33 | props[arg] = "text" 34 | elif arg == "id": 35 | raise ValueError("Lemon.FormControl.Input: id is required") 36 | elif arg == "rows": 37 | props[arg] = 3 38 | elif arg == "cols": 39 | props[arg] = 50 40 | else: 41 | props[arg] = "" 42 | else: 43 | pass 44 | 45 | return f""" 46 | 47 | 48 | """ 49 | 50 | class Select(Component): 51 | name = "Select" 52 | 53 | def item(props: dict): 54 | args = ["id", "text", "options", "disabled", "readonly", "size"] 55 | for arg in args: 56 | if arg not in list(props.keys()): 57 | if arg == "id": 58 | raise ValueError("Lemon.FormControl.Select: id is required") 59 | elif arg == "options": 60 | raise ValueError( 61 | "Lemon.FormControl.Select: options is required" 62 | ) 63 | else: 64 | props[arg] = "" 65 | else: 66 | if arg == "options": 67 | props[arg] = props[arg].split(",") 68 | 69 | option_text = "" 70 | selected_text = props["options"][0] 71 | props["options"].remove(selected_text) 72 | index = 1 73 | for option in props["options"]: 74 | option_text += f"""""" 75 | index += 1 76 | 77 | return f""" 78 | 79 | 83 | """ 84 | 85 | class Checkbox(Component): 86 | name = "Checkbox" 87 | 88 | def item(props: dict): 89 | output = f""" 90 |
91 | 92 | 95 |
96 | """ 97 | return output 98 | 99 | class Submit(Component): 100 | name = "Submit" 101 | 102 | def item(props: dict): 103 | args = ["id", "text", "disabled", "readonly"] 104 | for arg in args: 105 | if arg not in list(props.keys()): 106 | if arg == "id": 107 | raise ValueError("Lemon.FormControl.Submit: id is required") 108 | else: 109 | props[arg] = "" 110 | else: 111 | pass 112 | 113 | return f""" 114 | 115 | """ 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Lemon Logo 4 |

5 |
6 | 7 | [![Status](https://img.shields.io/badge/status-active-success.svg)]() 8 | [![GitHub Issues](https://img.shields.io/github/issues/Sas2k/Lemon.svg)](https://github.com/Sas2k/Lemon/issues) 9 | [![GitHub Pull Requests](https://img.shields.io/github/issues-pr/Sas2k/Lemon.svg)](https://github.com/Sas2k/Lemon/pulls) 10 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE) 11 | [![Downloads](https://static.pepy.tech/personalized-badge/lemon-library?period=total&units=international_system&left_color=yellow&right_color=orange&left_text=Downloads)](https://pepy.tech/project/lemon-library) 12 | 13 |
14 | 15 | --- 16 | 17 |

An Experimental Full-Stack Framework For Python. 18 |
19 |

20 | 21 | ## 📝 Table of Contents 22 | 23 | - [📝 Table of Contents](#-table-of-contents) 24 | - [🧐 About ](#-about-) 25 | - [🗒 To-Do ](#-to-do-) 26 | - [🏁 Getting Started ](#-getting-started-) 27 | - [Folder Structure for apps](#folder-structure-for-apps) 28 | - [Installing](#installing) 29 | - [⛏️ Built Using ](#️-built-using-) 30 | - [✍️ Authors ](#️-authors-) 31 | 32 | ## 🧐 About 33 | 34 | A full-stack framework built with python. The library is shipped with Bootstrap 5 for your styling needs. 35 | 36 | Docs: https://sas2k.github.io/Lemon 37 | 38 | Discord Server: https://discord.gg/Dw6hCp3usF 39 | 40 | Features: 41 | - UI Library (Development) 42 | - A full Back-end Capabilities 43 | - Django style route adding (See `examples/django-routing.py`) 44 | - An ORM and migrations feature (check-out -> examples/Lemon-App) (ORM supports strings only for now.) 45 | - React like syntax 46 | - middleware api 47 | - a terminal app to create app [create-lemon-app < app-name >] 48 | - Component Generator [https://github.com/Sas2k/Lemon-CLI] 49 | - Reactivity (See `examples/reactivity-example`) 50 | - Testing (See `examples/Tests.py`) 51 | - Custom Exception Handler (`examples/exception-handler.py`) 52 | - Blueprint Routing (`examples/Lemon-App`) 53 | 54 | 55 | > If you want to have live reloading try uvicorn: https://www.uvicorn.org/ 56 | 57 | > If you don't think this isn't capable to handle anything check these out!
58 | > https://sas2ks-old-portfolio.vercel.app/ | https://github.com/Sas2k/Old-Portfolio
59 | > https://github.com/Sas2k/HTTP-Blog 60 | 61 | ## 🗒 To-Do 62 | 63 | > Legend:
64 | > [x] - checked 65 | > [\*] - doing 66 | > [ ] - Not Done 67 | 68 | - [ ] Form Data Handling (Currently being Developed) 69 | - [ ] States (Currently being Developed) 70 | 71 | ## 🏁 Getting Started 72 | 73 | Docs Are still in Development Try heading over to `/examples` for some idea. 74 | Here is an example below 75 | 76 | ```python 77 | from Lemon.components import Component 78 | from Lemon.Server.server import Server 79 | 80 | app = Server(static_dir=None) 81 | Root = Component("Home Page", None, None) #Root component 82 | 83 | class Home(Component): 84 | "Home Page Component" 85 | name = "Home" 86 | 87 | def item(props: dict): 88 | "The Item Function: where the html and props are passed" 89 | return """ 90 |

Hello World!

91 | """ 92 | 93 | Root.add([Home]) 94 | 95 | @app.route("/") #Route decorator 96 | def index(request, response): 97 | home_page = Root.render("") 98 | response.text = home_page 99 | 100 | app.run() #runs the app 101 | ``` 102 | 103 | ### Folder Structure for apps 104 | 105 | Here is the folder structure I recommend. 106 | (you can create your own structure based on your needs) 107 | ``` 108 | App/ 109 | - src/ 110 | - Components/ 111 | - __init__.py 112 | - components.py 113 | - Models/ 114 | - __init__.py 115 | - models.py 116 | - Routes/ 117 | - __init__.py 118 | - routes.py 119 | - Public/ 120 | - css/ 121 | - style.css 122 | - js/ 123 | - script.js 124 | - app.py 125 | - base.py 126 | - README.md 127 | ``` 128 | 129 | ### Installing 130 | 131 | To install with, 132 | 133 | pip: `pip install Lemon-Library` 134 | 135 | ## ⛏️ Built Using 136 | 137 | - [Python](https://python.org) 138 | - [Waitress](https://pypi.org/project/waitress/) 139 | - [WebOb](https://pypi.org/project/WebOb/) 140 | - [Parse](https://pypi.org/project/parse) 141 | - [whitenoise](https://pypi.org/project/whitenoise/) 142 | - [requests](https://pypi.org/project/requests/) 143 | - [pytest](https://pypi.org/project/pytest/) 144 | - [requests (wsgi-adapter)](https://pypi.org/project/requests-wsgi-adapter/) 145 | - [black](https://pypi.org/project/black/) 146 | 147 | ## ✍️ Authors 148 | 149 | 150 | 151 | 152 | 153 | See also the list of [contributors](https://github.com/Sas2k/Lemon/contributors) who participated in this project. 154 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 17 | do not have permission to do that, you may request the second reviewer to merge it for you. 18 | 19 | ## Code of Conduct 20 | 21 | ### Our Pledge 22 | 23 | In the interest of fostering an open and welcoming environment, we as 24 | contributors and maintainers pledge to making participation in our project and 25 | our community a harassment-free experience for everyone, regardless of age, body 26 | size, disability, ethnicity, gender identity and expression, level of experience, 27 | nationality, personal appearance, race, religion, or sexual identity and 28 | orientation. 29 | 30 | ### Our Standards 31 | 32 | Examples of behavior that contributes to creating a positive environment 33 | include: 34 | 35 | * Using welcoming and inclusive language 36 | * Being respectful of differing viewpoints and experiences 37 | * Gracefully accepting constructive criticism 38 | * Focusing on what is best for the community 39 | * Showing empathy towards other community members 40 | 41 | Examples of unacceptable behavior by participants include: 42 | 43 | * The use of sexualized language or imagery and unwelcome sexual attention or 44 | advances 45 | * Trolling, insulting/derogatory comments, and personal or political attacks 46 | * Public or private harassment 47 | * Publishing others' private information, such as a physical or electronic 48 | address, without explicit permission 49 | * Other conduct which could reasonably be considered inappropriate in a 50 | professional setting 51 | 52 | ### Our Responsibilities 53 | 54 | Project maintainers are responsible for clarifying the standards of acceptable 55 | behavior and are expected to take appropriate and fair corrective action in 56 | response to any instances of unacceptable behavior. 57 | 58 | Project maintainers have the right and responsibility to remove, edit, or 59 | reject comments, commits, code, wiki edits, issues, and other contributions 60 | that are not aligned to this Code of Conduct, or to ban temporarily or 61 | permanently any contributor for other behaviors that they deem inappropriate, 62 | threatening, offensive, or harmful. 63 | 64 | ### Scope 65 | 66 | This Code of Conduct applies both within project spaces and in public spaces 67 | when an individual is representing the project or its community. Examples of 68 | representing a project or community include using an official project e-mail 69 | address, posting via an official social media account, or acting as an appointed 70 | representative at an online or offline event. Representation of a project may be 71 | further defined and clarified by project maintainers. 72 | 73 | ### Enforcement 74 | 75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 76 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 77 | complaints will be reviewed and investigated and will result in a response that 78 | is deemed necessary and appropriate to the circumstances. The project team is 79 | obligated to maintain confidentiality with regard to the reporter of an incident. 80 | Further details of specific enforcement policies may be posted separately. 81 | 82 | Project maintainers who do not follow or enforce the Code of Conduct in good 83 | faith may face temporary or permanent repercussions as determined by other 84 | members of the project's leadership. 85 | 86 | ### Attribution 87 | 88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 89 | available at [http://contributor-covenant.org/version/1/4][version] 90 | 91 | [homepage]: http://contributor-covenant.org 92 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /docs/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ["prismjs", { 4 | "languages": ["javascript", "css", "python"], 5 | "plugins": ["line-numbers"], 6 | "theme": "okaidia", 7 | "css": true 8 | }] 9 | ] 10 | } -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Lemon 🍋 Website and Docs 2 | 3 | Hello, here is the source for the website and docs of Lemon. 4 | 5 | [ This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. ] 6 | 7 | ### Installation 8 | 9 | ```bash 10 | #npm 11 | $ npm install . 12 | 13 | #yarn 14 | $ yarn 15 | ``` 16 | 17 | ### Local Development 18 | 19 | ``` bash 20 | # yarn 21 | $ yarn start 22 | 23 | # npm start 24 | $ npm run start 25 | ``` 26 | 27 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 28 | 29 | ### Build 30 | 31 | ```bash 32 | #npm 33 | $ npm run build 34 | 35 | # yarn 36 | $ yarn build 37 | ``` 38 | 39 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 40 | 41 | ### Deployment 42 | 43 | Using SSH: 44 | 45 | ```bash 46 | #yarn 47 | $ USE_SSH=true yarn deploy 48 | 49 | #npm: Linux 50 | $ USE_SSH=true npm run deploy 51 | 52 | #npm: Windows 53 | > set USE_SSH=true&&npm run deploy 54 | ``` 55 | 56 | Not using SSH: 57 | 58 | ```bash 59 | #yarn 60 | $ GIT_USER= yarn deploy 61 | 62 | #npm: Linux 63 | $ GIT_USER= npm run deploy 64 | 65 | #npm: Windows 66 | > cmd /C 'set "GIT_USER=Sas2k" && npm run deploy' 67 | ``` 68 | ``` 69 | 70 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 71 | -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/blog/2022-09-29-First-Post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: first post! 3 | authors: Sas2k 4 | --- 5 | 6 | # Hello! 👋🏽 7 | 8 | This is the very first post on the blog. 9 | 10 | This blog will give updates on Lemon and it's Development 11 | 12 | Github: https://github.com/Sas2k/Lemon 13 | 14 | Until the next one, 15 | Good day people! -------------------------------------------------------------------------------- /docs/blog/2022-10-01-Version-1-0-0-Update.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Version 1.0.0 Release 🎉 3 | authors: Sas2k 4 | --- 5 | 6 | # Lemon 🍋 is finally out of Beta, and on to Production. 7 | 8 | version 1.0.0 is released! 9 | and with it lemon is no longer Beta! 🎉 10 | 11 | ## Changes 12 | - Added Docs 13 | - Added Doc-String and Polished code 14 | - Added an example for middleware `examples/middleware-example.py` 15 | 16 | **Full Changelog**: https://github.com/Sas2k/Lemon/compare/V.Beta-3.7.0...V.1.0.0 17 | 18 | _**We've come a long way people. Until next time, Good Day people!**_ -------------------------------------------------------------------------------- /docs/blog/2022-10-04-Version-1-2-1-Update.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Version 1.2.0 Release 💾 3 | authors: Sas2k 4 | --- 5 | 6 | # Version 1.2.0 💾 7 | 8 | ## Changes 9 | 10 | - Changed the way, how the ORM functions 11 | ```python 12 | #base.py 13 | from Lemon.orm import DBManager, migrations 14 | 15 | baseModel = DBManager.baseModel 16 | ClassBase = DBManager.base 17 | migrate = migrations.MigrateCommand 18 | 19 | class model(baseModel): 20 | base_model = ClassBase 21 | tablename = "model" 22 | fields = ("field1", "field2") 23 | 24 | model_list = [model] 25 | 26 | migrate(model_list).migrate() 27 | #models.py 28 | from Lemon.orm.DBManager import SqliteManager 29 | 30 | sql = SqliteManager("../model.db") 31 | sql.insert("model", [("field1", "field2"), ("Hello", "World")]) 32 | ``` 33 | 34 | - Finished the Tutorial on Docs. 35 | 36 | - Updated `create-lemon-app` 37 | *`Models/Models.py`, `Models/__init__.py` and `app.py` updated* 38 | 39 | - Added Versioning Tags to Docs 40 | 41 | **Full Changelog**: https://github.com/Sas2k/Lemon/compare/V.1.0.0...V.1.2.0 42 | 43 | _**Until Next Time Good Day people!**_ -------------------------------------------------------------------------------- /docs/blog/2022-10-07-Version-1-3-0-Update.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Version 1.3.0 Release 🧪 3 | authors: Sas2k 4 | --- 5 | 6 | # Version 1.3.0 🧪 7 | 8 | ## Changes 9 | 10 | - Added Test Fixtures for server. 11 | 12 | ```python 13 | import pytest 14 | 15 | def client_can_send_requests(server, client): 16 | RESPONSE_TEXT = "THIS IS COOL" 17 | @server.route("/test") 18 | def test(request, response): 19 | response.text = RESPONSE_TEXT 20 | 21 | assert client.get("http://testserver/hey").text == RESPONSE_TEXT 22 | ``` 23 | 24 | - Added Exception Handler (the text you get when a server gets an error) 25 | 26 | ```python 27 | class ExceptionComponent(Component): 28 | name = "ExceptionComponent" 29 | 30 | def item(props: dict): 31 | return """ 32 | 51 |
52 |

001010100101101010010100101

53 |

Looks like something went wrong

54 |

Please try again later......

55 |
56 | """ 57 | 58 | def custom_exception_handler(request, response, exception_cls): 59 | response.text = root.render("") 60 | 61 | app.add_exception_handler(custom_exception_handler) 62 | ``` 63 | 64 | - Django Like Routing (since of this, blueprinting is now achievable: check `examples/Lemon-App`) 65 | 66 | ```python 67 | from Lemon.Server import server 68 | 69 | app = server.Server(None) 70 | 71 | def index(request, response): 72 | response.text = "Hello, world!" 73 | 74 | app.add_route("/", index) 75 | 76 | app.run() 77 | ``` 78 | 79 | - Updated `create-react-app`. 80 | 81 | **Full Changelog**: https://github.com/Sas2k/Lemon/compare/V.1.2.6...V.1.3.0 82 | 83 | _**Until Next Time Good Day people!**_ -------------------------------------------------------------------------------- /docs/blog/authors.yml: -------------------------------------------------------------------------------- 1 | Sas2k: 2 | name: Sasen Perera 3 | title: Maintainer and Creator of Lemon 🍋 4 | url: https://github.com/sas2k 5 | image_url: https://github.com/sas2k.png 6 | -------------------------------------------------------------------------------- /docs/docs/Hello-World.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World! 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon 🍋: Hello-World! 7 | 8 | Hello, in this part. we're going to build a small lemon app. 9 | 10 | ## Getting Started 11 | 12 | first of, let's create a virtual environment. 13 | 14 | ```bash 15 | #with venv 16 | python -m venv venv 17 | 18 | #with virtualenv 19 | python -m virtualenv venv 20 | ``` 21 | 22 | then activate it with the below command. 23 | 24 | ```bash 25 | #windows 26 | .\\venv\\Scripts\\activate 27 | ``` 28 | 29 | after that install Lemon in it. 30 | 31 | ```bash 32 | pip install Lemon-Library 33 | ``` 34 | 35 | ## creating the app 36 | 37 | now in that app create a file called `app.py` 38 | 39 | now in that app paste this code (don't worry I will explain the code). 40 | 41 | ```python 42 | from Lemon.components import Component 43 | from Lemon.Server.server import Server 44 | 45 | app = Server(None) 46 | Root = Component("Home") 47 | 48 | class home(Component): 49 | 50 | name = "home" 51 | 52 | def item(props: dict): 53 | return """ 54 |

Hello World!

55 |

This is generated in Python!

56 |

This is in BOLD

57 |

This is in ITALICS

58 | My Github Profile 59 | """ 60 | 61 | Root.add(home) 62 | 63 | @app.route("/") 64 | def student(request, response): 65 | home_page = Root.render("") 66 | response.text = home_page 67 | 68 | app.run() 69 | ``` 70 | 71 | now to run it, just do this. 72 | 73 | `python app.py` 74 | 75 | ## Code Break Down 🥚🍳 76 | 77 | Now let's break the code down. 78 | 79 | in the first 2 lines, it imports the server and the Component Class. (which is the base class to create the components.) 80 | 81 | then we define an `app` variable, which is the server instance. 82 | the `root` variable is the root component where the components are rendered. 83 | 84 | then there is the `Home` Class, which is a component. 85 | 86 | in the component class, there is a `name` variable, which is the variable that says the name of the variable. 87 | 88 | then the `item` function is where the components stuff is there (like the filling of a pie 🥧). 89 | 90 | the `item` function has a `props` dictionary object. Which are the properties of the element. 91 | 92 | For example: ` 93 | 94 | here the `name="Sas2k"` is the prop. 95 | 96 | After that the component is added to the Root with the `Root.add`. 97 | 98 | then their is the usual route function. 99 | 100 | After, their is the `app.run` which runs it. 101 | 102 | And that's basically it. 103 | 104 | _A Lemon app, broken down._ 105 | -------------------------------------------------------------------------------- /docs/docs/api-reference/Lemon-Server-middleware.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server.middleware 3 | sidebar_position: 4 4 | --- 5 | 6 | # Lemon.Server.middleware 7 | 8 | The middleware module 9 | 10 | ```python 11 | 1 | from Lemon.components import Component 12 | 2 | from Lemon.Server import server, middleware 13 | 3 | 14 | 4 | app = server.Server(None) 15 | 5 | 16 | 6 | class middleware_example(middleware.Middleware): 17 | 7 | def process_request(self, req): 18 | 8 | print("Despatching ->", req.url) 19 | 9 | 20 | 10| def process_response(self, req, res): 21 | 11| print("Despatched", req.url) 22 | 12| 23 | 13|app.add_middleware(middleware_example) 24 | ``` 25 | 26 | ## Middleware [Class] | (self, app) 27 | 28 | The middleware base class 29 | 30 | ### Attributes, Properties and Functions 31 | 32 | #### add [Function] | (self, middleware_cls) < Developer-Function > 33 | 34 | Adds a middleware. 35 | 36 | #### process_request [Function] | (self, req) 37 | 38 | Process's the middleware's requests 39 | 40 | > line 6~8 on example 41 | 42 | #### process_response [Function] | (self, req) 43 | 44 | Process's the middleware before sending back the response 45 | 46 | > line 10~11 on example 47 | 48 | #### handle_request [Function] | (self, req, res) < Developer-Function > 49 | 50 | Handles Request that the class receives. 51 | -------------------------------------------------------------------------------- /docs/docs/api-reference/Lemon-Server-server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server.server 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon.Server.server 7 | 8 | The server, the main backend. (which contains routes and etc..) 9 | 10 | ## Server [Class] | (self, static_dir="public") 11 | 12 | The Server Methods 13 | 14 | ```python 15 | from Lemon.Server import server 16 | 17 | app = server.Server(None) #place None here if you don't have any static files. 18 | ``` 19 | 20 | ### Attributes, Properties and Functions 21 | 22 | #### wsgi_app [Function] | (self, environ, start_response) | < Developer-Function > 23 | 24 | returns a response with environ. 25 | 26 | #### add_route [Function] | (self, path, handler) 27 | 28 | This function adds route django style!. 29 | 30 | ```python 31 | def index(request, response): 32 | response.text = "Hello World!" 33 | 34 | app.add_route("/", index) 35 | ``` 36 | 37 | #### add_exception_handler [Function] | (self, exception_handler) 38 | 39 | Adds a sever exception handler. 40 | 41 | ```python 42 | def custom_exception_handler(request, response, exception_cls): 43 | response.text = "Oops!, Something went wrong!" 44 | 45 | app.add_exception_handler(custom_exception_handler) 46 | ``` 47 | 48 | #### route [Decorator(Function)] | (self, path) 49 | 50 | the route decorator. 51 | 52 | ```python 53 | #Function Based Handler 54 | @app.route("/") 55 | def index(request, response): 56 | request.text = "Hello World" 57 | 58 | #Class Based Handler 59 | @app.route("/") 60 | class Index(): 61 | def get(self, req, res): 62 | res.text = "Hello World" 63 | 64 | def post(self, req, res): 65 | res.text = req.json 66 | ``` 67 | 68 | #### handle_request [Function] | (self, request) | < Developer-Function > 69 | 70 | Handles incoming requests. 71 | 72 | #### add_cookie [Function] | (self, response, key, value, max_age=None, expires=None, path="/", domain=None, Secure=False, httponly=False, samesite=None) 73 | 74 | Creates a cookie 🍪 75 | 76 | ```python 77 | @app.route("/") 78 | def index(request, response): 79 | add_cookie(response, "Hello", "world") 80 | ``` 81 | 82 | #### delete_cookie [Function] | (self, response, key, path="/", domain=None) 83 | 84 | Deletes a cookie 🍪🤏🏽 85 | 86 | ```python 87 | @app.route("/") 88 | def index(request, response): 89 | delete_cookie(response, "Hello") 90 | ``` 91 | 92 | #### get_cookie [Function] | (self, request, key) 93 | 94 | Gets a cookie 📦 95 | 96 | ```python 97 | @app.route("/") 98 | def index(request, response): 99 | get_cookie(request, "Hello") 100 | ``` 101 | 102 | #### add_middleware [Function] | (self, middleware_cls) 103 | 104 | Adds a middleware to run. 105 | 106 | ```python 107 | app.add_middleware(PrintMiddleWare) # <- Fake name "PrintMiddleWare" 108 | ``` 109 | 110 | #### test_session [Function] | (self, base_url="http://testserver") < Developer-Function > 111 | 112 | The testing session used in tests. 113 | 114 | #### run [Function] | (self, host="127.0.0.1", post=8000) 115 | 116 | Runs the app. 117 | 118 | ```python 119 | app.run(port=5000) 120 | ``` 121 | -------------------------------------------------------------------------------- /docs/docs/api-reference/Lemon-Server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon.Server 7 | 8 | The module containing the middleware and server functions. 9 | 10 | ## [Lemon.Server.server](Lemon-Server-server) 11 | ## [Lemon.Server.middleware](Lemon-Server-middleware) -------------------------------------------------------------------------------- /docs/docs/api-reference/Lemon-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.components 3 | sidebar_position: 1 4 | --- 5 | 6 | # Lemon.components 7 | 8 | The module responsible for initializing and creating components. 9 | 10 | ## Component [Class] | (self, name, stylesheet=None, script=None) 11 | 12 | The base component class 13 | 14 | ```python 15 | class TestComponent(Component): 16 | name = "TestComponent" 17 | 18 | def item(props: dict): 19 | return """ 20 |

Hello World!

21 |

Lorem ispum

22 | """ 23 | ``` 24 | 25 | > When naming Components, Always make the first letter Capital as if your writing names. 26 | 27 | ### Attributes, Properties and Functions 28 | 29 | #### add [Function] | (self, components: list or object) 30 | 31 | Adds a component(s) to a list. to parse. 32 | 33 | ```python 34 | Root.add( 35 | [ 36 | Component, 37 | Testing, 38 | WarningComponent 39 | ] 40 | ) 41 | ``` 42 | 43 | #### parse [Function] | (self, Root, prop: list) | < Developer-Function > 44 | 45 | The function that parses the string. 46 | 47 | #### render [Function] | (self, app: str) 48 | 49 | The function that will render the component 50 | 51 | ```python 52 | response.text = Root.render("") 53 | ``` 54 | 55 | #### item [Function] | (self, props: dict) 56 | 57 | The function where the components html/elements are present 58 | 59 | ```python 60 | # must be inside your component class. 61 | def item(props: dict): 62 | return f""" 63 |

{props['title']}

64 |

{props['body']}

65 | """ 66 | ``` 67 | -------------------------------------------------------------------------------- /docs/docs/api-reference/Lemon-orm-DBManager.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm.DBManager 3 | sidebar_position: 6 4 | --- 5 | 6 | # Lemon.orm.DBManager 7 | 8 | The Database Manager 9 | 10 | ## SQLConnectionManager [Class] | (self, filename) < Developer-Class > 11 | 12 | The SQLConnectionManager used in migrations 13 | 14 | ### Attributes, Properties and Functions 15 | 16 | #### commit [Decorator(Functions)] | (operation) 17 | 18 | Commits a query. 19 | 20 | #### create_table [Function] | (self, tablename, fields) 21 | 22 | creates a table 23 | 24 | #### show_tables [Property(Function)] | (self) 25 | 26 | shows the tables in the database 27 | 28 | ## SqliteManager [Class] | (self, filename) 29 | 30 | The SQLite Manager. 31 | 32 | ```python 33 | from Lemon.orm.DBManager import SqliteManager 34 | 35 | sql = SqliteManager("model.db") 36 | 37 | sql.select("authors", ["name", "age"]) 38 | 39 | sql.insert("authors", ["Paul", "age"], ["Paul", "25"]) 40 | 41 | ``` 42 | 43 | ### commit [Decorator(function)] | (operation) < Developer-Function > 44 | 45 | Commits the query. 46 | 47 | ### create_table [Function] | (self, tablename, columns) 48 | 49 | Creates a table in the Database. 50 | 51 | ```python 52 | sql = SqliteManager("model.db") 53 | 54 | sql.create_table("authors", ["name", "age"]) 55 | ``` 56 | 57 | ### insert [Function] | (self, tablename, columns, values) 58 | 59 | inserts data to columns 60 | 61 | ```python 62 | sql = SqliteManager("model.db") 63 | 64 | sql.insert("authors", ["name", "age"], ["Paul", "25"]) 65 | ``` 66 | 67 | ### select [Function] | (self, tablename, columns) 68 | 69 | selects columns from the table. 70 | 71 | 72 | ```python 73 | sql = SqliteManager("model.db") 74 | 75 | sql.select("authors", ["name", "age"]) 76 | ``` 77 | 78 | ### delete [Function] | (self, tablename, conditions, logic="AND") 79 | 80 | Deletes a record from the table which matches the condition. 81 | 82 | ```python 83 | sql = SqliteManager("model.db") 84 | 85 | sql.delete("authors", ["name='paul'", "age=25"], "AND") 86 | ``` 87 | 88 | ### update [Function] | (self, tablename, columns, values) 89 | 90 | Update values in the Database. 91 | 92 | ```python 93 | sql = SqliteManager("model.db") 94 | 95 | sql.update("authors", ["name", "age"], ["Paul", "22"]) 96 | ``` 97 | 98 | ## base [Class] | (self) 99 | 100 | The Base Class to be inherited. 101 | 102 | ## baseModel [Class] | (self) 103 | 104 | The Base Model to be inherited 105 | 106 | ## MetaModel [Class] | (self) < Developer-Class > 107 | 108 | The MetaModel Class 109 | 110 | > `base`, `baseModel` and `MetaModel` are used in the migrations. -------------------------------------------------------------------------------- /docs/docs/api-reference/Lemon-orm-migrations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm.migrations 3 | sidebar_position: 7 4 | --- 5 | 6 | # Lemon.orm.migrations 7 | 8 | The migrations manager 9 | 10 | ```python 11 | from Lemon.orm import DBManager, migrations 12 | 13 | baseModel = DBManager.baseModel 14 | ClassBase = DBManager.base 15 | migrate = migrations.MigrateCommand 16 | 17 | class model(baseModel): 18 | base_model = ClassBase 19 | tablename = "model" 20 | fields = ("field1", "field2") 21 | 22 | model_list = [model] 23 | 24 | migrate(model_list).migrate() 25 | ``` 26 | 27 | ## Migrate [Class] | (self, model_list) < Developer-Class > 28 | 29 | The migrate command for the Lemon ORM 30 | 31 | ### Attributes, Properties and Functions 32 | 33 | #### migrate [Function] | (self) 34 | 35 | migrates the models to a Database. 36 | 37 | ## MigrateCommand [Function] | (model_list) 38 | 39 | The base function for the migrate function. 40 | 41 | ## Attributes, Properties and Functions 42 | 43 | #### migrate [Function] | (self) 44 | 45 | The migrate function which is used in base.py 46 | 47 | ```python 48 | model_list = [model] 49 | 50 | migrate(model_list).migrate() 51 | ``` -------------------------------------------------------------------------------- /docs/docs/api-reference/Lemon-orm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm 3 | sidebar_position: 5 4 | --- 5 | 6 | # Lemon.orm 7 | 8 | the module containing the ORM. 9 | 10 | ## [Lemon.orm.DBManager](Lemon-orm-DBManager) 11 | ## [Lemon.orm.migrations](Lemon-orm-migrations) -------------------------------------------------------------------------------- /docs/docs/lemon-in-3min.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon In 3 minutes 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon in 3 minutes 7 | 8 | Let's try to create a site in **Lemon 🍋**.. 9 | 10 | ## Getting Started 11 | 12 | To get started first install Lemon 🍋 from pip 13 | 14 | ``` 15 | pip install Lemon-Library 16 | ``` 17 | 18 | ## Generate a new site 19 | 20 | to generate a new site run this command 21 | 22 | ``` 23 | create-lemon-app my-website 24 | ``` 25 | 26 | ## Start your site 27 | 28 | Run the development server: 29 | 30 | ```bash 31 | cd my-website 32 | python app.py 33 | ``` 34 | 35 | then visit localhost:8000 36 | 37 | The `cd` command changes the current directory to the website dir, 38 | 39 | next the `python app.py` runs the app. 40 | 41 | Now that you done this, head over to the [tutorial](tutorial/intro-to-tutorial), to create a basic app. -------------------------------------------------------------------------------- /docs/docs/lemon-vs-react.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon vs React 3 | sidebar_position: 4 4 | --- 5 | # Lemon vs React. 6 | 7 | In this page we're going to talk about the differences of Lemon and React. 8 | 9 | ## TLDR; What is React? 10 | 11 | React is a front-end framework for JavaScript, it's used to build Interactive UIs. ([Website](https://reactjs.org/)) 12 | 13 | **Now let's compare them feature at a time** 14 | 15 | ## Components 16 | 17 | Now let's talk about components, Both of the libraries use Components. 18 | 19 | ### Lemon [Python] (v1.0.0) 20 | 21 | ```python 22 | class HelloMessage(Component): 23 | name = "HelloMessage" 24 | def item(props:dict): 25 | return f"

Hello! {props['name']}" 26 | 27 | @app.route("/") #don't mind the app.route or the index function there just there to route the sever 28 | def index(request, response): 29 | response.text = root.render("") 30 | ``` 31 | 32 | ### React (JSX) 33 | 34 | ```jsx 35 | function HelloMessage(props){ 36 | return

Hello {props.name}
; 37 | }; 38 | 39 | root.render() 40 | ``` 41 | 42 | The first one is in Lemon(Python), 43 | The Second one is in React (JSX) 44 | 45 | Here we have a simple component created in both. 46 | Both of them are very similar. Except for the fact that since React uses JSX, you can write HTML directly. 47 | 48 | ## Reactivity 49 | 50 | what reactivity does is when the information, variables change, the render changes automatically. 51 | 52 | here is a To-Do example in both Lemon and React. 53 | 54 | ### Lemon (v1.0.0) 55 | 56 | `app.py` 57 | 58 | ```python 59 | class ToDo(Component): 60 | name = 'ToDo' 61 | def item(props:dict): 62 | return f""" 63 |
64 |
    65 |
66 | 67 |
68 | """ 69 | 70 | @app.route("/") 71 | def index(request, response): 72 | response.text = root.render("") 73 | ``` 74 | 75 | `public/index.js` 76 | 77 | ```js 78 | let todoitems = () => { 79 | data.message = document.getElementById("Text").value; 80 | }; 81 | 82 | let updateToDo = () => { 83 | document.getElementById("Todo-List").appendChild('
  • ' + data.message + '
  • \n'); 84 | }; 85 | 86 | watcher(updateToDo); 87 | ``` 88 | 89 | ### React 90 | 91 | > taken from homepage example. 92 | 93 | ```jsx 94 | class TodoApp extends React.Component { 95 | constructor(props) { 96 | super(props); 97 | this.state = { items: [], text: '' }; 98 | this.handleChange = this.handleChange.bind(this); 99 | this.handleSubmit = this.handleSubmit.bind(this); 100 | } 101 | 102 | render() { 103 | return ( 104 |
    105 |

    TODO

    106 | 107 |
    108 | 111 | 116 | 119 |
    120 |
    121 | ); 122 | } 123 | 124 | handleChange(e) { 125 | this.setState({ text: e.target.value }); 126 | } 127 | 128 | handleSubmit(e) { 129 | e.preventDefault(); 130 | if (this.state.text.length === 0) { 131 | return; 132 | } 133 | const newItem = { 134 | text: this.state.text, 135 | id: Date.now() 136 | }; 137 | this.setState(state => ({ 138 | items: state.items.concat(newItem), 139 | text: '' 140 | })); 141 | } 142 | } 143 | 144 | class TodoList extends React.Component { 145 | render() { 146 | return ( 147 |
      148 | {this.props.items.map(item => ( 149 |
    • {item.text}
    • 150 | ))} 151 |
    152 | ); 153 | } 154 | } 155 | 156 | root.render(); 157 | ``` 158 | 159 | Here as we can see, for lemon reactivity happens through a function called `watcher` which watched the function and it's variables to change, the `data.message` are the values that would change. 160 | 161 | **And that's about it, for the differences... (I might add more soon...)** -------------------------------------------------------------------------------- /docs/docs/table.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Table Of Contents 6 | - ## [Table-Of-Contents](table) 7 | - ## [Intro](lemon-in-3min) 8 | - ## Tutorial 9 | - ### [Intro](tutorial/intro-to-tutorial) 10 | - ### [Part-1](tutorial/tutorial-part-1) 11 | - ### [Part-2](tutorial/tutorial-part-2) 12 | - ### [Part-3](tutorial/tutorial-part-3) 13 | - ### [Part-4](tutorial/tutorial-part-4) 14 | - ### [Part-5](tutorial/tutorial-part-5) 15 | - ## Differences (Lemon vs [another library]) 16 | - ### [Lemon vs React](lemon-vs-react) 17 | - ## API Reference (Library Reference) 18 | - ### [Lemon.Components](api-reference/Lemon-Components) 19 | - ### [Lemon.Server](api-reference/Lemon-Server) 20 | - ### [Lemon.Server.server](api-reference/Lemon-Server-server) 21 | - ### [Lemon.Server.middleware](api-reference/Lemon-Server-middleware) 22 | - ### [Lemon.orm](api-reference/Lemon-orm) 23 | - ### [Lemon.orm.DBManager](api-reference/Lemon-orm-DBManager) 24 | - ### [Lemon.orm.migrations](api-reference/Lemon-orm-migrations) 25 | -------------------------------------------------------------------------------- /docs/docs/tutorial/images/blog-page.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/docs/docs/tutorial/images/blog-page.PNG -------------------------------------------------------------------------------- /docs/docs/tutorial/intro-to-tutorial.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | > This tutorial series will think, { that you already installed Lemon-Library and Python } 4 | > AND { that you have sufficient knowledge of Python. } 5 | 6 | Hello!, In this tutorial we are going to build a basic app in Lemon. 7 | So you guys can get the hang of it and learn it. 8 | 9 | ## What will be building? 10 | 11 | We're going to build a blog that can be updated through http request. 12 | 13 | So, now that we know what we're building let's get to it!. -------------------------------------------------------------------------------- /docs/docs/tutorial/tutorial-part-1.md: -------------------------------------------------------------------------------- 1 | # Part 1: Setting things up. 2 | 3 | Now, let's set thing up. 4 | 5 | firstly, let's run the usual `create-lemon-app` command to generate the boilerplate code. 6 | 7 | ```cmd 8 | create-lemon-app http-blog 9 | ``` 10 | 11 | ``` 12 | App created @ /http-blog/ 13 | ``` 14 | 15 | then move into it with `cd` 16 | 17 | ```bash 18 | cd http-blog 19 | ``` 20 | 21 | then the directory should look like this. 22 | 23 | ```dir 24 | http-blog/ 25 | - models/ 26 | - model.py 27 | -public/ 28 | - css/ 29 | - style.css 30 | - js/ 31 | - script.js 32 | - app.py 33 | - base.py 34 | - README.md 35 | ``` 36 | 37 | now create a virtual environment 38 | 39 | ```cmd 40 | #with venv 41 | python -m venv venv 42 | 43 | #with virtualenv 44 | pip install virtualenv #if you haven't already installed it before 45 | python -m virtualenv venv 46 | ``` 47 | 48 | After this install `Lemon` 49 | ``` 50 | pip install Lemon-Library 51 | ``` 52 | 53 | then run the `app.py` to see if everything is correct. 54 | 55 | `python app.py` 56 | 57 | if the app is running then visit localhost:8000, to see the app running. 58 | 59 | then press `control + c` to stop. 60 | 61 | now go ahead and delete the `script.js` and `style.css` which is inside the public. (since we don't need it yet.) 62 | 63 | Now go into the app.py 64 | 65 | and replace the file with this. 66 | 67 | ```python 68 | from Lemon.components import Component 69 | from Lemon.Server.server import Server 70 | 71 | Root = Component("Lemon") 72 | app = Server(static_dir="public") 73 | 74 | class App(Component): 75 | name = "App" 76 | def item(props: dict): 77 | return "Hello World" 78 | 79 | Root.add( 80 | [ 81 | App 82 | ] 83 | ) 84 | 85 | @app.route("/") 86 | def home(request, response): 87 | response.text = Root.render('') 88 | 89 | app.run() 90 | 91 | ``` 92 | 93 | Here, we have removed everything unnecessary from the app. 94 | (We kept the app component since, it will be the main component.) 95 | 96 | now if you run it. 97 | 98 | you will just see a Hello World text on the browser. 99 | 100 | Now the files are prepped and ready to write the code. 101 | 102 | Go to Part II. -------------------------------------------------------------------------------- /docs/docs/tutorial/tutorial-part-2.md: -------------------------------------------------------------------------------- 1 | # Part 2: Writing the basic components. 2 | 3 | now, let's create a directory(which is a fancy term for a folder.) and name it `Components` 4 | 5 | in this folder we're going to create a folder called `components.py` 6 | 7 | now we're going to write a basic component which has the title, the body and the author. 8 | 9 | > Now before we write anything let me quickly give you the structure of a component. 10 | > ```python 11 | > class thing(Component): 12 | > name = "thing" # the name here will the name going to be used in `root.render()` 13 | > def item(props: dict): 14 | > return "

    THING

    " # the item function is where the html code is presented. 15 | > ``` 16 | 17 | now firstly we need to import the `Component` class, which is the base class. 18 | ```python 19 | from Lemon.components import Component 20 | ``` 21 | 22 | then let's write a basic post component 23 | 24 | ```python 25 | class BlogPost(Component): 26 | name = "BlogPost" 27 | 28 | def item(props: dict): 29 | return f""" 30 |
    31 |

    {props['title']}

    32 |

    By {props['author']}

    33 |
    34 |

    {props['body']}

    35 |
    36 | """ 37 | ``` 38 | 39 | (you can change it however you like.) 40 | 41 | now in the `app.py` file import it like this. 42 | `from Components.components import BlogPost` 43 | 44 | then change the Root.add function like this, 45 | 46 | ```python 47 | Root.add( 48 | [ 49 | App, 50 | BlogPost 51 | ] 52 | ) 53 | ``` 54 | 55 | now you can test it out by removing the "Hello World" from the App components `item` function, and adding the `BlogPost` one. 56 | 57 | `` 58 | 59 | (above is an example) 60 | 61 | Now if you run it, you should see something like below. 62 | 63 | ----------------------------- 64 | 65 | ## Hello World 66 | ### Your-Name 67 | Lorem Ispum Dorem Almet why is this used everywhere? 68 | 69 | ----------------------------- 70 | 71 | Now, that the component is created an working let's move onto part 3. -------------------------------------------------------------------------------- /docs/docs/tutorial/tutorial-part-3.md: -------------------------------------------------------------------------------- 1 | # Part 3: Building the api. 2 | 3 | Now that we got the basic front-end down. 4 | 5 | We now have to focus on the back-end, which is the API. 6 | 7 | let's start of by creating a routes called /api/get and /api/post 8 | 9 | so the basic decorator to create the route is. 10 | 11 | ```python 12 | @app.route("/route") 13 | def route(request, response): 14 | response.text = "route" 15 | ``` 16 | 17 | now since /api/get is uses a `GET` method we can just make it a normal route. 18 | 19 | ```python 20 | @app.route("/api/get/{post_id:d}") # the {post_id} is an argument in the url. the d means digit. 21 | def api_get(request, response, post_id): 22 | #for now let's just return the post_id 23 | response.json = { "post_id": post_id } 24 | ``` 25 | 26 | now for the /api/post we have to use a class for this. 27 | 28 | ```python 29 | @app.route('/app/post/') 30 | class api_post(): 31 | def get(self, req, res): 32 | res.text = "method not allowed" 33 | def post(self, req, res): 34 | print(req.json) 35 | ``` 36 | 37 | here the body of the request is printed. 38 | now the basic api is implemented let's move to part 4. -------------------------------------------------------------------------------- /docs/docs/tutorial/tutorial-part-4.md: -------------------------------------------------------------------------------- 1 | # Part 4: Storing the requests and Displaying them as Posts 2 | 3 | In this part, we're going to store the requests, and then we're going to display them. as pages. 4 | 5 | To store them, we're going to create a `posts` list. 6 | 7 | ```python 8 | posts = [{"title": "Hello World", "author": "Lemon", "body": "This is a test post"}] 9 | ``` 10 | 11 | now let's change the return of the item function in the App Component to this, 12 | 13 | ```python 14 | return f"" 15 | ``` 16 | 17 | also let's change the "/" route to "/{post_id}" and add these. 18 | 19 | ```python 20 | @app.route("/{post_id}") 21 | def home(request, response, post_id): 22 | if post_id.isdigit(): 23 | try: 24 | post = posts[int(post_id)-1] 25 | response.text = Root.render(f'') 26 | except IndexError: 27 | response.status_code = 404 28 | response.text = "

    Post not found

    " 29 | else: 30 | response.text = "

    This id should be an integer, Not String

    " 31 | ``` 32 | 33 | also remember the API routes, let's change them like this. 34 | 35 | ```python 36 | @app.route("/api/get/{post_id}") # the {id} is an argument in the url. 37 | def api_get(request, response, post_id): 38 | #for now let's just return the post_id 39 | response.text = posts[post_id] 40 | 41 | @app.route('/api/post/') 42 | class api_post(): 43 | def get(self, req, res): 44 | res.text = "method not allowed" 45 | def post(self, req, res): 46 | json = req.json 47 | if json["title"] and json["body"] and json["author"] and json["id"]: 48 | post_id = int(json["id"]) 49 | if post_id not in posts: 50 | posts[post_id] = json 51 | res.text = "success" 52 | else: 53 | posts.append(json) 54 | res.text = "success" 55 | else: 56 | res.text = "failed" 57 | ``` 58 | 59 | And now run, the app. 60 | 61 | Try going to. https://localhost:8000/1 62 | 63 | and you should see the Test Post. 64 | 65 | you can create a your own posts by sending post requests to `/api/post` 66 | 67 | here is an example body 68 | 69 | ```json 70 | { 71 | "title": "Hello World", 72 | "author": "Sas2k", 73 | "body": "Lorem Ispum Dorem Alamet" 74 | } 75 | ``` 76 | 77 | And that's about it. 78 | 79 | We've created a fully functioning App in Lemon. 80 | 81 | Now let's move to part 5, to style the blog. -------------------------------------------------------------------------------- /docs/docs/tutorial/tutorial-part-5.md: -------------------------------------------------------------------------------- 1 | # Part 5: Styling the blog and finalizing. 2 | 3 | In this part we're going to style the posts. 4 | 5 | Now let's delete the `JS` folder, but let's keep the `CSS` Folder. 6 | 7 | Now let's create a `style.css`. 8 | 9 | Add this CSS code to style it. 10 | 11 | ```css 12 | * { 13 | font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; 14 | font-size: 1.2rem; 15 | color: #333; 16 | line-height: 1.5; 17 | margin: 0; 18 | padding: 0; 19 | box-sizing: border-box; 20 | } 21 | 22 | body { 23 | background: #ffffff; 24 | } 25 | 26 | h1 { 27 | font-size: 3rem; 28 | line-height: 1.2; 29 | margin-bottom: 1rem; 30 | } 31 | 32 | h2 { 33 | font-size: 2rem; 34 | margin-bottom: 1rem; 35 | } 36 | 37 | h3 { 38 | font-size: 1.5rem; 39 | margin-bottom: 1rem; 40 | color: #ffa; 41 | } 42 | 43 | p { 44 | margin-bottom: 1rem; 45 | } 46 | ``` 47 | 48 | now in the `app.py` file let's change the `Root`, to add the CSS file. 49 | 50 | ```python 51 | Root = Component("HTTP-Blog", stylesheet="public/css/style.css") 52 | ``` 53 | 54 | Now run the app and see the page now. 55 | 56 | ![blog-output](images/blog-page.PNG) 57 | 58 | And that's about it. 59 | 60 | A fully functioning app in Lemon 🍋. 61 | 62 | Github: https://github.com/Sas2k/HTTP-Blog -------------------------------------------------------------------------------- /docs/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Note: type annotations allow type checking and IDEs autocompletion 3 | 4 | const lightCodeTheme = require('prism-react-renderer/themes/github'); 5 | const darkCodeTheme = require('prism-react-renderer/themes/dracula'); 6 | 7 | /** @type {import('@docusaurus/types').Config} */ 8 | const config = { 9 | title: 'Lemon 🍋', 10 | tagline: 'A Full-Stack Framework for Python', 11 | url: 'https://sas2k.github.io/', 12 | baseUrl: '/Lemon/', 13 | trailingSlash: false, 14 | onBrokenLinks: 'throw', 15 | onBrokenMarkdownLinks: 'warn', 16 | favicon: 'img/favicon.png', 17 | 18 | // GitHub pages deployment config. 19 | // If you aren't using GitHub pages, you don't need these. 20 | organizationName: 'Sas2k', // Usually your GitHub org/user name. 21 | projectName: 'Lemon', // Usually your repo name. 22 | 23 | // Even if you don't use internalization, you can use this field to set useful 24 | // metadata like html lang. For example, if your site is Chinese, you may want 25 | // to replace "en" with "zh-Hans". 26 | i18n: { 27 | defaultLocale: 'en', 28 | locales: ['en'], 29 | }, 30 | 31 | presets: [ 32 | [ 33 | 'classic', 34 | /** @type {import('@docusaurus/preset-classic').Options} */ 35 | ({ 36 | docs: { 37 | sidebarPath: require.resolve('./sidebars.js'), 38 | editUrl: ({versionDocsDirPath, docPath}) => 39 | `https://github.com/Sas2k/Lemon/edit/main/website/${versionDocsDirPath}/${docPath}` 40 | }, 41 | blog: { 42 | showReadingTime: true, 43 | editUrl: 44 | 'https://github.com/Sas2k/Lemon/tree/main/docs/Lemon-Docs', 45 | }, 46 | theme: { 47 | customCss: require.resolve('./src/css/custom.css'), 48 | }, 49 | }), 50 | ], 51 | ], 52 | 53 | themeConfig: 54 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 55 | ({ 56 | navbar: { 57 | title: 'Lemon', 58 | logo: { 59 | alt: ':lemon:', 60 | src: 'img/favicon.png', 61 | }, 62 | items: [ 63 | { 64 | type: 'doc', 65 | docId: 'table', 66 | position: 'left', 67 | label: 'Docs', 68 | }, 69 | { 70 | type: 'doc', 71 | docId: 'lemon-in-3min', 72 | position: 'left', 73 | label: 'Quick-Start', 74 | }, 75 | { 76 | type: 'doc', 77 | docId: 'tutorial/intro-to-tutorial', 78 | position: 'left', 79 | label: 'Tutorial', 80 | }, 81 | {to: '/blog', label: 'Blog', position: 'left'}, 82 | { 83 | href: 'https://github.com/Sas2k/Lemon', 84 | label: 'GitHub', 85 | position: 'right', 86 | }, 87 | { 88 | type: 'docsVersionDropdown' 89 | }, 90 | ], 91 | }, 92 | footer: { 93 | style: 'dark', 94 | links: [ 95 | { 96 | title: 'Docs', 97 | items: [ 98 | { 99 | label: 'Tutorial', 100 | to: '/docs/lemon-in-3min', 101 | }, 102 | ], 103 | }, 104 | { 105 | title: 'Community', 106 | items: [ 107 | { 108 | label: 'Stack Overflow', 109 | href: 'https://stackoverflow.com/questions/tagged/lemon', 110 | }, 111 | { 112 | label: 'Discord', 113 | href: 'https://discord.gg/wg239Cpf', 114 | } 115 | ], 116 | }, 117 | { 118 | title: 'More', 119 | items: [ 120 | { 121 | label: 'Blog', 122 | to: '/blog', 123 | }, 124 | { 125 | label: 'GitHub', 126 | href: 'https://github.com/Sas2k/Lemon', 127 | }, 128 | ], 129 | }, 130 | ], 131 | copyright: `Copyright © ${new Date().getFullYear()} Lemon, Built with ❤ and Docusaurus.`, 132 | }, 133 | prism: { 134 | theme: lightCodeTheme, 135 | darkTheme: darkCodeTheme, 136 | }, 137 | }), 138 | }; 139 | 140 | module.exports = config; 141 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lemon-docs", 3 | "version": "1.3.6", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "2.1.0", 18 | "@docusaurus/preset-classic": "2.1.0", 19 | "@mdx-js/react": "^1.6.22", 20 | "babel-plugin-prismjs": "^2.1.0", 21 | "clsx": "^1.2.1", 22 | "prism-react-renderer": "^1.3.5", 23 | "react": "^17.0.2", 24 | "react-dom": "^17.0.2" 25 | }, 26 | "devDependencies": { 27 | "@docusaurus/module-type-aliases": "2.1.0" 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.5%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | }, 41 | "engines": { 42 | "node": ">=16.14" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /docs/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], 18 | 19 | // But you can create a sidebar manually 20 | /* 21 | tutorialSidebar: [ 22 | 'intro', 23 | 'hello', 24 | { 25 | type: 'category', 26 | label: 'Tutorial', 27 | items: ['tutorial-basics/create-a-document'], 28 | }, 29 | ], 30 | */ 31 | }; 32 | 33 | module.exports = sidebars; 34 | -------------------------------------------------------------------------------- /docs/src/components/HomePageComponents/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './styles.module.css'; 3 | 4 | function Code({ code }) { 5 | return ( 6 |
     7 |             
     8 |                 {code}
     9 |             
    10 |         
    11 | ); 12 | } 13 | 14 | var component_example = `class MyComponent(Component): 15 | name = "MyComponent" 16 | def item(props: dict): 17 | return f"
    Hello {props['name']}!
    "`; 18 | 19 | var back_and_front_example = `@app.route("/api") 20 | class api: 21 | def get(self, req, res): 22 | res.text = Root.render("") 23 | def post(self, req, res): 24 | name = req.json['name'] 25 | orm.insert('Person', [['Names'], [name]])`; 26 | 27 | function Codeandtext(props) { 28 | return ( 29 | <> 30 |
    31 |
    32 |

    Components made easy.

    33 |

    Components are isolated elements which have their own properties and states

    34 |
    35 | 36 |
    37 |
    38 |
    39 |

    Backend intertwined with Front-end.

    40 |

    the backend is seamlessly connected with the backend, So you can connect to the DB while fixing the UI 🛠

    41 |
    42 | 43 |
    44 | 45 | ); 46 | } 47 | 48 | function TutorialAndLinks(props){ 49 | return ( 50 | <> 51 | 55 | 56 | ); 57 | } 58 | 59 | export default function HomePageComponents(props) { 60 | return ( 61 | <> 62 |
    63 | 64 | 65 |
    66 | 67 | ); 68 | } -------------------------------------------------------------------------------- /docs/src/components/HomePageComponents/styles.module.css: -------------------------------------------------------------------------------- 1 | :root{ 2 | --code-bg: #f5f5f5; 3 | --code-text: #18181b; 4 | --text: #000000; 5 | } 6 | 7 | .codeBlock { 8 | display: flex; 9 | flex-direction: row; 10 | justify-content: center; 11 | align-items: center; 12 | border-radius: 0.5rem; 13 | background-color: var(--code-bg); 14 | color: var(--code-text); 15 | width: 50% fit-content; 16 | margin: auto; 17 | } 18 | 19 | .textBlock{ 20 | display: flex; 21 | flex-direction: column; 22 | justify-content: space-between; 23 | align-items: center; 24 | width: 65%; 25 | height: fit-content; 26 | margin: 10px; 27 | } 28 | 29 | .textBlock h3 { 30 | margin: 0; 31 | font-size: 1.5rem; 32 | font-weight: 700; 33 | color: var(--text); 34 | text-align: center; 35 | } 36 | 37 | .textBlock p { 38 | margin: 0; 39 | font-size: 1.2rem; 40 | line-height: 1.5; 41 | text-align: center; 42 | } 43 | 44 | .yellow_block { 45 | display: flex; 46 | flex-direction: column; 47 | justify-content: center; 48 | align-items: center; 49 | width: 100%; 50 | height: 100%; 51 | padding: 10px; 52 | margin: 0px; 53 | background-color: #cda721; 54 | } 55 | 56 | .green_block{ 57 | display: flex; 58 | flex-direction: column; 59 | justify-content: center; 60 | align-items: center; 61 | padding: 10px; 62 | width: 100%; 63 | height: 100%; 64 | background-color: #569875; 65 | } 66 | 67 | .TutorialLinks { 68 | display: flex; 69 | flex-direction: row; 70 | justify-content: center; 71 | align-items: center; 72 | height: fit-content; 73 | font-size: 1.5rem; 74 | margin: 10px; 75 | padding: 10px; 76 | color: #63b388; 77 | } 78 | 79 | .GetStarted{ 80 | position: relative; 81 | justify-content: center; 82 | align-items: center; 83 | font-size: 1rem; 84 | text-decoration: none; 85 | font-weight: 400; 86 | letter-spacing: 2px; 87 | text-transform: uppercase; 88 | color: black; 89 | padding: 1em; 90 | margin: 1em; 91 | width: fit-content; 92 | border: transparent; 93 | border-radius: 4px; 94 | background-color: yellowgreen; 95 | } -------------------------------------------------------------------------------- /docs/src/components/HomepageFeatures/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import styles from './styles.module.css'; 4 | 5 | const FeatureList = [ 6 | { 7 | title: 'Built In Python', 8 | description: ( 9 | <> 10 | Lemon is written in Python, and is designed like React and Vue. It's easy to learn and use. 11 | 12 | ), 13 | }, 14 | { 15 | title: 'Component Based', 16 | description: ( 17 | <> 18 | Lemon is component based, all of the page is designed in components to render and control the page. 19 | 20 | ), 21 | }, 22 | { 23 | title: 'Full-Stack', 24 | description: ( 25 | <> 26 | Lemon is a full-stack framework, it has a built-in server and database, and it's easy to use. 27 | 28 | ), 29 | } 30 | ]; 31 | 32 | function Feature({title, description}) { 33 | return ( 34 |
    35 |
    36 |

    {title}

    37 |

    {description}

    38 |
    39 |
    40 | ); 41 | } 42 | 43 | export default function HomepageFeatures() { 44 | return ( 45 |
    46 |
    47 |
    48 | {FeatureList.map((props, idx) => ( 49 | 50 | ))} 51 |
    52 |
    53 |
    54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /docs/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /docs/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #2e8555; 10 | --ifm-color-primary-dark: #29784c; 11 | --ifm-color-primary-darker: #277148; 12 | --ifm-color-primary-darkest: #205d3b; 13 | --ifm-color-primary-light: #33925d; 14 | --ifm-color-primary-lighter: #359962; 15 | --ifm-color-primary-lightest: #3cad6e; 16 | --ifm-code-font-size: 95%; 17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 21 | [data-theme='dark'] { 22 | --ifm-color-primary: #25c2a0; 23 | --ifm-color-primary-dark: #21af90; 24 | --ifm-color-primary-darker: #1fa588; 25 | --ifm-color-primary-darkest: #1a8870; 26 | --ifm-color-primary-light: #29d5b0; 27 | --ifm-color-primary-lighter: #32d8b4; 28 | --ifm-color-primary-lightest: #4fddbf; 29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 30 | } 31 | -------------------------------------------------------------------------------- /docs/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import Link from '@docusaurus/Link'; 4 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 5 | import Layout from '@theme/Layout'; 6 | import HomepageFeatures from '@site/src/components/HomepageFeatures'; 7 | import HomePageComponents from '@site/src/components/HomePageComponents'; 8 | 9 | import styles from './index.module.css'; 10 | 11 | function HomepageHeader() { 12 | const {siteConfig} = useDocusaurusContext(); 13 | return ( 14 |
    15 |
    16 |

    {siteConfig.title}

    17 |

    {siteConfig.tagline}

    18 |
    19 | 22 | Lemon Tutorial - 3min ⏱️ 23 | 24 |
    25 |
    26 |
    27 | ); 28 | } 29 | 30 | export default function Home() { 31 | const {siteConfig} = useDocusaurusContext(); 32 | return ( 33 | 36 | 37 |
    38 | 39 | 40 |
    41 |
    42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /docs/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | @media screen and (max-width: 996px) { 14 | .heroBanner { 15 | padding: 2rem; 16 | } 17 | } 18 | 19 | .buttons { 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | -------------------------------------------------------------------------------- /docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/docs/static/img/favicon.png -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/Hello-World.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World! 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon 🍋: Hello-World! 7 | 8 | Hello, in this part. we're going to build a small lemon app. 9 | 10 | ## Getting Started 11 | 12 | first of, let's create a virtual environment. 13 | 14 | ```bash 15 | #with venv 16 | python -m venv venv 17 | 18 | #with virtualenv 19 | python -m virtualenv venv 20 | ``` 21 | 22 | then activate it with the below command. 23 | 24 | ```bash 25 | #windows 26 | .\\venv\\Scripts\\activate 27 | ``` 28 | 29 | after that install Lemon in it. 30 | 31 | ```bash 32 | pip install Lemon-Library 33 | ``` 34 | 35 | ## creating the app 36 | 37 | now in that app create a file called `app.py` 38 | 39 | now in that app paste this code (don't worry I will explain the code). 40 | 41 | ```python 42 | from Lemon.components import Component 43 | from Lemon.Server.server import Server 44 | 45 | app = Server(None) 46 | Root = Component("Home") 47 | 48 | class home(Component): 49 | 50 | name = "home" 51 | 52 | def item(props: dict): 53 | return """ 54 |

    Hello World!

    55 |

    This is generated in Python!

    56 |

    This is in BOLD

    57 |

    This is in ITALICS

    58 | My Github Profile 59 | """ 60 | 61 | Root.add(home) 62 | 63 | @app.route("/") 64 | def student(request, response): 65 | home_page = Root.render("") 66 | response.text = home_page 67 | 68 | app.run() 69 | ``` 70 | 71 | now to run it, just do this. 72 | 73 | `python app.py` 74 | 75 | ## Code Break Down 🥚🍳 76 | 77 | Now let's break the code down. 78 | 79 | in the first 2 lines, it imports the server and the Component Class. (which is the base class to create the components.) 80 | 81 | then we define an `app` variable, which is the server instance. 82 | the `root` variable is the root component where the components are rendered. 83 | 84 | then there is the `Home` Class, which is a component. 85 | 86 | in the component class, there is a `name` variable, which is the variable that says the name of the variable. 87 | 88 | then the `item` function is where the components stuff is there (like the filling of a pie 🥧). 89 | 90 | the `item` function has a `props` dictionary object. Which are the properties of the element. 91 | 92 | For example: ` 93 | 94 | here the `name="Sas2k"` is the prop. 95 | 96 | After that the component is added to the Root with the `Root.add`. 97 | 98 | then their is the usual route function. 99 | 100 | After, their is the `app.run` which runs it. 101 | 102 | And that's basically it. 103 | 104 | _A Lemon app, broken down._ 105 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/lemon-in-3min.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon In 3 minutes 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon in 3 minutes 7 | 8 | Let's try to create a site in **Lemon 🍋**.. 9 | 10 | ## Getting Started 11 | 12 | To get started first install Lemon 🍋 from pip 13 | 14 | ``` 15 | pip install Lemon-Library 16 | ``` 17 | 18 | ## Generate a new site 19 | 20 | to generate a new site run this command 21 | 22 | ``` 23 | create-lemon-app my-website 24 | ``` 25 | 26 | ## Start your site 27 | 28 | Run the development server: 29 | 30 | ```bash 31 | cd my-website 32 | python app.py 33 | ``` 34 | 35 | then visit localhost:5000 36 | 37 | The `cd` command changes the current directory to the website dir, 38 | 39 | next the `python app.py` runs the app. 40 | 41 | Now that you done this, head over to the [tutorial](tutorial/intro-to-tutorial), to create a basic app. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/lemon-vs-react.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon vs React 3 | sidebar_position: 4 4 | --- 5 | # Lemon vs React. 6 | 7 | In this page we're going to talk about the differences of Lemon and React. 8 | 9 | ## TLDR; What is React? 10 | 11 | React is a front-end framework for JavaScript, it's used to build Interactive UIs. ([Website](https://reactjs.org/)) 12 | 13 | **Now let's compare them feature at a time** 14 | 15 | ## Components 16 | 17 | Now let's talk about components, Both of the libraries use Components. 18 | 19 | ### Lemon [Python] (v1.0.0) 20 | 21 | ```python 22 | class HelloMessage(Component): 23 | name = "HelloMessage" 24 | def item(props:dict): 25 | return f"

    Hello! {props['name']}" 26 | 27 | @app.route("/") #don't mind the app.route or the index function there just there to route the sever 28 | def index(request, response): 29 | response.text = root.render("") 30 | ``` 31 | 32 | ### React (JSX) 33 | 34 | ```jsx 35 | class HelloMessage extends React.Component { 36 | render(){ 37 | return

    Hello {this.props.name}; 38 | }; 39 | }; 40 | 41 | root.render() 42 | ``` 43 | 44 | The first one is in Lemon(Python), 45 | The Second one is in React (JSX) 46 | 47 | Here we have a simple component created in both. 48 | Both of them are very similar. Except for the fact that since React uses JSX, you can write HTML directly. 49 | 50 | ## Reactivity 51 | 52 | what reactivity does is when the information, variables change, the render changes automatically. 53 | 54 | here is a To-Do example in both Lemon and React. 55 | 56 | ### Lemon (v1.0.0) 57 | 58 | `app.py` 59 | 60 | ```python 61 | class ToDo(Component): 62 | name = 'ToDo' 63 | def item(props:dict): 64 | return f""" 65 |
    66 | 67 |

    68 |
    69 | """ 70 | 71 | @app.route("/") 72 | def index(request, response): 73 | response.text = root.render("") 74 | ``` 75 | 76 | `public/index.js` 77 | 78 | ```js 79 | let todoitems = () => { 80 | data.message = document.getElementById("Text").value; 81 | }; 82 | 83 | let updateToDo = () => { 84 | document.getElementById("Todo-List").text += data.message + '\n'; 85 | }; 86 | 87 | watcher(updateToDo); 88 | ``` 89 | 90 | ### React 91 | 92 | > taken from homepage example. 93 | 94 | ```jsx 95 | class TodoApp extends React.Component { 96 | constructor(props) { 97 | super(props); 98 | this.state = { items: [], text: '' }; 99 | this.handleChange = this.handleChange.bind(this); 100 | this.handleSubmit = this.handleSubmit.bind(this); 101 | } 102 | 103 | render() { 104 | return ( 105 |
    106 |

    TODO

    107 | 108 |
    109 | 112 | 117 | 120 |
    121 |
    122 | ); 123 | } 124 | 125 | handleChange(e) { 126 | this.setState({ text: e.target.value }); 127 | } 128 | 129 | handleSubmit(e) { 130 | e.preventDefault(); 131 | if (this.state.text.length === 0) { 132 | return; 133 | } 134 | const newItem = { 135 | text: this.state.text, 136 | id: Date.now() 137 | }; 138 | this.setState(state => ({ 139 | items: state.items.concat(newItem), 140 | text: '' 141 | })); 142 | } 143 | } 144 | 145 | class TodoList extends React.Component { 146 | render() { 147 | return ( 148 |
      149 | {this.props.items.map(item => ( 150 |
    • {item.text}
    • 151 | ))} 152 |
    153 | ); 154 | } 155 | } 156 | 157 | root.render(); 158 | ``` 159 | 160 | Here as we can see, for lemon reactivity happens through a function called `watcher` which watched the function and it's variables to change, the `data.message` are the values that would change. 161 | 162 | **And that's about it, for the differences... (I might add more soon...)** -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/table.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Table Of Content 6 | - ## [Table-Of-Content](table) 7 | - ## [Intro](lemon-in-3min) 8 | - ## Tutorial 9 | - ### [Tutorial-Intro](tutorial/intro-to-tutorial) 10 | - ### [Tutorial-Part-1](tutorial/tutorial-part-1) 11 | - ### [Tutorial-Part-2](tutorial/tutorial-part-2) 12 | - ### [Tutorial-Part-3](tutorial/tutorial-part-3) 13 | - ## Differences (Lemon vs [another library]) 14 | - ### [Lemon vs React](lemon-vs-react) 15 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/tutorial/images/blog-page.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/docs/versioned_docs/version-1.0.0/tutorial/images/blog-page.PNG -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/tutorial/intro-to-tutorial.md: -------------------------------------------------------------------------------- 1 | # Intro To Tutorial 2 | 3 | > This tutorial series will think, { that you already installed Lemon-Library and Python } 4 | > AND { that you have sufficient knowledge of Python. } 5 | 6 | > *Still Under Construction 🏗 7 | 8 | Hello!, In this tutorial we are going to build a basic app in Lemon. 9 | So you guys can get the hang of it and learn it. 10 | 11 | ## First of what are we building? 12 | 13 | We're going to build a blog that can be updated through http request. 14 | 15 | So, now that we know what we're building let's get to it!. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/tutorial/tutorial-part-1.md: -------------------------------------------------------------------------------- 1 | # Tutorial Part 1: Setting things up. 2 | 3 | Now, let's set thing up. 4 | 5 | firstly, let's run the usual `create-lemon-app` command to generate the boilerplate code. 6 | 7 | ```cmd 8 | create-lemon-app http-blog 9 | ``` 10 | 11 | ``` 12 | App created @ /http-blog/ 13 | ``` 14 | 15 | then move into it with `cd` 16 | 17 | ```bash 18 | cd http-blog 19 | ``` 20 | 21 | then the directory should look like this. 22 | 23 | ```dir 24 | http-blog/ 25 | - models/ 26 | - model.py 27 | -public/ 28 | - css/ 29 | - style.css 30 | - js/ 31 | - script.js 32 | - app.py 33 | - base.py 34 | - README.md 35 | ``` 36 | 37 | now create a virtual environment 38 | 39 | ```cmd 40 | #with venv 41 | python -m venv venv 42 | 43 | #with virtualenv 44 | pip install virtualenv #if you haven't already installed it before 45 | python -m virtualenv venv 46 | ``` 47 | 48 | After this install `Lemon` 49 | ``` 50 | pip install Lemon-Library 51 | ``` 52 | 53 | then run the `app.py` to see if everything is correct. 54 | 55 | `python app.py` 56 | 57 | if the app is running then visit localhost:8000, to see the app running. 58 | 59 | then press `control + c` to stop. 60 | 61 | now go ahead and delete the `script.js` and `style.css` which is inside the public. (since we don't need it yet.) 62 | 63 | Now go into the app.py 64 | 65 | and replace the file with this. 66 | 67 | ```python 68 | from Lemon.components import Component 69 | from Lemon.Server.server import Server 70 | 71 | Root = Component("Lemon") 72 | app = Server(static_dir="public") 73 | 74 | class App(Component): 75 | name = "App" 76 | def item(props: dict): 77 | return "Hello World" 78 | 79 | Root.add( 80 | [ 81 | App 82 | ] 83 | ) 84 | 85 | @app.route("/") 86 | def home(request, response): 87 | response.text = Root.render('') 88 | 89 | app.run() 90 | 91 | ``` 92 | 93 | Here, we have removed everything unnecessary from the app. 94 | (We kept the app component since, it will be the main component.) 95 | 96 | now if you run it. 97 | 98 | you will just see a Hello World text on the browser. 99 | 100 | Now the files are prepped and ready to write the code. 101 | 102 | Go to Part II. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/tutorial/tutorial-part-2.md: -------------------------------------------------------------------------------- 1 | # Tutorial Part 2: Writing the basic components. 2 | 3 | now, let's create a directory(which is a fancy term for a folder.) and name it `Components` 4 | 5 | in this folder we're going to create a folder called `components.py` 6 | 7 | now we're going to write a basic component which has the title, the body and the author. 8 | 9 | > Now before we write anything let me quickly give you the structure of a component. 10 | > ```python 11 | > class thing(Component): 12 | > name = "thing" # the name here will the name going to be used in `root.render()` 13 | > def item(props: dict): 14 | > return "

    THING

    " # the item function is where the html code is presented. 15 | > ``` 16 | 17 | now firstly we need to import the `Component` class, which is the base class. 18 | ```python 19 | from Lemon.components import Component 20 | ``` 21 | 22 | then let's write a basic post component 23 | 24 | ```python 25 | class BlogPost(Component): 26 | name = "BlogPost" 27 | 28 | def item(props: dict): 29 | return f""" 30 |
    31 |

    {props['title']}

    32 |

    By {props['author']}

    33 |
    34 |

    {props['body']}

    35 |
    36 | """ 37 | ``` 38 | 39 | (you can change it however you like.) 40 | 41 | now in the `app.py` file import it like this. 42 | `from Components.components import BlogPost` 43 | 44 | then change the Root.add function like this, 45 | 46 | ```python 47 | Root.add( 48 | [ 49 | App, 50 | BlogPost 51 | ] 52 | ) 53 | ``` 54 | 55 | now you can test it out by removing the "Hello World" from the App components `item` function, and adding the `BlogPost` one. 56 | 57 | `` 58 | 59 | (above is an example) 60 | 61 | Now if you run it, you should see something like below. 62 | 63 | ----------------------------- 64 | 65 | ## Hello World 66 | ### Your-Name 67 | Lorem Ispum Dorem Almet why is this used everywhere? 68 | 69 | ----------------------------- 70 | 71 | Now, that the component is created an working let's move onto part 3. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/tutorial/tutorial-part-3.md: -------------------------------------------------------------------------------- 1 | # Tutorial Part 3: Building the api. 2 | 3 | Now that we got the basic front-end down. 4 | 5 | We now have to focus on the back-end, which is the API. 6 | 7 | let's start of by creating a routes called /api/get and /api/post 8 | 9 | so the basic decorator to create the route is. 10 | 11 | ```python 12 | @app.route("/route") 13 | def route(request, response): 14 | response.text = "route" 15 | ``` 16 | 17 | now since /api/get is uses a `GET` method we can just make it a normal route. 18 | 19 | ```python 20 | @app.route("/api/get/{post_id:d}") # the {post_id} is an argument in the url. the d means digit. 21 | def api_get(request, response, post_id): 22 | #for now let's just return the post_id 23 | response.json = { "post_id": post_id } 24 | ``` 25 | 26 | now for the /api/post we have to use a class for this. 27 | 28 | ```python 29 | @app.route('/app/post/') 30 | class api_post(): 31 | def get(self, req, res): 32 | res.text = "method not allowed" 33 | def post(self, req, res): 34 | print(req.json) 35 | ``` 36 | 37 | here the body of the request is printed. 38 | now the basic api is implemented let's move to part 4. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/tutorial/tutorial-part-4.md: -------------------------------------------------------------------------------- 1 | # Tutorial Part 4: Storing the requests and Displaying them as Posts 2 | 3 | In this part, we're going to store the requests, and then we're going to display them. as pages. 4 | 5 | To store them, we're going to create a `posts` list. 6 | 7 | ```python 8 | posts = [{"title": "Hello World", "author": "Lemon", "body": "This is a test post"}] 9 | ``` 10 | 11 | now let's change the return of the item function in the App Component to this, 12 | 13 | ```python 14 | return f"" 15 | ``` 16 | 17 | also let's change the "/" route to "/{post_id}" and add these. 18 | 19 | ```python 20 | @app.route("/{post_id}") 21 | def home(request, response, post_id): 22 | if post_id.isdigit(): 23 | try: 24 | post = posts[int(post_id)-1] 25 | response.text = Root.render(f'') 26 | except IndexError: 27 | response.status_code = 404 28 | response.text = "

    Post not found

    " 29 | else: 30 | response.text = "

    This id should be an integer, Not String

    " 31 | ``` 32 | 33 | also remember the API routes, let's change them like this. 34 | 35 | ```python 36 | @app.route("/api/get/{post_id}") # the {id} is an argument in the url. 37 | def api_get(request, response, post_id): 38 | #for now let's just return the post_id 39 | response.text = posts[post_id] 40 | 41 | @app.route('/api/post/') 42 | class api_post(): 43 | def get(self, req, res): 44 | res.text = "method not allowed" 45 | def post(self, req, res): 46 | json = req.json 47 | if json["title"] and json["body"] and json["author"] and json["id"]: 48 | post_id = int(json["id"]) 49 | if post_id not in posts: 50 | posts[post_id] = json 51 | res.text = "success" 52 | else: 53 | posts.append(json) 54 | res.text = "success" 55 | else: 56 | res.text = "failed" 57 | ``` 58 | 59 | And now run, the app. 60 | 61 | Try going to. https://localhost:8000/1 62 | 63 | and you should see the Test Post. 64 | 65 | you can create a your own posts by sending post requests to `/api/post` 66 | 67 | here is an example body 68 | 69 | ```json 70 | { 71 | "title": "Hello World", 72 | "author": "Sas2k", 73 | "body": "Lorem Ispum Dorem Alamet" 74 | } 75 | ``` 76 | 77 | And that's about it. 78 | 79 | We've created a fully functioning App in Lemon. 80 | 81 | Now let's move to part 5, to style the blog. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.0.0/tutorial/tutorial-part-5.md: -------------------------------------------------------------------------------- 1 | # Tutorial Part 5: Styling the blog and finalizing. 2 | 3 | In this part we're going to style the posts. 4 | 5 | Now let's delete the `JS` folder, but let's keep the `CSS` Folder. 6 | 7 | Now let's create a `style.css`. 8 | 9 | Add this CSS code to style it. 10 | 11 | ```css 12 | * { 13 | font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; 14 | font-size: 1.2rem; 15 | color: #333; 16 | line-height: 1.5; 17 | margin: 0; 18 | padding: 0; 19 | box-sizing: border-box; 20 | } 21 | 22 | body { 23 | background: #ffffff; 24 | } 25 | 26 | h1 { 27 | font-size: 3rem; 28 | line-height: 1.2; 29 | margin-bottom: 1rem; 30 | } 31 | 32 | h2 { 33 | font-size: 2rem; 34 | margin-bottom: 1rem; 35 | } 36 | 37 | h3 { 38 | font-size: 1.5rem; 39 | margin-bottom: 1rem; 40 | color: #ffa; 41 | } 42 | 43 | p { 44 | margin-bottom: 1rem; 45 | } 46 | ``` 47 | 48 | now in the `app.py` file let's change the `Root`, to add the CSS file. 49 | 50 | ```python 51 | Root = Component("HTTP-Blog", stylesheet="public/css/style.css") 52 | ``` 53 | 54 | Now run the app and see the page now. 55 | 56 | ![blog-output](images/blog-page.PNG) 57 | 58 | And that's about it. 59 | 60 | A fully functioning app in Lemon 🍋. 61 | 62 | Github: https://github.com/Sas2k/HTTP-Blog -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/Hello-World.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World! 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon 🍋: Hello-World! 7 | 8 | Hello, in this part. we're going to build a small lemon app. 9 | 10 | ## Getting Started 11 | 12 | first of, let's create a virtual environment. 13 | 14 | ```bash 15 | #with venv 16 | python -m venv venv 17 | 18 | #with virtualenv 19 | python -m virtualenv venv 20 | ``` 21 | 22 | then activate it with the below command. 23 | 24 | ```bash 25 | #windows 26 | .\\venv\\Scripts\\activate 27 | ``` 28 | 29 | after that install Lemon in it. 30 | 31 | ```bash 32 | pip install Lemon-Library 33 | ``` 34 | 35 | ## creating the app 36 | 37 | now in that app create a file called `app.py` 38 | 39 | now in that app paste this code (don't worry I will explain the code). 40 | 41 | ```python 42 | from Lemon.components import Component 43 | from Lemon.Server.server import Server 44 | 45 | app = Server(None) 46 | Root = Component("Home") 47 | 48 | class home(Component): 49 | 50 | name = "home" 51 | 52 | def item(props: dict): 53 | return """ 54 |

    Hello World!

    55 |

    This is generated in Python!

    56 |

    This is in BOLD

    57 |

    This is in ITALICS

    58 | My Github Profile 59 | """ 60 | 61 | Root.add(home) 62 | 63 | @app.route("/") 64 | def student(request, response): 65 | home_page = Root.render("") 66 | response.text = home_page 67 | 68 | app.run() 69 | ``` 70 | 71 | now to run it, just do this. 72 | 73 | `python app.py` 74 | 75 | ## Code Break Down 🥚🍳 76 | 77 | Now let's break the code down. 78 | 79 | in the first 2 lines, it imports the server and the Component Class. (which is the base class to create the components.) 80 | 81 | then we define an `app` variable, which is the server instance. 82 | the `root` variable is the root component where the components are rendered. 83 | 84 | then there is the `Home` Class, which is a component. 85 | 86 | in the component class, there is a `name` variable, which is the variable that says the name of the variable. 87 | 88 | then the `item` function is where the components stuff is there (like the filling of a pie 🥧). 89 | 90 | the `item` function has a `props` dictionary object. Which are the properties of the element. 91 | 92 | For example: ` 93 | 94 | here the `name="Sas2k"` is the prop. 95 | 96 | After that the component is added to the Root with the `Root.add`. 97 | 98 | then their is the usual route function. 99 | 100 | After, their is the `app.run` which runs it. 101 | 102 | And that's basically it. 103 | 104 | _A Lemon app, broken down._ 105 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/api-reference/Lemon-Server-middleware.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server.middleware 3 | sidebar_position: 4 4 | --- 5 | 6 | # Lemon.Server.middleware 7 | 8 | The middleware module 9 | 10 | ```python 11 | 1 | from Lemon.components import Component 12 | 2 | from Lemon.Server import server, middleware 13 | 3 | 14 | 4 | app = server.Server(None) 15 | 5 | 16 | 6 | class middleware_example(middleware): 17 | 7 | def process_request(self, req): 18 | 8 | print("Despatching ->", req.url) 19 | 9 | 20 | 10| def process_response(self, req, res): 21 | 11| print("Despatched", req.url) 22 | 12| 23 | 13|app.add_middleware(middleware_example) 24 | ``` 25 | 26 | ## Middleware [Class] | (self, app) 27 | 28 | The middleware base class 29 | 30 | ### Attributes, Properties and Functions 31 | 32 | #### add [Function] | (self, middleware_cls) < Developer-Function > 33 | 34 | Adds a middleware. 35 | 36 | #### process_request [Function] | (self, req) 37 | 38 | Process's the middleware's requests 39 | 40 | > line 6~8 on example 41 | 42 | #### process_response [Function] | (self, req) 43 | 44 | Process's the middleware before sending back the response 45 | 46 | > line 10~11 on example 47 | 48 | #### handle_request [Function] | (self, req, res) < Developer-Function > 49 | 50 | Handles Request that the class receives. 51 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/api-reference/Lemon-Server-server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server.server 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon.Server.server 7 | 8 | The server, the main backend. (which contains routes and etc..) 9 | 10 | ## Server [Class] | (self, static_dir="public") 11 | 12 | The Server Methods 13 | 14 | ```python 15 | from Lemon.Server import server 16 | 17 | app = server.Server(None) #place None here if you don't have any static files. 18 | ``` 19 | 20 | ### Attributes, Properties and Functions 21 | 22 | #### wsgi_app [Function] | (self, environ, start_response) | < Developer-Function > 23 | 24 | returns a response with environ. 25 | 26 | #### add_route [Function] | (self, path, handler) 27 | 28 | This function adds route django style!. 29 | 30 | ```python 31 | def index(request, response): 32 | response.text = "Hello World!" 33 | 34 | app.add_route("/", index) 35 | ``` 36 | 37 | #### add_exception_handler [Function] | (self, exception_handler) 38 | 39 | Adds a sever exception handler. 40 | 41 | ```python 42 | def custom_exception_handler(request, response, exception_cls): 43 | response.text = "Oops!, Something went wrong!" 44 | 45 | app.add_exception_handler(custom_exception_handler) 46 | ``` 47 | 48 | #### route [Decorator(Function)] | (self, path) 49 | 50 | the route decorator. 51 | 52 | ```python 53 | #Function Based Handler 54 | @app.route("/") 55 | def index(request, response): 56 | request.text = "Hello World" 57 | 58 | #Class Based Handler 59 | @app.route("/") 60 | class Index(): 61 | def get(self, req, res): 62 | res.text = "Hello World" 63 | 64 | def post(self, req, res): 65 | res.text = req.json 66 | ``` 67 | 68 | #### handle_request [Function] | (self, request) | < Developer-Function > 69 | 70 | Handles incoming requests. 71 | 72 | #### add_cookie [Function] | (self, response, key, value, max_age=None, expires=None, path="/", domain=None, Secure=False, httponly=False, samesite=None) 73 | 74 | Creates a cookie 🍪 75 | 76 | ```python 77 | @app.route("/") 78 | def index(request, response): 79 | add_cookie(response, "Hello", "world") 80 | ``` 81 | 82 | #### delete_cookie [Function] | (self, response, key, path="/", domain=None) 83 | 84 | Deletes a cookie 🍪🤏🏽 85 | 86 | ```python 87 | @app.route("/") 88 | def index(request, response): 89 | delete_cookie(response, "Hello") 90 | ``` 91 | 92 | #### get_cookie [Function] | (self, request, key) 93 | 94 | Gets a cookie 📦 95 | 96 | ```python 97 | @app.route("/") 98 | def index(request, response): 99 | get_cookie(request, "Hello") 100 | ``` 101 | 102 | #### add_middleware [Function] | (self, middleware_cls) 103 | 104 | Adds a middleware to run. 105 | 106 | ```python 107 | app.add_middleware(PrintMiddleWare) # <- Fake name "PrintMiddleWare" 108 | ``` 109 | 110 | #### test_session [Function] | (self, base_url="http://testserver") < Developer-Function > 111 | 112 | The testing session used in tests. 113 | 114 | #### run [Function] | (self, host="127.0.0.1", post=8000) 115 | 116 | Runs the app. 117 | 118 | ```python 119 | app.run(port=5000) 120 | ``` 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/api-reference/Lemon-Server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon.Server 7 | 8 | The module containing the middleware and server functions. 9 | 10 | ## [Lemon.Server.server](Lemon-Server-server) 11 | ## [Lemon.Server.middleware](Lemon-Server-middleware) -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/api-reference/Lemon-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.components 3 | sidebar_position: 1 4 | --- 5 | 6 | # Lemon.components 7 | 8 | The module responsible for initializing and creating components. 9 | 10 | ## Component [Class] | (self, name, stylesheet=None, script=None) 11 | 12 | The base component class 13 | 14 | ```python 15 | class TestComponent(Component): 16 | name = "TestComponent" 17 | 18 | def item(props: dict): 19 | return """ 20 |

    Hello World!

    21 |

    Lorem ispum

    22 | """ 23 | ``` 24 | 25 | > When naming Components, Always make the first letter Capital as if your writing names. 26 | 27 | ### Attributes, Properties and Functions 28 | 29 | #### add [Function] | (self, components: list or object) 30 | 31 | Adds a component(s) to a list. to parse. 32 | 33 | ```python 34 | Root.add( 35 | [ 36 | Component, 37 | Testing, 38 | WarningComponent 39 | ] 40 | ) 41 | ``` 42 | 43 | #### parse [Function] | (self, Root, prop: list) | < Developer-Function > 44 | 45 | The function that parses the string. 46 | 47 | #### render [Function] | (self, app: str) 48 | 49 | The function that will render the component 50 | 51 | ```python 52 | response.text = Root.render("") 53 | ``` 54 | 55 | #### item [Function] | (self, props: dict) 56 | 57 | The function where the components html/elements are present 58 | 59 | ```python 60 | # must be inside your component class. 61 | def item(props: dict): 62 | return f""" 63 |

    {props['title']}

    64 |

    {props['body']}

    65 | """ 66 | ``` 67 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/api-reference/Lemon-orm-DBManager.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm.DBManager 3 | sidebar_position: 6 4 | --- 5 | 6 | # Lemon.orm.DBManager 7 | 8 | The Database Manager 9 | 10 | ## SQLConnectionManager [Class] | (self, filename) < Developer-Class > 11 | 12 | The SQLConnectionManager used in migrations 13 | 14 | ### Attributes, Properties and Functions 15 | 16 | #### commit [Decorator(Functions)] | (operation) 17 | 18 | Commits a query. 19 | 20 | #### create_table [Function] | (self, tablename, fields) 21 | 22 | creates a table 23 | 24 | #### show_tables [Property(Function)] | (self) 25 | 26 | shows the tables in the database 27 | 28 | ## SqliteManager [Class] | (self, filename) 29 | 30 | The SQLite Manager. 31 | 32 | ```python 33 | from Lemon.orm.DBManager import SqliteManager 34 | 35 | sql = SqliteManager("model.db") 36 | 37 | sql.select("authors", ["name", "age"]) 38 | 39 | sql.insert("authors", ["Paul", "age"], ["Paul", "25"]) 40 | 41 | ``` 42 | 43 | ### commit [Decorator(function)] | (operation) < Developer-Function > 44 | 45 | Commits the query. 46 | 47 | ### create_table [Function] | (self, tablename, columns) 48 | 49 | Creates a table in the Database. 50 | 51 | ```python 52 | sql = SqliteManager("model.db") 53 | 54 | sql.create_table("authors", ["name", "age"]) 55 | ``` 56 | 57 | ### insert [Function] | (self, tablename, columns, values) 58 | 59 | inserts data to columns 60 | 61 | ```python 62 | sql = SqliteManager("model.db") 63 | 64 | sql.insert("authors", ["name", "age"], ["Paul", "25"]) 65 | ``` 66 | 67 | ### select [Function] | (self, tablename, columns) 68 | 69 | selects columns from the table. 70 | 71 | 72 | ```python 73 | sql = SqliteManager("model.db") 74 | 75 | sql.select("authors", ["name", "age"]) 76 | ``` 77 | 78 | ### delete [Function] | (self, tablename, conditions, logic="AND") 79 | 80 | Deletes a record from the table which matches the condition. 81 | 82 | ```python 83 | sql = SqliteManager("model.db") 84 | 85 | sql.delete("authors", ["name='paul'", "age=25"], "AND") 86 | ``` 87 | 88 | ### update [Function] | (self, tablename, columns, values) 89 | 90 | Update values in the Database. 91 | 92 | ```python 93 | sql = SqliteManager("model.db") 94 | 95 | sql.update("authors", ["name", "age"], ["Paul", "22"]) 96 | ``` 97 | 98 | ## base [Class] | (self) 99 | 100 | The Base Class to be inherited. 101 | 102 | ## baseModel [Class] | (self) 103 | 104 | The Base Model to be inherited 105 | 106 | ## MetaModel [Class] | (self) < Developer-Class > 107 | 108 | The MetaModel Class 109 | 110 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/api-reference/Lemon-orm-migrations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm.migrations 3 | sidebar_position: 7 4 | --- 5 | 6 | # Lemon.orm.migrations 7 | 8 | The migrations manager 9 | 10 | ```python 11 | from Lemon.orm import DBManager, migrations 12 | 13 | baseModel = DBManager.baseModel 14 | ClassBase = DBManager.base 15 | migrate = migrations.MigrateCommand 16 | 17 | class model(baseModel): 18 | base_model = ClassBase 19 | tablename = "model" 20 | fields = ("field1", "field2") 21 | 22 | model_list = [model] 23 | 24 | migrate(model_list).migrate() 25 | ``` 26 | 27 | ## Migrate [Class] | (self, model_list) < Developer-Class > 28 | 29 | The migrate command for the Lemon ORM 30 | 31 | ### Attributes, Properties and Functions 32 | 33 | #### migrate [Function] | (self) 34 | 35 | migrates the models to a Database. 36 | 37 | ## MigrateCommand [Function] | (model_list) 38 | 39 | The base function for the migrate function. 40 | 41 | ## Attributes, Properties and Functions 42 | 43 | #### migrate [Function] | (self) 44 | 45 | The migrate function which is used in base.py 46 | 47 | ```python 48 | model_list = [model] 49 | 50 | migrate(model_list).migrate() 51 | ``` -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/api-reference/Lemon-orm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm 3 | sidebar_position: 5 4 | --- 5 | 6 | # Lemon.orm 7 | 8 | the module containing the ORM. 9 | 10 | ## [Lemon.orm.DBManager](Lemon-orm-DBManager) 11 | ## [Lemon.orm.migrations](Lemon-orm-migrations) -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/lemon-in-3min.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon In 3 minutes 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon in 3 minutes 7 | 8 | Let's try to create a site in **Lemon 🍋**.. 9 | 10 | ## Getting Started 11 | 12 | To get started first install Lemon 🍋 from pip 13 | 14 | ``` 15 | pip install Lemon-Library 16 | ``` 17 | 18 | ## Generate a new site 19 | 20 | to generate a new site run this command 21 | 22 | ``` 23 | create-lemon-app my-website 24 | ``` 25 | 26 | ## Start your site 27 | 28 | Run the development server: 29 | 30 | ```bash 31 | cd my-website 32 | python app.py 33 | ``` 34 | 35 | then visit localhost:5000 36 | 37 | The `cd` command changes the current directory to the website dir, 38 | 39 | next the `python app.py` runs the app. 40 | 41 | Now that you done this, head over to the [tutorial](tutorial/intro-to-tutorial), to create a basic app. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/lemon-vs-react.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon vs React 3 | sidebar_position: 4 4 | --- 5 | # Lemon vs React. 6 | 7 | In this page we're going to talk about the differences of Lemon and React. 8 | 9 | ## TLDR; What is React? 10 | 11 | React is a front-end framework for JavaScript, it's used to build Interactive UIs. ([Website](https://reactjs.org/)) 12 | 13 | **Now let's compare them feature at a time** 14 | 15 | ## Components 16 | 17 | Now let's talk about components, Both of the libraries use Components. 18 | 19 | ### Lemon [Python] (v1.0.0) 20 | 21 | ```python 22 | class HelloMessage(Component): 23 | name = "HelloMessage" 24 | def item(props:dict): 25 | return f"

    Hello! {props['name']}" 26 | 27 | @app.route("/") #don't mind the app.route or the index function there just there to route the sever 28 | def index(request, response): 29 | response.text = root.render("") 30 | ``` 31 | 32 | ### React (JSX) 33 | 34 | ```jsx 35 | function HelloMessage(props){ 36 | return

    Hello {props.name}
    ; 37 | }; 38 | 39 | root.render() 40 | ``` 41 | 42 | The first one is in Lemon(Python), 43 | The Second one is in React (JSX) 44 | 45 | Here we have a simple component created in both. 46 | Both of them are very similar. Except for the fact that since React uses JSX, you can write HTML directly. 47 | 48 | ## Reactivity 49 | 50 | what reactivity does is when the information, variables change, the render changes automatically. 51 | 52 | here is a To-Do example in both Lemon and React. 53 | 54 | ### Lemon (v1.0.0) 55 | 56 | `app.py` 57 | 58 | ```python 59 | class ToDo(Component): 60 | name = 'ToDo' 61 | def item(props:dict): 62 | return f""" 63 |
    64 |
      65 |
    66 | 67 |
    68 | """ 69 | 70 | @app.route("/") 71 | def index(request, response): 72 | response.text = root.render("") 73 | ``` 74 | 75 | `public/index.js` 76 | 77 | ```js 78 | let todoitems = () => { 79 | data.message = document.getElementById("Text").value; 80 | }; 81 | 82 | let updateToDo = () => { 83 | document.getElementById("Todo-List").appendChild('
  • ' + data.message + '
  • \n'); 84 | }; 85 | 86 | watcher(updateToDo); 87 | ``` 88 | 89 | ### React 90 | 91 | > taken from homepage example. 92 | 93 | ```jsx 94 | class TodoApp extends React.Component { 95 | constructor(props) { 96 | super(props); 97 | this.state = { items: [], text: '' }; 98 | this.handleChange = this.handleChange.bind(this); 99 | this.handleSubmit = this.handleSubmit.bind(this); 100 | } 101 | 102 | render() { 103 | return ( 104 |
    105 |

    TODO

    106 | 107 |
    108 | 111 | 116 | 119 |
    120 |
    121 | ); 122 | } 123 | 124 | handleChange(e) { 125 | this.setState({ text: e.target.value }); 126 | } 127 | 128 | handleSubmit(e) { 129 | e.preventDefault(); 130 | if (this.state.text.length === 0) { 131 | return; 132 | } 133 | const newItem = { 134 | text: this.state.text, 135 | id: Date.now() 136 | }; 137 | this.setState(state => ({ 138 | items: state.items.concat(newItem), 139 | text: '' 140 | })); 141 | } 142 | } 143 | 144 | class TodoList extends React.Component { 145 | render() { 146 | return ( 147 |
      148 | {this.props.items.map(item => ( 149 |
    • {item.text}
    • 150 | ))} 151 |
    152 | ); 153 | } 154 | } 155 | 156 | root.render(); 157 | ``` 158 | 159 | Here as we can see, for lemon reactivity happens through a function called `watcher` which watched the function and it's variables to change, the `data.message` are the values that would change. 160 | 161 | **And that's about it, for the differences... (I might add more soon...)** -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/table.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Table Of Contents 6 | - ## [Table-Of-Contents](table) 7 | - ## [Intro](lemon-in-3min) 8 | - ## Tutorial 9 | - ### [Intro](tutorial/intro-to-tutorial) 10 | - ### [Part-1](tutorial/tutorial-part-1) 11 | - ### [Part-2](tutorial/tutorial-part-2) 12 | - ### [Part-3](tutorial/tutorial-part-3) 13 | - ### [Part-4](tutorial/tutorial-part-4) 14 | - ### [Part-5](tutorial/tutorial-part-5) 15 | - ## Differences (Lemon vs [another library]) 16 | - ### [Lemon vs React](lemon-vs-react) 17 | - ## API Reference (Library Reference) 18 | - ### [Lemon.Components](api-reference/Lemon-Components) 19 | - ### [Lemon.Server](api-reference/Lemon-Server) 20 | - ### [Lemon.Server.server](api-reference/Lemon-Server-server) 21 | - ### [Lemon.Server.middleware](api-reference/Lemon-Server-middleware) 22 | - ### [Lemon.orm](api-reference/Lemon-orm) 23 | - ### [Lemon.orm.DBManager](api-reference/Lemon-orm-DBManager) 24 | - ### [Lemon.orm.migrations](api-reference/Lemon-orm-migrations) 25 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/tutorial/images/blog-page.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/docs/versioned_docs/version-1.3.0/tutorial/images/blog-page.PNG -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/tutorial/intro-to-tutorial.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | > This tutorial series will think, { that you already installed Lemon-Library and Python } 4 | > AND { that you have sufficient knowledge of Python. } 5 | 6 | Hello!, In this tutorial we are going to build a basic app in Lemon. 7 | So you guys can get the hang of it and learn it. 8 | 9 | ## What will be building? 10 | 11 | We're going to build a blog that can be updated through http request. 12 | 13 | So, now that we know what we're building let's get to it!. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/tutorial/tutorial-part-1.md: -------------------------------------------------------------------------------- 1 | # Part 1: Setting things up. 2 | 3 | Now, let's set thing up. 4 | 5 | firstly, let's run the usual `create-lemon-app` command to generate the boilerplate code. 6 | 7 | ```cmd 8 | create-lemon-app http-blog 9 | ``` 10 | 11 | ``` 12 | App created @ /http-blog/ 13 | ``` 14 | 15 | then move into it with `cd` 16 | 17 | ```bash 18 | cd http-blog 19 | ``` 20 | 21 | then the directory should look like this. 22 | 23 | ```dir 24 | http-blog/ 25 | - models/ 26 | - model.py 27 | -public/ 28 | - css/ 29 | - style.css 30 | - js/ 31 | - script.js 32 | - app.py 33 | - base.py 34 | - README.md 35 | ``` 36 | 37 | now create a virtual environment 38 | 39 | ```cmd 40 | #with venv 41 | python -m venv venv 42 | 43 | #with virtualenv 44 | pip install virtualenv #if you haven't already installed it before 45 | python -m virtualenv venv 46 | ``` 47 | 48 | After this install `Lemon` 49 | ``` 50 | pip install Lemon-Library 51 | ``` 52 | 53 | then run the `app.py` to see if everything is correct. 54 | 55 | `python app.py` 56 | 57 | if the app is running then visit localhost:8000, to see the app running. 58 | 59 | then press `control + c` to stop. 60 | 61 | now go ahead and delete the `script.js` and `style.css` which is inside the public. (since we don't need it yet.) 62 | 63 | Now go into the app.py 64 | 65 | and replace the file with this. 66 | 67 | ```python 68 | from Lemon.components import Component 69 | from Lemon.Server.server import Server 70 | 71 | Root = Component("Lemon") 72 | app = Server(static_dir="public") 73 | 74 | class App(Component): 75 | name = "App" 76 | def item(props: dict): 77 | return "Hello World" 78 | 79 | Root.add( 80 | [ 81 | App 82 | ] 83 | ) 84 | 85 | @app.route("/") 86 | def home(request, response): 87 | response.text = Root.render('') 88 | 89 | app.run() 90 | 91 | ``` 92 | 93 | Here, we have removed everything unnecessary from the app. 94 | (We kept the app component since, it will be the main component.) 95 | 96 | now if you run it. 97 | 98 | you will just see a Hello World text on the browser. 99 | 100 | Now the files are prepped and ready to write the code. 101 | 102 | Go to Part II. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/tutorial/tutorial-part-2.md: -------------------------------------------------------------------------------- 1 | # Part 2: Writing the basic components. 2 | 3 | now, let's create a directory(which is a fancy term for a folder.) and name it `Components` 4 | 5 | in this folder we're going to create a folder called `components.py` 6 | 7 | now we're going to write a basic component which has the title, the body and the author. 8 | 9 | > Now before we write anything let me quickly give you the structure of a component. 10 | > ```python 11 | > class thing(Component): 12 | > name = "thing" # the name here will the name going to be used in `root.render()` 13 | > def item(props: dict): 14 | > return "

    THING

    " # the item function is where the html code is presented. 15 | > ``` 16 | 17 | now firstly we need to import the `Component` class, which is the base class. 18 | ```python 19 | from Lemon.components import Component 20 | ``` 21 | 22 | then let's write a basic post component 23 | 24 | ```python 25 | class BlogPost(Component): 26 | name = "BlogPost" 27 | 28 | def item(props: dict): 29 | return f""" 30 |
    31 |

    {props['title']}

    32 |

    By {props['author']}

    33 |
    34 |

    {props['body']}

    35 |
    36 | """ 37 | ``` 38 | 39 | (you can change it however you like.) 40 | 41 | now in the `app.py` file import it like this. 42 | `from Components.components import BlogPost` 43 | 44 | then change the Root.add function like this, 45 | 46 | ```python 47 | Root.add( 48 | [ 49 | App, 50 | BlogPost 51 | ] 52 | ) 53 | ``` 54 | 55 | now you can test it out by removing the "Hello World" from the App components `item` function, and adding the `BlogPost` one. 56 | 57 | `` 58 | 59 | (above is an example) 60 | 61 | Now if you run it, you should see something like below. 62 | 63 | ----------------------------- 64 | 65 | ## Hello World 66 | ### Your-Name 67 | Lorem Ispum Dorem Almet why is this used everywhere? 68 | 69 | ----------------------------- 70 | 71 | Now, that the component is created an working let's move onto part 3. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/tutorial/tutorial-part-3.md: -------------------------------------------------------------------------------- 1 | # Part 3: Building the api. 2 | 3 | Now that we got the basic front-end down. 4 | 5 | We now have to focus on the back-end, which is the API. 6 | 7 | let's start of by creating a routes called /api/get and /api/post 8 | 9 | so the basic decorator to create the route is. 10 | 11 | ```python 12 | @app.route("/route") 13 | def route(request, response): 14 | response.text = "route" 15 | ``` 16 | 17 | now since /api/get is uses a `GET` method we can just make it a normal route. 18 | 19 | ```python 20 | @app.route("/api/get/{post_id:d}") # the {post_id} is an argument in the url. the d means digit. 21 | def api_get(request, response, post_id): 22 | #for now let's just return the post_id 23 | response.json = { "post_id": post_id } 24 | ``` 25 | 26 | now for the /api/post we have to use a class for this. 27 | 28 | ```python 29 | @app.route('/app/post/') 30 | class api_post(): 31 | def get(self, req, res): 32 | res.text = "method not allowed" 33 | def post(self, req, res): 34 | print(req.json) 35 | ``` 36 | 37 | here the body of the request is printed. 38 | now the basic api is implemented let's move to part 4. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/tutorial/tutorial-part-4.md: -------------------------------------------------------------------------------- 1 | # Part 4: Storing the requests and Displaying them as Posts 2 | 3 | In this part, we're going to store the requests, and then we're going to display them. as pages. 4 | 5 | To store them, we're going to create a `posts` list. 6 | 7 | ```python 8 | posts = [{"title": "Hello World", "author": "Lemon", "body": "This is a test post"}] 9 | ``` 10 | 11 | now let's change the return of the item function in the App Component to this, 12 | 13 | ```python 14 | return f"" 15 | ``` 16 | 17 | also let's change the "/" route to "/{post_id}" and add these. 18 | 19 | ```python 20 | @app.route("/{post_id}") 21 | def home(request, response, post_id): 22 | if post_id.isdigit(): 23 | try: 24 | post = posts[int(post_id)-1] 25 | response.text = Root.render(f'') 26 | except IndexError: 27 | response.status_code = 404 28 | response.text = "

    Post not found

    " 29 | else: 30 | response.text = "

    This id should be an integer, Not String

    " 31 | ``` 32 | 33 | also remember the API routes, let's change them like this. 34 | 35 | ```python 36 | @app.route("/api/get/{post_id}") # the {id} is an argument in the url. 37 | def api_get(request, response, post_id): 38 | #for now let's just return the post_id 39 | response.text = posts[post_id] 40 | 41 | @app.route('/api/post/') 42 | class api_post(): 43 | def get(self, req, res): 44 | res.text = "method not allowed" 45 | def post(self, req, res): 46 | json = req.json 47 | if json["title"] and json["body"] and json["author"] and json["id"]: 48 | post_id = int(json["id"]) 49 | if post_id not in posts: 50 | posts[post_id] = json 51 | res.text = "success" 52 | else: 53 | posts.append(json) 54 | res.text = "success" 55 | else: 56 | res.text = "failed" 57 | ``` 58 | 59 | And now run, the app. 60 | 61 | Try going to. https://localhost:8000/1 62 | 63 | and you should see the Test Post. 64 | 65 | you can create a your own posts by sending post requests to `/api/post` 66 | 67 | here is an example body 68 | 69 | ```json 70 | { 71 | "title": "Hello World", 72 | "author": "Sas2k", 73 | "body": "Lorem Ispum Dorem Alamet" 74 | } 75 | ``` 76 | 77 | And that's about it. 78 | 79 | We've created a fully functioning App in Lemon. 80 | 81 | Now let's move to part 5, to style the blog. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.0/tutorial/tutorial-part-5.md: -------------------------------------------------------------------------------- 1 | # Part 5: Styling the blog and finalizing. 2 | 3 | In this part we're going to style the posts. 4 | 5 | Now let's delete the `JS` folder, but let's keep the `CSS` Folder. 6 | 7 | Now let's create a `style.css`. 8 | 9 | Add this CSS code to style it. 10 | 11 | ```css 12 | * { 13 | font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; 14 | font-size: 1.2rem; 15 | color: #333; 16 | line-height: 1.5; 17 | margin: 0; 18 | padding: 0; 19 | box-sizing: border-box; 20 | } 21 | 22 | body { 23 | background: #ffffff; 24 | } 25 | 26 | h1 { 27 | font-size: 3rem; 28 | line-height: 1.2; 29 | margin-bottom: 1rem; 30 | } 31 | 32 | h2 { 33 | font-size: 2rem; 34 | margin-bottom: 1rem; 35 | } 36 | 37 | h3 { 38 | font-size: 1.5rem; 39 | margin-bottom: 1rem; 40 | color: #ffa; 41 | } 42 | 43 | p { 44 | margin-bottom: 1rem; 45 | } 46 | ``` 47 | 48 | now in the `app.py` file let's change the `Root`, to add the CSS file. 49 | 50 | ```python 51 | Root = Component("HTTP-Blog", stylesheet="public/css/style.css") 52 | ``` 53 | 54 | Now run the app and see the page now. 55 | 56 | ![blog-output](images/blog-page.PNG) 57 | 58 | And that's about it. 59 | 60 | A fully functioning app in Lemon 🍋. 61 | 62 | Github: https://github.com/Sas2k/HTTP-Blog -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/Hello-World.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World! 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon 🍋: Hello-World! 7 | 8 | Hello, in this part. we're going to build a small lemon app. 9 | 10 | ## Getting Started 11 | 12 | first of, let's create a virtual environment. 13 | 14 | ```bash 15 | #with venv 16 | python -m venv venv 17 | 18 | #with virtualenv 19 | python -m virtualenv venv 20 | ``` 21 | 22 | then activate it with the below command. 23 | 24 | ```bash 25 | #windows 26 | .\\venv\\Scripts\\activate 27 | ``` 28 | 29 | after that install Lemon in it. 30 | 31 | ```bash 32 | pip install Lemon-Library 33 | ``` 34 | 35 | ## creating the app 36 | 37 | now in that app create a file called `app.py` 38 | 39 | now in that app paste this code (don't worry I will explain the code). 40 | 41 | ```python 42 | from Lemon.components import Component 43 | from Lemon.Server.server import Server 44 | 45 | app = Server(None) 46 | Root = Component("Home") 47 | 48 | class home(Component): 49 | 50 | name = "home" 51 | 52 | def item(props: dict): 53 | return """ 54 |

    Hello World!

    55 |

    This is generated in Python!

    56 |

    This is in BOLD

    57 |

    This is in ITALICS

    58 | My Github Profile 59 | """ 60 | 61 | Root.add(home) 62 | 63 | @app.route("/") 64 | def student(request, response): 65 | home_page = Root.render("") 66 | response.text = home_page 67 | 68 | app.run() 69 | ``` 70 | 71 | now to run it, just do this. 72 | 73 | `python app.py` 74 | 75 | ## Code Break Down 🥚🍳 76 | 77 | Now let's break the code down. 78 | 79 | in the first 2 lines, it imports the server and the Component Class. (which is the base class to create the components.) 80 | 81 | then we define an `app` variable, which is the server instance. 82 | the `root` variable is the root component where the components are rendered. 83 | 84 | then there is the `Home` Class, which is a component. 85 | 86 | in the component class, there is a `name` variable, which is the variable that says the name of the variable. 87 | 88 | then the `item` function is where the components stuff is there (like the filling of a pie 🥧). 89 | 90 | the `item` function has a `props` dictionary object. Which are the properties of the element. 91 | 92 | For example: ` 93 | 94 | here the `name="Sas2k"` is the prop. 95 | 96 | After that the component is added to the Root with the `Root.add`. 97 | 98 | then their is the usual route function. 99 | 100 | After, their is the `app.run` which runs it. 101 | 102 | And that's basically it. 103 | 104 | _A Lemon app, broken down._ 105 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/api-reference/Lemon-Server-middleware.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server.middleware 3 | sidebar_position: 4 4 | --- 5 | 6 | # Lemon.Server.middleware 7 | 8 | The middleware module 9 | 10 | ```python 11 | 1 | from Lemon.components import Component 12 | 2 | from Lemon.Server import server, middleware 13 | 3 | 14 | 4 | app = server.Server(None) 15 | 5 | 16 | 6 | class middleware_example(middleware.Middleware): 17 | 7 | def process_request(self, req): 18 | 8 | print("Despatching ->", req.url) 19 | 9 | 20 | 10| def process_response(self, req, res): 21 | 11| print("Despatched", req.url) 22 | 12| 23 | 13|app.add_middleware(middleware_example) 24 | ``` 25 | 26 | ## Middleware [Class] | (self, app) 27 | 28 | The middleware base class 29 | 30 | ### Attributes, Properties and Functions 31 | 32 | #### add [Function] | (self, middleware_cls) < Developer-Function > 33 | 34 | Adds a middleware. 35 | 36 | #### process_request [Function] | (self, req) 37 | 38 | Process's the middleware's requests 39 | 40 | > line 6~8 on example 41 | 42 | #### process_response [Function] | (self, req) 43 | 44 | Process's the middleware before sending back the response 45 | 46 | > line 10~11 on example 47 | 48 | #### handle_request [Function] | (self, req, res) < Developer-Function > 49 | 50 | Handles Request that the class receives. 51 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/api-reference/Lemon-Server-server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server.server 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon.Server.server 7 | 8 | The server, the main backend. (which contains routes and etc..) 9 | 10 | ## Server [Class] | (self, static_dir="public") 11 | 12 | The Server Methods 13 | 14 | ```python 15 | from Lemon.Server import server 16 | 17 | app = server.Server(None) #place None here if you don't have any static files. 18 | ``` 19 | 20 | ### Attributes, Properties and Functions 21 | 22 | #### wsgi_app [Function] | (self, environ, start_response) | < Developer-Function > 23 | 24 | returns a response with environ. 25 | 26 | #### add_route [Function] | (self, path, handler) 27 | 28 | This function adds route django style!. 29 | 30 | ```python 31 | def index(request, response): 32 | response.text = "Hello World!" 33 | 34 | app.add_route("/", index) 35 | ``` 36 | 37 | #### add_exception_handler [Function] | (self, exception_handler) 38 | 39 | Adds a sever exception handler. 40 | 41 | ```python 42 | def custom_exception_handler(request, response, exception_cls): 43 | response.text = "Oops!, Something went wrong!" 44 | 45 | app.add_exception_handler(custom_exception_handler) 46 | ``` 47 | 48 | #### route [Decorator(Function)] | (self, path) 49 | 50 | the route decorator. 51 | 52 | ```python 53 | #Function Based Handler 54 | @app.route("/") 55 | def index(request, response): 56 | request.text = "Hello World" 57 | 58 | #Class Based Handler 59 | @app.route("/") 60 | class Index(): 61 | def get(self, req, res): 62 | res.text = "Hello World" 63 | 64 | def post(self, req, res): 65 | res.text = req.json 66 | ``` 67 | 68 | #### handle_request [Function] | (self, request) | < Developer-Function > 69 | 70 | Handles incoming requests. 71 | 72 | #### add_cookie [Function] | (self, response, key, value, max_age=None, expires=None, path="/", domain=None, Secure=False, httponly=False, samesite=None) 73 | 74 | Creates a cookie 🍪 75 | 76 | ```python 77 | @app.route("/") 78 | def index(request, response): 79 | add_cookie(response, "Hello", "world") 80 | ``` 81 | 82 | #### delete_cookie [Function] | (self, response, key, path="/", domain=None) 83 | 84 | Deletes a cookie 🍪🤏🏽 85 | 86 | ```python 87 | @app.route("/") 88 | def index(request, response): 89 | delete_cookie(response, "Hello") 90 | ``` 91 | 92 | #### get_cookie [Function] | (self, request, key) 93 | 94 | Gets a cookie 📦 95 | 96 | ```python 97 | @app.route("/") 98 | def index(request, response): 99 | get_cookie(request, "Hello") 100 | ``` 101 | 102 | #### add_middleware [Function] | (self, middleware_cls) 103 | 104 | Adds a middleware to run. 105 | 106 | ```python 107 | app.add_middleware(PrintMiddleWare) # <- Fake name "PrintMiddleWare" 108 | ``` 109 | 110 | #### test_session [Function] | (self, base_url="http://testserver") < Developer-Function > 111 | 112 | The testing session used in tests. 113 | 114 | #### run [Function] | (self, host="127.0.0.1", post=8000) 115 | 116 | Runs the app. 117 | 118 | ```python 119 | app.run(port=5000) 120 | ``` 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/api-reference/Lemon-Server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon.Server 7 | 8 | The module containing the middleware and server functions. 9 | 10 | ## [Lemon.Server.server](Lemon-Server-server) 11 | ## [Lemon.Server.middleware](Lemon-Server-middleware) -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/api-reference/Lemon-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.components 3 | sidebar_position: 1 4 | --- 5 | 6 | # Lemon.components 7 | 8 | The module responsible for initializing and creating components. 9 | 10 | ## Component [Class] | (self, name, stylesheet=None, script=None) 11 | 12 | The base component class 13 | 14 | ```python 15 | class TestComponent(Component): 16 | name = "TestComponent" 17 | 18 | def item(props: dict): 19 | return """ 20 |

    Hello World!

    21 |

    Lorem ispum

    22 | """ 23 | ``` 24 | 25 | > When naming Components, Always make the first letter Capital as if your writing names. 26 | 27 | ### Attributes, Properties and Functions 28 | 29 | #### add [Function] | (self, components: list or object) 30 | 31 | Adds a component(s) to a list. to parse. 32 | 33 | ```python 34 | Root.add( 35 | [ 36 | Component, 37 | Testing, 38 | WarningComponent 39 | ] 40 | ) 41 | ``` 42 | 43 | #### parse [Function] | (self, Root, prop: list) | < Developer-Function > 44 | 45 | The function that parses the string. 46 | 47 | #### render [Function] | (self, app: str) 48 | 49 | The function that will render the component 50 | 51 | ```python 52 | response.text = Root.render("") 53 | ``` 54 | 55 | #### item [Function] | (self, props: dict) 56 | 57 | The function where the components html/elements are present 58 | 59 | ```python 60 | # must be inside your component class. 61 | def item(props: dict): 62 | return f""" 63 |

    {props['title']}

    64 |

    {props['body']}

    65 | """ 66 | ``` 67 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/api-reference/Lemon-orm-DBManager.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm.DBManager 3 | sidebar_position: 6 4 | --- 5 | 6 | # Lemon.orm.DBManager 7 | 8 | The Database Manager 9 | 10 | ## SQLConnectionManager [Class] | (self, filename) < Developer-Class > 11 | 12 | The SQLConnectionManager used in migrations 13 | 14 | ### Attributes, Properties and Functions 15 | 16 | #### commit [Decorator(Functions)] | (operation) 17 | 18 | Commits a query. 19 | 20 | #### create_table [Function] | (self, tablename, fields) 21 | 22 | creates a table 23 | 24 | #### show_tables [Property(Function)] | (self) 25 | 26 | shows the tables in the database 27 | 28 | ## SqliteManager [Class] | (self, filename) 29 | 30 | The SQLite Manager. 31 | 32 | ```python 33 | from Lemon.orm.DBManager import SqliteManager 34 | 35 | sql = SqliteManager("model.db") 36 | 37 | sql.select("authors", ["name", "age"]) 38 | 39 | sql.insert("authors", ["Paul", "age"], ["Paul", "25"]) 40 | 41 | ``` 42 | 43 | ### commit [Decorator(function)] | (operation) < Developer-Function > 44 | 45 | Commits the query. 46 | 47 | ### create_table [Function] | (self, tablename, columns) 48 | 49 | Creates a table in the Database. 50 | 51 | ```python 52 | sql = SqliteManager("model.db") 53 | 54 | sql.create_table("authors", ["name", "age"]) 55 | ``` 56 | 57 | ### insert [Function] | (self, tablename, columns, values) 58 | 59 | inserts data to columns 60 | 61 | ```python 62 | sql = SqliteManager("model.db") 63 | 64 | sql.insert("authors", ["name", "age"], ["Paul", "25"]) 65 | ``` 66 | 67 | ### select [Function] | (self, tablename, columns) 68 | 69 | selects columns from the table. 70 | 71 | 72 | ```python 73 | sql = SqliteManager("model.db") 74 | 75 | sql.select("authors", ["name", "age"]) 76 | ``` 77 | 78 | ### delete [Function] | (self, tablename, conditions, logic="AND") 79 | 80 | Deletes a record from the table which matches the condition. 81 | 82 | ```python 83 | sql = SqliteManager("model.db") 84 | 85 | sql.delete("authors", ["name='paul'", "age=25"], "AND") 86 | ``` 87 | 88 | ### update [Function] | (self, tablename, columns, values) 89 | 90 | Update values in the Database. 91 | 92 | ```python 93 | sql = SqliteManager("model.db") 94 | 95 | sql.update("authors", ["name", "age"], ["Paul", "22"]) 96 | ``` 97 | 98 | ## base [Class] | (self) 99 | 100 | The Base Class to be inherited. 101 | 102 | ## baseModel [Class] | (self) 103 | 104 | The Base Model to be inherited 105 | 106 | ## MetaModel [Class] | (self) < Developer-Class > 107 | 108 | The MetaModel Class 109 | 110 | > `base`, `baseModel` and `MetaModel` are used in the migrations. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/api-reference/Lemon-orm-migrations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm.migrations 3 | sidebar_position: 7 4 | --- 5 | 6 | # Lemon.orm.migrations 7 | 8 | The migrations manager 9 | 10 | ```python 11 | from Lemon.orm import DBManager, migrations 12 | 13 | baseModel = DBManager.baseModel 14 | ClassBase = DBManager.base 15 | migrate = migrations.MigrateCommand 16 | 17 | class model(baseModel): 18 | base_model = ClassBase 19 | tablename = "model" 20 | fields = ("field1", "field2") 21 | 22 | model_list = [model] 23 | 24 | migrate(model_list).migrate() 25 | ``` 26 | 27 | ## Migrate [Class] | (self, model_list) < Developer-Class > 28 | 29 | The migrate command for the Lemon ORM 30 | 31 | ### Attributes, Properties and Functions 32 | 33 | #### migrate [Function] | (self) 34 | 35 | migrates the models to a Database. 36 | 37 | ## MigrateCommand [Function] | (model_list) 38 | 39 | The base function for the migrate function. 40 | 41 | ## Attributes, Properties and Functions 42 | 43 | #### migrate [Function] | (self) 44 | 45 | The migrate function which is used in base.py 46 | 47 | ```python 48 | model_list = [model] 49 | 50 | migrate(model_list).migrate() 51 | ``` -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/api-reference/Lemon-orm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm 3 | sidebar_position: 5 4 | --- 5 | 6 | # Lemon.orm 7 | 8 | the module containing the ORM. 9 | 10 | ## [Lemon.orm.DBManager](Lemon-orm-DBManager) 11 | ## [Lemon.orm.migrations](Lemon-orm-migrations) -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/lemon-in-3min.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon In 3 minutes 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon in 3 minutes 7 | 8 | Let's try to create a site in **Lemon 🍋**.. 9 | 10 | ## Getting Started 11 | 12 | To get started first install Lemon 🍋 from pip 13 | 14 | ``` 15 | pip install Lemon-Library 16 | ``` 17 | 18 | ## Generate a new site 19 | 20 | to generate a new site run this command 21 | 22 | ``` 23 | create-lemon-app my-website 24 | ``` 25 | 26 | ## Start your site 27 | 28 | Run the development server: 29 | 30 | ```bash 31 | cd my-website 32 | python app.py 33 | ``` 34 | 35 | then visit localhost:5000 36 | 37 | The `cd` command changes the current directory to the website dir, 38 | 39 | next the `python app.py` runs the app. 40 | 41 | Now that you done this, head over to the [tutorial](tutorial/intro-to-tutorial), to create a basic app. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/lemon-vs-react.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon vs React 3 | sidebar_position: 4 4 | --- 5 | # Lemon vs React. 6 | 7 | In this page we're going to talk about the differences of Lemon and React. 8 | 9 | ## TLDR; What is React? 10 | 11 | React is a front-end framework for JavaScript, it's used to build Interactive UIs. ([Website](https://reactjs.org/)) 12 | 13 | **Now let's compare them feature at a time** 14 | 15 | ## Components 16 | 17 | Now let's talk about components, Both of the libraries use Components. 18 | 19 | ### Lemon [Python] (v1.0.0) 20 | 21 | ```python 22 | class HelloMessage(Component): 23 | name = "HelloMessage" 24 | def item(props:dict): 25 | return f"

    Hello! {props['name']}" 26 | 27 | @app.route("/") #don't mind the app.route or the index function there just there to route the sever 28 | def index(request, response): 29 | response.text = root.render("") 30 | ``` 31 | 32 | ### React (JSX) 33 | 34 | ```jsx 35 | function HelloMessage(props){ 36 | return

    Hello {props.name}
    ; 37 | }; 38 | 39 | root.render() 40 | ``` 41 | 42 | The first one is in Lemon(Python), 43 | The Second one is in React (JSX) 44 | 45 | Here we have a simple component created in both. 46 | Both of them are very similar. Except for the fact that since React uses JSX, you can write HTML directly. 47 | 48 | ## Reactivity 49 | 50 | what reactivity does is when the information, variables change, the render changes automatically. 51 | 52 | here is a To-Do example in both Lemon and React. 53 | 54 | ### Lemon (v1.0.0) 55 | 56 | `app.py` 57 | 58 | ```python 59 | class ToDo(Component): 60 | name = 'ToDo' 61 | def item(props:dict): 62 | return f""" 63 |
    64 |
      65 |
    66 | 67 |
    68 | """ 69 | 70 | @app.route("/") 71 | def index(request, response): 72 | response.text = root.render("") 73 | ``` 74 | 75 | `public/index.js` 76 | 77 | ```js 78 | let todoitems = () => { 79 | data.message = document.getElementById("Text").value; 80 | }; 81 | 82 | let updateToDo = () => { 83 | document.getElementById("Todo-List").appendChild('
  • ' + data.message + '
  • \n'); 84 | }; 85 | 86 | watcher(updateToDo); 87 | ``` 88 | 89 | ### React 90 | 91 | > taken from homepage example. 92 | 93 | ```jsx 94 | class TodoApp extends React.Component { 95 | constructor(props) { 96 | super(props); 97 | this.state = { items: [], text: '' }; 98 | this.handleChange = this.handleChange.bind(this); 99 | this.handleSubmit = this.handleSubmit.bind(this); 100 | } 101 | 102 | render() { 103 | return ( 104 |
    105 |

    TODO

    106 | 107 |
    108 | 111 | 116 | 119 |
    120 |
    121 | ); 122 | } 123 | 124 | handleChange(e) { 125 | this.setState({ text: e.target.value }); 126 | } 127 | 128 | handleSubmit(e) { 129 | e.preventDefault(); 130 | if (this.state.text.length === 0) { 131 | return; 132 | } 133 | const newItem = { 134 | text: this.state.text, 135 | id: Date.now() 136 | }; 137 | this.setState(state => ({ 138 | items: state.items.concat(newItem), 139 | text: '' 140 | })); 141 | } 142 | } 143 | 144 | class TodoList extends React.Component { 145 | render() { 146 | return ( 147 |
      148 | {this.props.items.map(item => ( 149 |
    • {item.text}
    • 150 | ))} 151 |
    152 | ); 153 | } 154 | } 155 | 156 | root.render(); 157 | ``` 158 | 159 | Here as we can see, for lemon reactivity happens through a function called `watcher` which watched the function and it's variables to change, the `data.message` are the values that would change. 160 | 161 | **And that's about it, for the differences... (I might add more soon...)** -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/table.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Table Of Contents 6 | - ## [Table-Of-Contents](table) 7 | - ## [Intro](lemon-in-3min) 8 | - ## Tutorial 9 | - ### [Intro](tutorial/intro-to-tutorial) 10 | - ### [Part-1](tutorial/tutorial-part-1) 11 | - ### [Part-2](tutorial/tutorial-part-2) 12 | - ### [Part-3](tutorial/tutorial-part-3) 13 | - ### [Part-4](tutorial/tutorial-part-4) 14 | - ### [Part-5](tutorial/tutorial-part-5) 15 | - ## Differences (Lemon vs [another library]) 16 | - ### [Lemon vs React](lemon-vs-react) 17 | - ## API Reference (Library Reference) 18 | - ### [Lemon.Components](api-reference/Lemon-Components) 19 | - ### [Lemon.Server](api-reference/Lemon-Server) 20 | - ### [Lemon.Server.server](api-reference/Lemon-Server-server) 21 | - ### [Lemon.Server.middleware](api-reference/Lemon-Server-middleware) 22 | - ### [Lemon.orm](api-reference/Lemon-orm) 23 | - ### [Lemon.orm.DBManager](api-reference/Lemon-orm-DBManager) 24 | - ### [Lemon.orm.migrations](api-reference/Lemon-orm-migrations) 25 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/tutorial/images/blog-page.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/docs/versioned_docs/version-1.3.5/tutorial/images/blog-page.PNG -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/tutorial/intro-to-tutorial.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | > This tutorial series will think, { that you already installed Lemon-Library and Python } 4 | > AND { that you have sufficient knowledge of Python. } 5 | 6 | Hello!, In this tutorial we are going to build a basic app in Lemon. 7 | So you guys can get the hang of it and learn it. 8 | 9 | ## What will be building? 10 | 11 | We're going to build a blog that can be updated through http request. 12 | 13 | So, now that we know what we're building let's get to it!. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/tutorial/tutorial-part-1.md: -------------------------------------------------------------------------------- 1 | # Part 1: Setting things up. 2 | 3 | Now, let's set thing up. 4 | 5 | firstly, let's run the usual `create-lemon-app` command to generate the boilerplate code. 6 | 7 | ```cmd 8 | create-lemon-app http-blog 9 | ``` 10 | 11 | ``` 12 | App created @ /http-blog/ 13 | ``` 14 | 15 | then move into it with `cd` 16 | 17 | ```bash 18 | cd http-blog 19 | ``` 20 | 21 | then the directory should look like this. 22 | 23 | ```dir 24 | http-blog/ 25 | - models/ 26 | - model.py 27 | -public/ 28 | - css/ 29 | - style.css 30 | - js/ 31 | - script.js 32 | - app.py 33 | - base.py 34 | - README.md 35 | ``` 36 | 37 | now create a virtual environment 38 | 39 | ```cmd 40 | #with venv 41 | python -m venv venv 42 | 43 | #with virtualenv 44 | pip install virtualenv #if you haven't already installed it before 45 | python -m virtualenv venv 46 | ``` 47 | 48 | After this install `Lemon` 49 | ``` 50 | pip install Lemon-Library 51 | ``` 52 | 53 | then run the `app.py` to see if everything is correct. 54 | 55 | `python app.py` 56 | 57 | if the app is running then visit localhost:8000, to see the app running. 58 | 59 | then press `control + c` to stop. 60 | 61 | now go ahead and delete the `script.js` and `style.css` which is inside the public. (since we don't need it yet.) 62 | 63 | Now go into the app.py 64 | 65 | and replace the file with this. 66 | 67 | ```python 68 | from Lemon.components import Component 69 | from Lemon.Server.server import Server 70 | 71 | Root = Component("Lemon") 72 | app = Server(static_dir="public") 73 | 74 | class App(Component): 75 | name = "App" 76 | def item(props: dict): 77 | return "Hello World" 78 | 79 | Root.add( 80 | [ 81 | App 82 | ] 83 | ) 84 | 85 | @app.route("/") 86 | def home(request, response): 87 | response.text = Root.render('') 88 | 89 | app.run() 90 | 91 | ``` 92 | 93 | Here, we have removed everything unnecessary from the app. 94 | (We kept the app component since, it will be the main component.) 95 | 96 | now if you run it. 97 | 98 | you will just see a Hello World text on the browser. 99 | 100 | Now the files are prepped and ready to write the code. 101 | 102 | Go to Part II. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/tutorial/tutorial-part-2.md: -------------------------------------------------------------------------------- 1 | # Part 2: Writing the basic components. 2 | 3 | now, let's create a directory(which is a fancy term for a folder.) and name it `Components` 4 | 5 | in this folder we're going to create a folder called `components.py` 6 | 7 | now we're going to write a basic component which has the title, the body and the author. 8 | 9 | > Now before we write anything let me quickly give you the structure of a component. 10 | > ```python 11 | > class thing(Component): 12 | > name = "thing" # the name here will the name going to be used in `root.render()` 13 | > def item(props: dict): 14 | > return "

    THING

    " # the item function is where the html code is presented. 15 | > ``` 16 | 17 | now firstly we need to import the `Component` class, which is the base class. 18 | ```python 19 | from Lemon.components import Component 20 | ``` 21 | 22 | then let's write a basic post component 23 | 24 | ```python 25 | class BlogPost(Component): 26 | name = "BlogPost" 27 | 28 | def item(props: dict): 29 | return f""" 30 |
    31 |

    {props['title']}

    32 |

    By {props['author']}

    33 |
    34 |

    {props['body']}

    35 |
    36 | """ 37 | ``` 38 | 39 | (you can change it however you like.) 40 | 41 | now in the `app.py` file import it like this. 42 | `from Components.components import BlogPost` 43 | 44 | then change the Root.add function like this, 45 | 46 | ```python 47 | Root.add( 48 | [ 49 | App, 50 | BlogPost 51 | ] 52 | ) 53 | ``` 54 | 55 | now you can test it out by removing the "Hello World" from the App components `item` function, and adding the `BlogPost` one. 56 | 57 | `` 58 | 59 | (above is an example) 60 | 61 | Now if you run it, you should see something like below. 62 | 63 | ----------------------------- 64 | 65 | ## Hello World 66 | ### Your-Name 67 | Lorem Ispum Dorem Almet why is this used everywhere? 68 | 69 | ----------------------------- 70 | 71 | Now, that the component is created an working let's move onto part 3. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/tutorial/tutorial-part-3.md: -------------------------------------------------------------------------------- 1 | # Part 3: Building the api. 2 | 3 | Now that we got the basic front-end down. 4 | 5 | We now have to focus on the back-end, which is the API. 6 | 7 | let's start of by creating a routes called /api/get and /api/post 8 | 9 | so the basic decorator to create the route is. 10 | 11 | ```python 12 | @app.route("/route") 13 | def route(request, response): 14 | response.text = "route" 15 | ``` 16 | 17 | now since /api/get is uses a `GET` method we can just make it a normal route. 18 | 19 | ```python 20 | @app.route("/api/get/{post_id:d}") # the {post_id} is an argument in the url. the d means digit. 21 | def api_get(request, response, post_id): 22 | #for now let's just return the post_id 23 | response.json = { "post_id": post_id } 24 | ``` 25 | 26 | now for the /api/post we have to use a class for this. 27 | 28 | ```python 29 | @app.route('/app/post/') 30 | class api_post(): 31 | def get(self, req, res): 32 | res.text = "method not allowed" 33 | def post(self, req, res): 34 | print(req.json) 35 | ``` 36 | 37 | here the body of the request is printed. 38 | now the basic api is implemented let's move to part 4. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/tutorial/tutorial-part-4.md: -------------------------------------------------------------------------------- 1 | # Part 4: Storing the requests and Displaying them as Posts 2 | 3 | In this part, we're going to store the requests, and then we're going to display them. as pages. 4 | 5 | To store them, we're going to create a `posts` list. 6 | 7 | ```python 8 | posts = [{"title": "Hello World", "author": "Lemon", "body": "This is a test post"}] 9 | ``` 10 | 11 | now let's change the return of the item function in the App Component to this, 12 | 13 | ```python 14 | return f"" 15 | ``` 16 | 17 | also let's change the "/" route to "/{post_id}" and add these. 18 | 19 | ```python 20 | @app.route("/{post_id}") 21 | def home(request, response, post_id): 22 | if post_id.isdigit(): 23 | try: 24 | post = posts[int(post_id)-1] 25 | response.text = Root.render(f'') 26 | except IndexError: 27 | response.status_code = 404 28 | response.text = "

    Post not found

    " 29 | else: 30 | response.text = "

    This id should be an integer, Not String

    " 31 | ``` 32 | 33 | also remember the API routes, let's change them like this. 34 | 35 | ```python 36 | @app.route("/api/get/{post_id}") # the {id} is an argument in the url. 37 | def api_get(request, response, post_id): 38 | #for now let's just return the post_id 39 | response.text = posts[post_id] 40 | 41 | @app.route('/api/post/') 42 | class api_post(): 43 | def get(self, req, res): 44 | res.text = "method not allowed" 45 | def post(self, req, res): 46 | json = req.json 47 | if json["title"] and json["body"] and json["author"] and json["id"]: 48 | post_id = int(json["id"]) 49 | if post_id not in posts: 50 | posts[post_id] = json 51 | res.text = "success" 52 | else: 53 | posts.append(json) 54 | res.text = "success" 55 | else: 56 | res.text = "failed" 57 | ``` 58 | 59 | And now run, the app. 60 | 61 | Try going to. https://localhost:8000/1 62 | 63 | and you should see the Test Post. 64 | 65 | you can create a your own posts by sending post requests to `/api/post` 66 | 67 | here is an example body 68 | 69 | ```json 70 | { 71 | "title": "Hello World", 72 | "author": "Sas2k", 73 | "body": "Lorem Ispum Dorem Alamet" 74 | } 75 | ``` 76 | 77 | And that's about it. 78 | 79 | We've created a fully functioning App in Lemon. 80 | 81 | Now let's move to part 5, to style the blog. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.5/tutorial/tutorial-part-5.md: -------------------------------------------------------------------------------- 1 | # Part 5: Styling the blog and finalizing. 2 | 3 | In this part we're going to style the posts. 4 | 5 | Now let's delete the `JS` folder, but let's keep the `CSS` Folder. 6 | 7 | Now let's create a `style.css`. 8 | 9 | Add this CSS code to style it. 10 | 11 | ```css 12 | * { 13 | font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; 14 | font-size: 1.2rem; 15 | color: #333; 16 | line-height: 1.5; 17 | margin: 0; 18 | padding: 0; 19 | box-sizing: border-box; 20 | } 21 | 22 | body { 23 | background: #ffffff; 24 | } 25 | 26 | h1 { 27 | font-size: 3rem; 28 | line-height: 1.2; 29 | margin-bottom: 1rem; 30 | } 31 | 32 | h2 { 33 | font-size: 2rem; 34 | margin-bottom: 1rem; 35 | } 36 | 37 | h3 { 38 | font-size: 1.5rem; 39 | margin-bottom: 1rem; 40 | color: #ffa; 41 | } 42 | 43 | p { 44 | margin-bottom: 1rem; 45 | } 46 | ``` 47 | 48 | now in the `app.py` file let's change the `Root`, to add the CSS file. 49 | 50 | ```python 51 | Root = Component("HTTP-Blog", stylesheet="public/css/style.css") 52 | ``` 53 | 54 | Now run the app and see the page now. 55 | 56 | ![blog-output](images/blog-page.PNG) 57 | 58 | And that's about it. 59 | 60 | A fully functioning app in Lemon 🍋. 61 | 62 | Github: https://github.com/Sas2k/HTTP-Blog -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/Hello-World.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World! 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon 🍋: Hello-World! 7 | 8 | Hello, in this part. we're going to build a small lemon app. 9 | 10 | ## Getting Started 11 | 12 | first of, let's create a virtual environment. 13 | 14 | ```bash 15 | #with venv 16 | python -m venv venv 17 | 18 | #with virtualenv 19 | python -m virtualenv venv 20 | ``` 21 | 22 | then activate it with the below command. 23 | 24 | ```bash 25 | #windows 26 | .\\venv\\Scripts\\activate 27 | ``` 28 | 29 | after that install Lemon in it. 30 | 31 | ```bash 32 | pip install Lemon-Library 33 | ``` 34 | 35 | ## creating the app 36 | 37 | now in that app create a file called `app.py` 38 | 39 | now in that app paste this code (don't worry I will explain the code). 40 | 41 | ```python 42 | from Lemon.components import Component 43 | from Lemon.Server.server import Server 44 | 45 | app = Server(None) 46 | Root = Component("Home") 47 | 48 | class home(Component): 49 | 50 | name = "home" 51 | 52 | def item(props: dict): 53 | return """ 54 |

    Hello World!

    55 |

    This is generated in Python!

    56 |

    This is in BOLD

    57 |

    This is in ITALICS

    58 | My Github Profile 59 | """ 60 | 61 | Root.add(home) 62 | 63 | @app.route("/") 64 | def student(request, response): 65 | home_page = Root.render("") 66 | response.text = home_page 67 | 68 | app.run() 69 | ``` 70 | 71 | now to run it, just do this. 72 | 73 | `python app.py` 74 | 75 | ## Code Break Down 🥚🍳 76 | 77 | Now let's break the code down. 78 | 79 | in the first 2 lines, it imports the server and the Component Class. (which is the base class to create the components.) 80 | 81 | then we define an `app` variable, which is the server instance. 82 | the `root` variable is the root component where the components are rendered. 83 | 84 | then there is the `Home` Class, which is a component. 85 | 86 | in the component class, there is a `name` variable, which is the variable that says the name of the variable. 87 | 88 | then the `item` function is where the components stuff is there (like the filling of a pie 🥧). 89 | 90 | the `item` function has a `props` dictionary object. Which are the properties of the element. 91 | 92 | For example: ` 93 | 94 | here the `name="Sas2k"` is the prop. 95 | 96 | After that the component is added to the Root with the `Root.add`. 97 | 98 | then their is the usual route function. 99 | 100 | After, their is the `app.run` which runs it. 101 | 102 | And that's basically it. 103 | 104 | _A Lemon app, broken down._ 105 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/api-reference/Lemon-Server-middleware.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server.middleware 3 | sidebar_position: 4 4 | --- 5 | 6 | # Lemon.Server.middleware 7 | 8 | The middleware module 9 | 10 | ```python 11 | 1 | from Lemon.components import Component 12 | 2 | from Lemon.Server import server, middleware 13 | 3 | 14 | 4 | app = server.Server(None) 15 | 5 | 16 | 6 | class middleware_example(middleware.Middleware): 17 | 7 | def process_request(self, req): 18 | 8 | print("Despatching ->", req.url) 19 | 9 | 20 | 10| def process_response(self, req, res): 21 | 11| print("Despatched", req.url) 22 | 12| 23 | 13|app.add_middleware(middleware_example) 24 | ``` 25 | 26 | ## Middleware [Class] | (self, app) 27 | 28 | The middleware base class 29 | 30 | ### Attributes, Properties and Functions 31 | 32 | #### add [Function] | (self, middleware_cls) < Developer-Function > 33 | 34 | Adds a middleware. 35 | 36 | #### process_request [Function] | (self, req) 37 | 38 | Process's the middleware's requests 39 | 40 | > line 6~8 on example 41 | 42 | #### process_response [Function] | (self, req) 43 | 44 | Process's the middleware before sending back the response 45 | 46 | > line 10~11 on example 47 | 48 | #### handle_request [Function] | (self, req, res) < Developer-Function > 49 | 50 | Handles Request that the class receives. 51 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/api-reference/Lemon-Server-server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server.server 3 | sidebar_position: 3 4 | --- 5 | 6 | # Lemon.Server.server 7 | 8 | The server, the main backend. (which contains routes and etc..) 9 | 10 | ## Server [Class] | (self, static_dir="public") 11 | 12 | The Server Methods 13 | 14 | ```python 15 | from Lemon.Server import server 16 | 17 | app = server.Server(None) #place None here if you don't have any static files. 18 | ``` 19 | 20 | ### Attributes, Properties and Functions 21 | 22 | #### wsgi_app [Function] | (self, environ, start_response) | < Developer-Function > 23 | 24 | returns a response with environ. 25 | 26 | #### add_route [Function] | (self, path, handler) 27 | 28 | This function adds route django style!. 29 | 30 | ```python 31 | def index(request, response): 32 | response.text = "Hello World!" 33 | 34 | app.add_route("/", index) 35 | ``` 36 | 37 | #### add_exception_handler [Function] | (self, exception_handler) 38 | 39 | Adds a sever exception handler. 40 | 41 | ```python 42 | def custom_exception_handler(request, response, exception_cls): 43 | response.text = "Oops!, Something went wrong!" 44 | 45 | app.add_exception_handler(custom_exception_handler) 46 | ``` 47 | 48 | #### route [Decorator(Function)] | (self, path) 49 | 50 | the route decorator. 51 | 52 | ```python 53 | #Function Based Handler 54 | @app.route("/") 55 | def index(request, response): 56 | request.text = "Hello World" 57 | 58 | #Class Based Handler 59 | @app.route("/") 60 | class Index(): 61 | def get(self, req, res): 62 | res.text = "Hello World" 63 | 64 | def post(self, req, res): 65 | res.text = req.json 66 | ``` 67 | 68 | #### handle_request [Function] | (self, request) | < Developer-Function > 69 | 70 | Handles incoming requests. 71 | 72 | #### add_cookie [Function] | (self, response, key, value, max_age=None, expires=None, path="/", domain=None, Secure=False, httponly=False, samesite=None) 73 | 74 | Creates a cookie 🍪 75 | 76 | ```python 77 | @app.route("/") 78 | def index(request, response): 79 | add_cookie(response, "Hello", "world") 80 | ``` 81 | 82 | #### delete_cookie [Function] | (self, response, key, path="/", domain=None) 83 | 84 | Deletes a cookie 🍪🤏🏽 85 | 86 | ```python 87 | @app.route("/") 88 | def index(request, response): 89 | delete_cookie(response, "Hello") 90 | ``` 91 | 92 | #### get_cookie [Function] | (self, request, key) 93 | 94 | Gets a cookie 📦 95 | 96 | ```python 97 | @app.route("/") 98 | def index(request, response): 99 | get_cookie(request, "Hello") 100 | ``` 101 | 102 | #### add_middleware [Function] | (self, middleware_cls) 103 | 104 | Adds a middleware to run. 105 | 106 | ```python 107 | app.add_middleware(PrintMiddleWare) # <- Fake name "PrintMiddleWare" 108 | ``` 109 | 110 | #### test_session [Function] | (self, base_url="http://testserver") < Developer-Function > 111 | 112 | The testing session used in tests. 113 | 114 | #### run [Function] | (self, host="127.0.0.1", post=8000) 115 | 116 | Runs the app. 117 | 118 | ```python 119 | app.run(port=5000) 120 | ``` 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/api-reference/Lemon-Server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.Server 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon.Server 7 | 8 | The module containing the middleware and server functions. 9 | 10 | ## [Lemon.Server.server](Lemon-Server-server) 11 | ## [Lemon.Server.middleware](Lemon-Server-middleware) -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/api-reference/Lemon-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.components 3 | sidebar_position: 1 4 | --- 5 | 6 | # Lemon.components 7 | 8 | The module responsible for initializing and creating components. 9 | 10 | ## Component [Class] | (self, name, stylesheet=None, script=None) 11 | 12 | The base component class 13 | 14 | ```python 15 | class TestComponent(Component): 16 | name = "TestComponent" 17 | 18 | def item(props: dict): 19 | return """ 20 |

    Hello World!

    21 |

    Lorem ispum

    22 | """ 23 | ``` 24 | 25 | > When naming Components, Always make the first letter Capital as if your writing names. 26 | 27 | ### Attributes, Properties and Functions 28 | 29 | #### add [Function] | (self, components: list or object) 30 | 31 | Adds a component(s) to a list. to parse. 32 | 33 | ```python 34 | Root.add( 35 | [ 36 | Component, 37 | Testing, 38 | WarningComponent 39 | ] 40 | ) 41 | ``` 42 | 43 | #### parse [Function] | (self, Root, prop: list) | < Developer-Function > 44 | 45 | The function that parses the string. 46 | 47 | #### render [Function] | (self, app: str) 48 | 49 | The function that will render the component 50 | 51 | ```python 52 | response.text = Root.render("") 53 | ``` 54 | 55 | #### item [Function] | (self, props: dict) 56 | 57 | The function where the components html/elements are present 58 | 59 | ```python 60 | # must be inside your component class. 61 | def item(props: dict): 62 | return f""" 63 |

    {props['title']}

    64 |

    {props['body']}

    65 | """ 66 | ``` 67 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/api-reference/Lemon-orm-DBManager.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm.DBManager 3 | sidebar_position: 6 4 | --- 5 | 6 | # Lemon.orm.DBManager 7 | 8 | The Database Manager 9 | 10 | ## SQLConnectionManager [Class] | (self, filename) < Developer-Class > 11 | 12 | The SQLConnectionManager used in migrations 13 | 14 | ### Attributes, Properties and Functions 15 | 16 | #### commit [Decorator(Functions)] | (operation) 17 | 18 | Commits a query. 19 | 20 | #### create_table [Function] | (self, tablename, fields) 21 | 22 | creates a table 23 | 24 | #### show_tables [Property(Function)] | (self) 25 | 26 | shows the tables in the database 27 | 28 | ## SqliteManager [Class] | (self, filename) 29 | 30 | The SQLite Manager. 31 | 32 | ```python 33 | from Lemon.orm.DBManager import SqliteManager 34 | 35 | sql = SqliteManager("model.db") 36 | 37 | sql.select("authors", ["name", "age"]) 38 | 39 | sql.insert("authors", ["Paul", "age"], ["Paul", "25"]) 40 | 41 | ``` 42 | 43 | ### commit [Decorator(function)] | (operation) < Developer-Function > 44 | 45 | Commits the query. 46 | 47 | ### create_table [Function] | (self, tablename, columns) 48 | 49 | Creates a table in the Database. 50 | 51 | ```python 52 | sql = SqliteManager("model.db") 53 | 54 | sql.create_table("authors", ["name", "age"]) 55 | ``` 56 | 57 | ### insert [Function] | (self, tablename, columns, values) 58 | 59 | inserts data to columns 60 | 61 | ```python 62 | sql = SqliteManager("model.db") 63 | 64 | sql.insert("authors", ["name", "age"], ["Paul", "25"]) 65 | ``` 66 | 67 | ### select [Function] | (self, tablename, columns) 68 | 69 | selects columns from the table. 70 | 71 | 72 | ```python 73 | sql = SqliteManager("model.db") 74 | 75 | sql.select("authors", ["name", "age"]) 76 | ``` 77 | 78 | ### delete [Function] | (self, tablename, conditions, logic="AND") 79 | 80 | Deletes a record from the table which matches the condition. 81 | 82 | ```python 83 | sql = SqliteManager("model.db") 84 | 85 | sql.delete("authors", ["name='paul'", "age=25"], "AND") 86 | ``` 87 | 88 | ### update [Function] | (self, tablename, columns, values) 89 | 90 | Update values in the Database. 91 | 92 | ```python 93 | sql = SqliteManager("model.db") 94 | 95 | sql.update("authors", ["name", "age"], ["Paul", "22"]) 96 | ``` 97 | 98 | ## base [Class] | (self) 99 | 100 | The Base Class to be inherited. 101 | 102 | ## baseModel [Class] | (self) 103 | 104 | The Base Model to be inherited 105 | 106 | ## MetaModel [Class] | (self) < Developer-Class > 107 | 108 | The MetaModel Class 109 | 110 | > `base`, `baseModel` and `MetaModel` are used in the migrations. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/api-reference/Lemon-orm-migrations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm.migrations 3 | sidebar_position: 7 4 | --- 5 | 6 | # Lemon.orm.migrations 7 | 8 | The migrations manager 9 | 10 | ```python 11 | from Lemon.orm import DBManager, migrations 12 | 13 | baseModel = DBManager.baseModel 14 | ClassBase = DBManager.base 15 | migrate = migrations.MigrateCommand 16 | 17 | class model(baseModel): 18 | base_model = ClassBase 19 | tablename = "model" 20 | fields = ("field1", "field2") 21 | 22 | model_list = [model] 23 | 24 | migrate(model_list).migrate() 25 | ``` 26 | 27 | ## Migrate [Class] | (self, model_list) < Developer-Class > 28 | 29 | The migrate command for the Lemon ORM 30 | 31 | ### Attributes, Properties and Functions 32 | 33 | #### migrate [Function] | (self) 34 | 35 | migrates the models to a Database. 36 | 37 | ## MigrateCommand [Function] | (model_list) 38 | 39 | The base function for the migrate function. 40 | 41 | ## Attributes, Properties and Functions 42 | 43 | #### migrate [Function] | (self) 44 | 45 | The migrate function which is used in base.py 46 | 47 | ```python 48 | model_list = [model] 49 | 50 | migrate(model_list).migrate() 51 | ``` -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/api-reference/Lemon-orm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon.orm 3 | sidebar_position: 5 4 | --- 5 | 6 | # Lemon.orm 7 | 8 | the module containing the ORM. 9 | 10 | ## [Lemon.orm.DBManager](Lemon-orm-DBManager) 11 | ## [Lemon.orm.migrations](Lemon-orm-migrations) -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/lemon-in-3min.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon In 3 minutes 3 | sidebar_position: 2 4 | --- 5 | 6 | # Lemon in 3 minutes 7 | 8 | Let's try to create a site in **Lemon 🍋**.. 9 | 10 | ## Getting Started 11 | 12 | To get started first install Lemon 🍋 from pip 13 | 14 | ``` 15 | pip install Lemon-Library 16 | ``` 17 | 18 | ## Generate a new site 19 | 20 | to generate a new site run this command 21 | 22 | ``` 23 | create-lemon-app my-website 24 | ``` 25 | 26 | ## Start your site 27 | 28 | Run the development server: 29 | 30 | ```bash 31 | cd my-website 32 | python app.py 33 | ``` 34 | 35 | then visit localhost:8000 36 | 37 | The `cd` command changes the current directory to the website dir, 38 | 39 | next the `python app.py` runs the app. 40 | 41 | Now that you done this, head over to the [tutorial](tutorial/intro-to-tutorial), to create a basic app. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/lemon-vs-react.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lemon vs React 3 | sidebar_position: 4 4 | --- 5 | # Lemon vs React. 6 | 7 | In this page we're going to talk about the differences of Lemon and React. 8 | 9 | ## TLDR; What is React? 10 | 11 | React is a front-end framework for JavaScript, it's used to build Interactive UIs. ([Website](https://reactjs.org/)) 12 | 13 | **Now let's compare them feature at a time** 14 | 15 | ## Components 16 | 17 | Now let's talk about components, Both of the libraries use Components. 18 | 19 | ### Lemon [Python] (v1.0.0) 20 | 21 | ```python 22 | class HelloMessage(Component): 23 | name = "HelloMessage" 24 | def item(props:dict): 25 | return f"

    Hello! {props['name']}" 26 | 27 | @app.route("/") #don't mind the app.route or the index function there just there to route the sever 28 | def index(request, response): 29 | response.text = root.render("") 30 | ``` 31 | 32 | ### React (JSX) 33 | 34 | ```jsx 35 | function HelloMessage(props){ 36 | return

    Hello {props.name}
    ; 37 | }; 38 | 39 | root.render() 40 | ``` 41 | 42 | The first one is in Lemon(Python), 43 | The Second one is in React (JSX) 44 | 45 | Here we have a simple component created in both. 46 | Both of them are very similar. Except for the fact that since React uses JSX, you can write HTML directly. 47 | 48 | ## Reactivity 49 | 50 | what reactivity does is when the information, variables change, the render changes automatically. 51 | 52 | here is a To-Do example in both Lemon and React. 53 | 54 | ### Lemon (v1.0.0) 55 | 56 | `app.py` 57 | 58 | ```python 59 | class ToDo(Component): 60 | name = 'ToDo' 61 | def item(props:dict): 62 | return f""" 63 |
    64 |
      65 |
    66 | 67 |
    68 | """ 69 | 70 | @app.route("/") 71 | def index(request, response): 72 | response.text = root.render("") 73 | ``` 74 | 75 | `public/index.js` 76 | 77 | ```js 78 | let todoitems = () => { 79 | data.message = document.getElementById("Text").value; 80 | }; 81 | 82 | let updateToDo = () => { 83 | document.getElementById("Todo-List").appendChild('
  • ' + data.message + '
  • \n'); 84 | }; 85 | 86 | watcher(updateToDo); 87 | ``` 88 | 89 | ### React 90 | 91 | > taken from homepage example. 92 | 93 | ```jsx 94 | class TodoApp extends React.Component { 95 | constructor(props) { 96 | super(props); 97 | this.state = { items: [], text: '' }; 98 | this.handleChange = this.handleChange.bind(this); 99 | this.handleSubmit = this.handleSubmit.bind(this); 100 | } 101 | 102 | render() { 103 | return ( 104 |
    105 |

    TODO

    106 | 107 |
    108 | 111 | 116 | 119 |
    120 |
    121 | ); 122 | } 123 | 124 | handleChange(e) { 125 | this.setState({ text: e.target.value }); 126 | } 127 | 128 | handleSubmit(e) { 129 | e.preventDefault(); 130 | if (this.state.text.length === 0) { 131 | return; 132 | } 133 | const newItem = { 134 | text: this.state.text, 135 | id: Date.now() 136 | }; 137 | this.setState(state => ({ 138 | items: state.items.concat(newItem), 139 | text: '' 140 | })); 141 | } 142 | } 143 | 144 | class TodoList extends React.Component { 145 | render() { 146 | return ( 147 |
      148 | {this.props.items.map(item => ( 149 |
    • {item.text}
    • 150 | ))} 151 |
    152 | ); 153 | } 154 | } 155 | 156 | root.render(); 157 | ``` 158 | 159 | Here as we can see, for lemon reactivity happens through a function called `watcher` which watched the function and it's variables to change, the `data.message` are the values that would change. 160 | 161 | **And that's about it, for the differences... (I might add more soon...)** -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/table.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Table Of Contents 6 | - ## [Table-Of-Contents](table) 7 | - ## [Intro](lemon-in-3min) 8 | - ## Tutorial 9 | - ### [Intro](tutorial/intro-to-tutorial) 10 | - ### [Part-1](tutorial/tutorial-part-1) 11 | - ### [Part-2](tutorial/tutorial-part-2) 12 | - ### [Part-3](tutorial/tutorial-part-3) 13 | - ### [Part-4](tutorial/tutorial-part-4) 14 | - ### [Part-5](tutorial/tutorial-part-5) 15 | - ## Differences (Lemon vs [another library]) 16 | - ### [Lemon vs React](lemon-vs-react) 17 | - ## API Reference (Library Reference) 18 | - ### [Lemon.Components](api-reference/Lemon-Components) 19 | - ### [Lemon.Server](api-reference/Lemon-Server) 20 | - ### [Lemon.Server.server](api-reference/Lemon-Server-server) 21 | - ### [Lemon.Server.middleware](api-reference/Lemon-Server-middleware) 22 | - ### [Lemon.orm](api-reference/Lemon-orm) 23 | - ### [Lemon.orm.DBManager](api-reference/Lemon-orm-DBManager) 24 | - ### [Lemon.orm.migrations](api-reference/Lemon-orm-migrations) 25 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/tutorial/images/blog-page.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/docs/versioned_docs/version-1.3.6/tutorial/images/blog-page.PNG -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/tutorial/intro-to-tutorial.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | > This tutorial series will think, { that you already installed Lemon-Library and Python } 4 | > AND { that you have sufficient knowledge of Python. } 5 | 6 | Hello!, In this tutorial we are going to build a basic app in Lemon. 7 | So you guys can get the hang of it and learn it. 8 | 9 | ## What will be building? 10 | 11 | We're going to build a blog that can be updated through http request. 12 | 13 | So, now that we know what we're building let's get to it!. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/tutorial/tutorial-part-1.md: -------------------------------------------------------------------------------- 1 | # Part 1: Setting things up. 2 | 3 | Now, let's set thing up. 4 | 5 | firstly, let's run the usual `create-lemon-app` command to generate the boilerplate code. 6 | 7 | ```cmd 8 | create-lemon-app http-blog 9 | ``` 10 | 11 | ``` 12 | App created @ /http-blog/ 13 | ``` 14 | 15 | then move into it with `cd` 16 | 17 | ```bash 18 | cd http-blog 19 | ``` 20 | 21 | then the directory should look like this. 22 | 23 | ```dir 24 | http-blog/ 25 | - models/ 26 | - model.py 27 | -public/ 28 | - css/ 29 | - style.css 30 | - js/ 31 | - script.js 32 | - app.py 33 | - base.py 34 | - README.md 35 | ``` 36 | 37 | now create a virtual environment 38 | 39 | ```cmd 40 | #with venv 41 | python -m venv venv 42 | 43 | #with virtualenv 44 | pip install virtualenv #if you haven't already installed it before 45 | python -m virtualenv venv 46 | ``` 47 | 48 | After this install `Lemon` 49 | ``` 50 | pip install Lemon-Library 51 | ``` 52 | 53 | then run the `app.py` to see if everything is correct. 54 | 55 | `python app.py` 56 | 57 | if the app is running then visit localhost:8000, to see the app running. 58 | 59 | then press `control + c` to stop. 60 | 61 | now go ahead and delete the `script.js` and `style.css` which is inside the public. (since we don't need it yet.) 62 | 63 | Now go into the app.py 64 | 65 | and replace the file with this. 66 | 67 | ```python 68 | from Lemon.components import Component 69 | from Lemon.Server.server import Server 70 | 71 | Root = Component("Lemon") 72 | app = Server(static_dir="public") 73 | 74 | class App(Component): 75 | name = "App" 76 | def item(props: dict): 77 | return "Hello World" 78 | 79 | Root.add( 80 | [ 81 | App 82 | ] 83 | ) 84 | 85 | @app.route("/") 86 | def home(request, response): 87 | response.text = Root.render('') 88 | 89 | app.run() 90 | 91 | ``` 92 | 93 | Here, we have removed everything unnecessary from the app. 94 | (We kept the app component since, it will be the main component.) 95 | 96 | now if you run it. 97 | 98 | you will just see a Hello World text on the browser. 99 | 100 | Now the files are prepped and ready to write the code. 101 | 102 | Go to Part II. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/tutorial/tutorial-part-2.md: -------------------------------------------------------------------------------- 1 | # Part 2: Writing the basic components. 2 | 3 | now, let's create a directory(which is a fancy term for a folder.) and name it `Components` 4 | 5 | in this folder we're going to create a folder called `components.py` 6 | 7 | now we're going to write a basic component which has the title, the body and the author. 8 | 9 | > Now before we write anything let me quickly give you the structure of a component. 10 | > ```python 11 | > class thing(Component): 12 | > name = "thing" # the name here will the name going to be used in `root.render()` 13 | > def item(props: dict): 14 | > return "

    THING

    " # the item function is where the html code is presented. 15 | > ``` 16 | 17 | now firstly we need to import the `Component` class, which is the base class. 18 | ```python 19 | from Lemon.components import Component 20 | ``` 21 | 22 | then let's write a basic post component 23 | 24 | ```python 25 | class BlogPost(Component): 26 | name = "BlogPost" 27 | 28 | def item(props: dict): 29 | return f""" 30 |
    31 |

    {props['title']}

    32 |

    By {props['author']}

    33 |
    34 |

    {props['body']}

    35 |
    36 | """ 37 | ``` 38 | 39 | (you can change it however you like.) 40 | 41 | now in the `app.py` file import it like this. 42 | `from Components.components import BlogPost` 43 | 44 | then change the Root.add function like this, 45 | 46 | ```python 47 | Root.add( 48 | [ 49 | App, 50 | BlogPost 51 | ] 52 | ) 53 | ``` 54 | 55 | now you can test it out by removing the "Hello World" from the App components `item` function, and adding the `BlogPost` one. 56 | 57 | `` 58 | 59 | (above is an example) 60 | 61 | Now if you run it, you should see something like below. 62 | 63 | ----------------------------- 64 | 65 | ## Hello World 66 | ### Your-Name 67 | Lorem Ispum Dorem Almet why is this used everywhere? 68 | 69 | ----------------------------- 70 | 71 | Now, that the component is created an working let's move onto part 3. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/tutorial/tutorial-part-3.md: -------------------------------------------------------------------------------- 1 | # Part 3: Building the api. 2 | 3 | Now that we got the basic front-end down. 4 | 5 | We now have to focus on the back-end, which is the API. 6 | 7 | let's start of by creating a routes called /api/get and /api/post 8 | 9 | so the basic decorator to create the route is. 10 | 11 | ```python 12 | @app.route("/route") 13 | def route(request, response): 14 | response.text = "route" 15 | ``` 16 | 17 | now since /api/get is uses a `GET` method we can just make it a normal route. 18 | 19 | ```python 20 | @app.route("/api/get/{post_id:d}") # the {post_id} is an argument in the url. the d means digit. 21 | def api_get(request, response, post_id): 22 | #for now let's just return the post_id 23 | response.json = { "post_id": post_id } 24 | ``` 25 | 26 | now for the /api/post we have to use a class for this. 27 | 28 | ```python 29 | @app.route('/app/post/') 30 | class api_post(): 31 | def get(self, req, res): 32 | res.text = "method not allowed" 33 | def post(self, req, res): 34 | print(req.json) 35 | ``` 36 | 37 | here the body of the request is printed. 38 | now the basic api is implemented let's move to part 4. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/tutorial/tutorial-part-4.md: -------------------------------------------------------------------------------- 1 | # Part 4: Storing the requests and Displaying them as Posts 2 | 3 | In this part, we're going to store the requests, and then we're going to display them. as pages. 4 | 5 | To store them, we're going to create a `posts` list. 6 | 7 | ```python 8 | posts = [{"title": "Hello World", "author": "Lemon", "body": "This is a test post"}] 9 | ``` 10 | 11 | now let's change the return of the item function in the App Component to this, 12 | 13 | ```python 14 | return f"" 15 | ``` 16 | 17 | also let's change the "/" route to "/{post_id}" and add these. 18 | 19 | ```python 20 | @app.route("/{post_id}") 21 | def home(request, response, post_id): 22 | if post_id.isdigit(): 23 | try: 24 | post = posts[int(post_id)-1] 25 | response.text = Root.render(f'') 26 | except IndexError: 27 | response.status_code = 404 28 | response.text = "

    Post not found

    " 29 | else: 30 | response.text = "

    This id should be an integer, Not String

    " 31 | ``` 32 | 33 | also remember the API routes, let's change them like this. 34 | 35 | ```python 36 | @app.route("/api/get/{post_id}") # the {id} is an argument in the url. 37 | def api_get(request, response, post_id): 38 | #for now let's just return the post_id 39 | response.text = posts[post_id] 40 | 41 | @app.route('/api/post/') 42 | class api_post(): 43 | def get(self, req, res): 44 | res.text = "method not allowed" 45 | def post(self, req, res): 46 | json = req.json 47 | if json["title"] and json["body"] and json["author"] and json["id"]: 48 | post_id = int(json["id"]) 49 | if post_id not in posts: 50 | posts[post_id] = json 51 | res.text = "success" 52 | else: 53 | posts.append(json) 54 | res.text = "success" 55 | else: 56 | res.text = "failed" 57 | ``` 58 | 59 | And now run, the app. 60 | 61 | Try going to. https://localhost:8000/1 62 | 63 | and you should see the Test Post. 64 | 65 | you can create a your own posts by sending post requests to `/api/post` 66 | 67 | here is an example body 68 | 69 | ```json 70 | { 71 | "title": "Hello World", 72 | "author": "Sas2k", 73 | "body": "Lorem Ispum Dorem Alamet" 74 | } 75 | ``` 76 | 77 | And that's about it. 78 | 79 | We've created a fully functioning App in Lemon. 80 | 81 | Now let's move to part 5, to style the blog. -------------------------------------------------------------------------------- /docs/versioned_docs/version-1.3.6/tutorial/tutorial-part-5.md: -------------------------------------------------------------------------------- 1 | # Part 5: Styling the blog and finalizing. 2 | 3 | In this part we're going to style the posts. 4 | 5 | Now let's delete the `JS` folder, but let's keep the `CSS` Folder. 6 | 7 | Now let's create a `style.css`. 8 | 9 | Add this CSS code to style it. 10 | 11 | ```css 12 | * { 13 | font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; 14 | font-size: 1.2rem; 15 | color: #333; 16 | line-height: 1.5; 17 | margin: 0; 18 | padding: 0; 19 | box-sizing: border-box; 20 | } 21 | 22 | body { 23 | background: #ffffff; 24 | } 25 | 26 | h1 { 27 | font-size: 3rem; 28 | line-height: 1.2; 29 | margin-bottom: 1rem; 30 | } 31 | 32 | h2 { 33 | font-size: 2rem; 34 | margin-bottom: 1rem; 35 | } 36 | 37 | h3 { 38 | font-size: 1.5rem; 39 | margin-bottom: 1rem; 40 | color: #ffa; 41 | } 42 | 43 | p { 44 | margin-bottom: 1rem; 45 | } 46 | ``` 47 | 48 | now in the `app.py` file let's change the `Root`, to add the CSS file. 49 | 50 | ```python 51 | Root = Component("HTTP-Blog", stylesheet="public/css/style.css") 52 | ``` 53 | 54 | Now run the app and see the page now. 55 | 56 | ![blog-output](images/blog-page.PNG) 57 | 58 | And that's about it. 59 | 60 | A fully functioning app in Lemon 🍋. 61 | 62 | Github: https://github.com/Sas2k/HTTP-Blog -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-1.0.0-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "tutorialSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-1.3.0-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "tutorialSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-1.3.5-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "tutorialSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-1.3.6-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "tutorialSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versions.json: -------------------------------------------------------------------------------- 1 | [ 2 | "1.3.6", 3 | "1.3.5", 4 | "1.3.0", 5 | "1.0.0" 6 | ] 7 | -------------------------------------------------------------------------------- /examples/Custom-Route-Id.py: -------------------------------------------------------------------------------- 1 | from Lemon.components import Component 2 | from Lemon.Server.server import Server 3 | from Lemon.ui.buttons import Buttons 4 | 5 | 6 | class Index(Component): 7 | 8 | name = "Index" 9 | 10 | def __init__(self, name): 11 | self.name = name 12 | 13 | def item(props: dict): 14 | return f""" 15 |

    YOLO

    16 |
    17 |

    You only live once {props["name"]}

    18 | """ 19 | 20 | 21 | class home_redirect(Component): 22 | 23 | name = "home_redirect" 24 | 25 | def item(props: dict): 26 | return f""" 27 |

    Go to /your-name-here

    28 | 29 | """ 30 | 31 | 32 | app = Server(static_dir=None) 33 | Root = Component("YOLO") 34 | 35 | Root.add([Index, home_redirect, Buttons().components]) 36 | 37 | 38 | @app.route("/") 39 | def name(request, response): 40 | response.text = Root.render("") 41 | 42 | 43 | @app.route("/{name}") 44 | def name(request, response, name): 45 | index = Root.render(f"") 46 | response.text = index 47 | 48 | 49 | app.run() 50 | -------------------------------------------------------------------------------- /examples/Hello-World.py: -------------------------------------------------------------------------------- 1 | from Lemon.components import Component 2 | from Lemon.Server.server import Server 3 | 4 | app = Server(None) 5 | Root = Component("Home") 6 | 7 | 8 | class home(Component): 9 | 10 | name = "home" 11 | 12 | def item(props: dict): 13 | return """ 14 |

    Hello World!

    15 |

    This is generated in Python!

    16 |

    This is in BOLD

    17 |

    This is in ITALICS

    18 | My Github Profile 19 | """ 20 | 21 | 22 | Root.add(home) 23 | 24 | 25 | @app.route("/") 26 | def student(request, response): 27 | home_page = Root.render("") 28 | response.text = home_page 29 | 30 | 31 | app.run() 32 | -------------------------------------------------------------------------------- /examples/Lemon-App/README.md: -------------------------------------------------------------------------------- 1 | # create-lemon-app: Lemon-App 2 | 3 | ## Run it. 🚀 4 | 5 | run the app by doing this command. 6 | 7 | `python app.py` 8 | 9 | ## Migrate SQL 10 | 11 | With this 12 | 13 | `python base.py` 14 | -------------------------------------------------------------------------------- /examples/Lemon-App/Tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/examples/Lemon-App/Tests/__init__.py -------------------------------------------------------------------------------- /examples/Lemon-App/Tests/test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | def test_of_test(server, client): 4 | RESPONSE_TEXT = "THIS IS COOL" 5 | @api.route("/test") 6 | def test(): 7 | return RESPONSE_TEXT 8 | assert client.get("http://testserver/test").text == RESPONSE_TEXT 9 | -------------------------------------------------------------------------------- /examples/Lemon-App/app.py: -------------------------------------------------------------------------------- 1 | from Lemon.components import Component 2 | from Lemon.Server.server import Server 3 | from Lemon.ui.buttons import Buttons 4 | 5 | from random import choice 6 | 7 | from models.model import insert_fake_data 8 | 9 | from routes.route import route 10 | 11 | Root = Component("Lemon", "public/css/style.css", "public/js/script.js") 12 | app = Server(static_dir="public") 13 | 14 | class App(Component): 15 | name = "App" 16 | 17 | def item(props: dict): 18 | lemons = ['Lemonade', '🍋', 'Lemon', 'Sour'] 19 | return f''' 20 |
    21 |

    🍋

    22 |

    Hello! edit this in app.py

    23 |

    Here is a random lemon:{choice(lemons)}

    24 | 25 |
    26 | ''' 27 | 28 | Root.add( 29 | [ 30 | App, 31 | Buttons().components 32 | ] 33 | ) 34 | 35 | @app.route("/") 36 | def home(request, response): 37 | insert_fake_data() 38 | response.text = Root.render('') 39 | 40 | app.add_route("/route", route) 41 | 42 | app.run() 43 | 44 | -------------------------------------------------------------------------------- /examples/Lemon-App/base.py: -------------------------------------------------------------------------------- 1 | from Lemon.orm import DBManager, migrations 2 | 3 | baseModel = DBManager.baseModel 4 | ClassBase = DBManager.base 5 | migrate = migrations.MigrateCommand 6 | 7 | class model(baseModel): 8 | base_model = ClassBase 9 | tablename = "model" 10 | fields = ("field1", "field2") 11 | 12 | model_list = [model] 13 | 14 | migrate(model_list).migrate() -------------------------------------------------------------------------------- /examples/Lemon-App/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/examples/Lemon-App/models/__init__.py -------------------------------------------------------------------------------- /examples/Lemon-App/models/model.py: -------------------------------------------------------------------------------- 1 | from Lemon.orm.DBManager import SqliteManager 2 | 3 | sql = SqliteManager("model.db") 4 | # inserts some fake data to field1 and field2 5 | def insert_fake_data(): 6 | sql.insert("model", ("field1", "field2"), ("Hello", "World")) 7 | print(sql.select("model", ("field1", "field2"))) 8 | print("From model.py") 9 | sql.delete("model", ("field1='Hello'", "field2='World'")) 10 | -------------------------------------------------------------------------------- /examples/Lemon-App/public/css/style.css: -------------------------------------------------------------------------------- 1 | *, body { 2 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 | background-color: yellow; 4 | text-align: center; 5 | } 6 | 7 | #BIG{ 8 | font-size: 6rem; 9 | } 10 | 11 | h1 { 12 | text-align: center; 13 | font-weight: bold; 14 | } 15 | 16 | h2 { 17 | text-align: center; 18 | font-style: italic; 19 | } -------------------------------------------------------------------------------- /examples/Lemon-App/public/js/script.js: -------------------------------------------------------------------------------- 1 | let Today = new Date(); 2 | var time = Today.getFullYear() + '-' + Today.getMonth() + '-' + Today.getDate() + ' | ' + Today.getHours() + ':' + Today.getMinutes() + ':' + Today.getSeconds() 3 | var pop_up = (string) => { 4 | console.log(string) 5 | alert(time + ':\n' + string) 6 | } 7 | -------------------------------------------------------------------------------- /examples/Lemon-App/requirements.txt: -------------------------------------------------------------------------------- 1 | Lemon-Library 2 | pytest -------------------------------------------------------------------------------- /examples/Lemon-App/routes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sas2k/Lemon/133509570662a6aa82fe10e6bed69d73716de86b/examples/Lemon-App/routes/__init__.py -------------------------------------------------------------------------------- /examples/Lemon-App/routes/route.py: -------------------------------------------------------------------------------- 1 | from Lemon.components import Component 2 | from Lemon.ui.buttons import Buttons 3 | 4 | Root = Component("Lemon", "public/css/style.css", "public/js/script.js") 5 | 6 | class route(Component): 7 | name = "route" 8 | 9 | def item(props: dict): 10 | return f''' 11 |
    12 |

    🍋

    13 |

    Hello! edit this in routes/route.py

    14 |

    Isn't the Lemon very BIG

    15 | 16 |
    17 | ''' 18 | 19 | Root.add( 20 | [ 21 | route 22 | ] 23 | ) 24 | 25 | def route(request, response): 26 | response.text = Root.render("") 27 | -------------------------------------------------------------------------------- /examples/Tests.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | def client_can_send_requests(server, client): 5 | RESPONSE_TEXT = "THIS IS COOL" 6 | 7 | @server.route("/test") 8 | def test(request, response): 9 | response.text = RESPONSE_TEXT 10 | 11 | assert client.get("http://testserver/hey").text == RESPONSE_TEXT 12 | -------------------------------------------------------------------------------- /examples/django-routing.py: -------------------------------------------------------------------------------- 1 | from Lemon.Server import server 2 | 3 | app = server.Server(None) 4 | 5 | 6 | def index(request, response): 7 | response.text = "Hello, world!" 8 | 9 | 10 | app.add_route("/", index) 11 | 12 | app.run() 13 | -------------------------------------------------------------------------------- /examples/exception-handler.py: -------------------------------------------------------------------------------- 1 | from Lemon.Server import server 2 | from Lemon.components import Component 3 | 4 | app = server.Server(None) 5 | root = Component(app) 6 | 7 | 8 | class ExceptionComponent(Component): 9 | name = "ExceptionComponent" 10 | 11 | def item(props: dict): 12 | return """ 13 | 32 |
    33 |

    001010100101101010010100101

    34 |

    Looks like something went wrong

    35 |

    Please try again later......

    36 |
    37 | """ 38 | 39 | 40 | def custom_exception_handler(request, response, exception_cls): 41 | response.text = root.render("") 42 | 43 | 44 | app.add_exception_handler(custom_exception_handler) 45 | 46 | root.add([ExceptionComponent]) 47 | 48 | 49 | @app.route("/") 50 | def index(request): 51 | raise AssertionError("ERRRRRRRROR! (So many R's)") 52 | 53 | 54 | app.run() 55 | -------------------------------------------------------------------------------- /examples/middleware-example.py: -------------------------------------------------------------------------------- 1 | from Lemon.components import Component 2 | from Lemon.Server import server, middleware 3 | 4 | app = server.Server(None) 5 | 6 | 7 | class middleware_example(middleware.Middleware): 8 | def process_request(self, req): 9 | print("Despatching ->", req.url) 10 | 11 | def process_response(self, req, res): 12 | print("Despatched", req.url) 13 | 14 | 15 | app.add_middleware(middleware_example) 16 | 17 | app.run() -------------------------------------------------------------------------------- /examples/props.py: -------------------------------------------------------------------------------- 1 | from Lemon.components import Component 2 | from Lemon.Server.server import Server 3 | 4 | Root = Component("Props") 5 | app = Server(static_dir=None) 6 | 7 | 8 | class test(Component): 9 | 10 | name = "test" 11 | 12 | def item(props: dict): 13 | return "" 14 | 15 | 16 | class Props(Component): 17 | 18 | name = "Props" 19 | components = {} 20 | 21 | def __init__(self): 22 | pass 23 | 24 | def item(props: dict): 25 | return f""" 26 |

    {props['title']}

    27 |

    {props['h1']}

    28 |

    {props['p']} 29 | """ 30 | 31 | 32 | Root.add([test, Props]) 33 | 34 | 35 | @app.route("/") 36 | def title(request, response): 37 | page = Root.render( 38 | """""" 39 | ) 40 | response.text = page 41 | 42 | 43 | app.run() 44 | -------------------------------------------------------------------------------- /examples/reactivity-example/app.py: -------------------------------------------------------------------------------- 1 | from Lemon.components import Component 2 | from Lemon.Server.server import Server 3 | from Lemon.ui.forms import FormControl 4 | 5 | app = Server() 6 | Root = Component("Test", None, "public/script.js") 7 | 8 | 9 | class Test(Component): 10 | 11 | name = "Test" 12 | 13 | def item(props: dict): 14 | return """ 15 |

    16 |

    Type in the text box!

    17 |
    18 | 19 |
    20 |

    Text:

    21 |
    22 | """ 23 | 24 | 25 | Root.add([Test, FormControl().components]) 26 | 27 | 28 | @app.route("/") 29 | def index(request, response): 30 | response.text = Root.render("") 31 | 32 | 33 | app.run() 34 | -------------------------------------------------------------------------------- /examples/reactivity-example/public/script.js: -------------------------------------------------------------------------------- 1 | //from the input field take the value and replace the text in text-output with it 2 | let changetext = () => { 3 | data.message = document.getElementById("text").value; 4 | } 5 | 6 | function updateText() { 7 | document.getElementById("text-output").innerText = data.message; 8 | } 9 | 10 | watcher(updateText) -------------------------------------------------------------------------------- /examples/ui-demo.py: -------------------------------------------------------------------------------- 1 | from Lemon.components import Component 2 | from Lemon.Server.server import Server 3 | from Lemon.ui.buttons import Buttons 4 | from Lemon.ui.forms import FormControl 5 | 6 | Root = Component("UI-Demo") 7 | app = Server(static_dir=None) 8 | 9 | 10 | class Button(Component): 11 | name = "Button" 12 | 13 | def item(props: dict): 14 | return f""" 15 |
    16 |

    Buttons

    17 |
    18 | 19 |
    20 | 21 |
    22 | 23 |
    24 | 25 |
    26 | 27 |
    28 | 29 |
    30 | 31 |
    32 | 33 |
    34 | 35 |
    36 | """ 37 | 38 | 39 | class Forms(Component): 40 | name = "Forms" 41 | 42 | def item(props: dict): 43 | return f""" 44 |
    45 |

    Forms

    46 |
    47 | 48 |