diff --git a/app/config/errors.php b/app/config/errors.php index c3b791f613..f9c2f6b5ba 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -837,7 +837,7 @@ return [ Exception::RULE_VERIFICATION_FAILED => [ 'name' => Exception::RULE_VERIFICATION_FAILED, 'description' => 'Domain verification failed. Please check if your DNS records are correct and try again.', - 'code' => 401, + 'code' => 400, 'publish' => true ], Exception::PROJECT_SMTP_CONFIG_INVALID => [ diff --git a/app/config/frameworks.php b/app/config/frameworks.php index 82fd70bf5b..afdf96145e 100644 --- a/app/config/frameworks.php +++ b/app/config/frameworks.php @@ -138,7 +138,7 @@ return [ 'vue' => [ 'key' => 'vue', 'name' => 'Vue.js', - 'screenshotSleep' => 3000, + 'screenshotSleep' => 5000, 'buildRuntime' => 'node-22', 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'adapters' => [ @@ -227,6 +227,23 @@ return [ ] ] ], + 'lynx' => [ + 'key' => 'lynx', + 'name' => 'Lynx', + 'screenshotSleep' => 5000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'adapters' => [ + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist', + 'startCommand' => 'bash helpers/server.sh', + 'fallbackFile' => 'index.html' + ] + ] + ], 'flutter' => [ 'key' => 'flutter', 'name' => 'Flutter', diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index cc8a611416..bd2230a4a8 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -24718,6 +24718,7 @@ "sveltekit", "astro", "remix", + "lynx", "flutter", "vite", "other" @@ -25353,6 +25354,7 @@ "sveltekit", "astro", "remix", + "lynx", "flutter", "vite", "other" @@ -37040,6 +37042,11 @@ "description": "Site Template Name.", "x-example": "Starter site" }, + "tagline": { + "type": "string", + "description": "Short description of template", + "x-example": "Minimal web app integrating with Appwrite." + }, "demoUrl": { "type": "string", "description": "URL hosting a template demo.", @@ -37103,6 +37110,7 @@ "required": [ "key", "name", + "tagline", "demoUrl", "screenshotDark", "screenshotLight", diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index ecda53b77b..706d84bd84 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -16816,6 +16816,7 @@ "sveltekit", "astro", "remix", + "lynx", "flutter", "vite", "other" @@ -17226,6 +17227,7 @@ "sveltekit", "astro", "remix", + "lynx", "flutter", "vite", "other" diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 4d3ab5bce8..0ef66f4f9c 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -25221,6 +25221,7 @@ "sveltekit", "astro", "remix", + "lynx", "flutter", "vite", "other" @@ -25871,6 +25872,7 @@ "sveltekit", "astro", "remix", + "lynx", "flutter", "vite", "other" @@ -37623,6 +37625,11 @@ "description": "Site Template Name.", "x-example": "Starter site" }, + "tagline": { + "type": "string", + "description": "Short description of template", + "x-example": "Minimal web app integrating with Appwrite." + }, "demoUrl": { "type": "string", "description": "URL hosting a template demo.", @@ -37688,6 +37695,7 @@ "required": [ "key", "name", + "tagline", "demoUrl", "screenshotDark", "screenshotLight", diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index c2d3b06ebc..59f7b5f7b8 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -17285,6 +17285,7 @@ "sveltekit", "astro", "remix", + "lynx", "flutter", "vite", "other" @@ -17714,6 +17715,7 @@ "sveltekit", "astro", "remix", + "lynx", "flutter", "vite", "other" diff --git a/app/config/templates/function.php b/app/config/templates/function.php index e543b2419c..d8426ad900 100644 --- a/app/config/templates/function.php +++ b/app/config/templates/function.php @@ -23,6 +23,7 @@ return [ 'icon' => 'icon-lightning-bolt', 'id' => 'starter', 'name' => 'Starter function', + 'score' => 5, 'tagline' => 'A simple function to get started. Edit this function to explore endless possibilities with Appwrite Functions.', 'permissions' => ['any'], @@ -62,6 +63,7 @@ return [ 'icon' => 'icon-upstash', 'id' => 'query-upstash-vector', 'name' => 'Query Upstash Vector', + 'score' => 4, 'tagline' => 'Vector database that stores text embeddings and context retrieval for LLMs', 'permissions' => ['any'], 'events' => [], @@ -106,6 +108,7 @@ return [ 'icon' => 'icon-redis', 'id' => 'query-redis-labs', 'name' => 'Query Redis Labs', + 'score' => 4, 'tagline' => 'Key-value database with advanced caching capabilities.', 'permissions' => ['any'], 'events' => [], @@ -149,6 +152,7 @@ return [ 'icon' => 'icon-neo4j', 'id' => 'query-neo4j-auradb', 'name' => 'Query Neo4j AuraDB', + 'score' => 4, 'tagline' => 'Graph database with focus on relations between data.', 'permissions' => ['any'], 'events' => [], @@ -200,6 +204,7 @@ return [ 'icon' => 'icon-mongodb', 'id' => 'query-mongo-atlas', 'name' => 'Query MongoDB Atlas', + 'score' => 4, 'tagline' => 'Realtime NoSQL document database with geospecial, graph, search, and vector suport.', 'permissions' => ['any'], @@ -237,6 +242,7 @@ return [ 'icon' => 'icon-neon', 'id' => 'query-neon-postgres', 'name' => 'Query Neon Postgres', + 'score' => 4, 'tagline' => 'Reliable SQL database with replication, point-in-time recovery, and pgvector support.', 'permissions' => ['any'], @@ -305,6 +311,7 @@ return [ 'icon' => 'icon-open-ai', 'id' => 'prompt-chatgpt', 'name' => 'Prompt ChatGPT', + 'score' => 7, 'tagline' => 'Ask questions and let OpenAI GPT-3.5-turbo answer.', 'permissions' => ['any'], 'events' => [], @@ -366,6 +373,7 @@ return [ 'icon' => 'icon-discord', 'id' => 'discord-command-bot', 'name' => 'Discord Command Bot', + 'score' => 6, 'tagline' => 'Simple command using Discord Interactions.', 'permissions' => ['any'], 'events' => [], @@ -429,6 +437,7 @@ return [ 'icon' => 'icon-perspective-api', 'id' => 'analyze-with-perspectiveapi', 'name' => 'Analyze with PerspectiveAPI', + 'score' => 5, 'tagline' => 'Automate moderation by getting toxicity of messages.', 'permissions' => ['any'], 'events' => [], @@ -464,6 +473,7 @@ return [ 'icon' => 'icon-pangea', 'id' => 'censor-with-redact', 'name' => 'Censor with Redact', + 'score' => 5, 'tagline' => 'Censor sensitive information from a provided text string using Redact API by Pangea.', 'permissions' => ['any'], @@ -512,6 +522,7 @@ return [ 'icon' => 'icon-document', 'id' => 'generate-pdf', 'name' => 'Generate PDF', + 'score' => 7, 'tagline' => 'Document containing sample invoice in PDF format.', 'permissions' => ['any'], 'events' => [], @@ -533,6 +544,7 @@ return [ 'icon' => 'icon-github', 'id' => 'github-issue-bot', 'name' => 'GitHub issue bot', + 'score' => 4, 'tagline' => 'Automate the process of responding to newly opened issues in a GitHub repository.', 'permissions' => ['any'], @@ -577,6 +589,7 @@ return [ 'icon' => 'icon-bookmark', 'id' => 'url-shortener', 'name' => 'URL shortener', + 'score' => 3, 'tagline' => 'Generate URL with short ID and redirect to the original URL when visited.', 'permissions' => ['any'], 'events' => [], @@ -628,6 +641,7 @@ return [ 'icon' => 'icon-algolia', 'id' => 'sync-with-algolia', 'name' => 'Sync with Algolia', + 'score' => 4, 'tagline' => 'Intuitive search bar for any data in Appwrite Databases.', 'permissions' => ['any'], 'events' => [], @@ -709,6 +723,7 @@ return [ 'icon' => 'icon-meilisearch', 'id' => 'sync-with-meilisearch', 'name' => 'Sync with Meilisearch', + 'score' => 4, 'tagline' => 'Intuitive search bar for any data in Appwrite Databases.', 'permissions' => ['any'], 'events' => [], @@ -802,6 +817,7 @@ return [ 'icon' => 'icon-vonage', 'id' => 'whatsapp-with-vonage', 'name' => 'WhatsApp with Vonage', + 'score' => 6, 'tagline' => 'Simple bot to answer WhatsApp messages.', 'permissions' => ['any'], 'events' => [], @@ -888,6 +904,7 @@ return [ 'icon' => 'icon-bell', 'id' => 'push-notification-with-fcm', 'name' => 'Push notification with FCM', + 'score' => 4, 'tagline' => 'Send push notifications to your users using Firebase Cloud Messaging (FCM).', 'permissions' => ['any'], 'events' => [], @@ -944,6 +961,7 @@ return [ 'icon' => 'icon-mail', 'id' => 'email-contact-form', 'name' => 'Email contact form', + 'score' => 7, 'tagline' => 'Sends an email with the contents of a HTML form.', 'permissions' => ['any'], 'events' => [], @@ -1027,6 +1045,7 @@ return [ 'icon' => 'icon-stripe', 'id' => 'subscriptions-with-stripe', 'name' => 'Subscriptions with Stripe', + 'score' => 6, 'tagline' => 'Receive recurring card payments and grant subscribers extra permissions.', 'permissions' => ['any'], 'events' => [], @@ -1068,6 +1087,7 @@ return [ 'icon' => 'icon-stripe', 'id' => 'payments-with-stripe', 'name' => 'Payments with Stripe', + 'score' => 8, 'tagline' => 'Receive card payments and store paid orders.', 'permissions' => ['any'], 'events' => [], @@ -1125,6 +1145,7 @@ return [ 'icon' => 'icon-chat', 'id' => 'text-generation-with-huggingface', 'name' => 'Text generation', + 'score' => 5, 'tagline' => 'Generate text using the Hugging Face inference API.', 'permissions' => ['any'], 'events' => [], @@ -1159,6 +1180,7 @@ return [ 'icon' => 'icon-translate', 'id' => 'language-translation-with-huggingface', 'name' => 'Language translation', + 'score' => 5, 'tagline' => 'Translate text using the Hugging Face inference API.', 'permissions' => ['any'], 'events' => [], @@ -1193,6 +1215,7 @@ return [ 'icon' => 'icon-eye', 'id' => 'image-classification-with-huggingface', 'name' => 'Image classification', + 'score' => 5, 'tagline' => 'Classify images using the Hugging Face inference API.', 'permissions' => ['any'], 'events' => ['buckets.*.files.*.create'], @@ -1251,6 +1274,7 @@ return [ 'icon' => 'icon-eye', 'id' => 'object-detection-with-huggingface', 'name' => 'Object detection', + 'score' => 5, 'tagline' => 'Detect objects in images using the Hugging Face inference API.', 'permissions' => ['any'], 'events' => ['buckets.*.files.*.create'], @@ -1309,6 +1333,7 @@ return [ 'icon' => 'icon-text', 'id' => 'speech-recognition-with-huggingface', 'name' => 'Speech recognition', + 'score' => 5, 'tagline' => 'Transcribe audio to text using the Hugging Face inference API.', 'permissions' => ['any'], 'events' => ['buckets.*.files.*.create'], @@ -1367,6 +1392,7 @@ return [ 'icon' => 'icon-chat', 'id' => 'text-to-speech-with-huggingface', 'name' => 'Text to speech', + 'score' => 5, 'tagline' => 'Convert text to speech using the Hugging Face inference API.', 'permissions' => ['any'], 'events' => ['databases.*.collections.*.documents.*.create'], @@ -1425,6 +1451,7 @@ return [ 'icon' => 'icon-chip', 'id' => 'generate-with-replicate', 'name' => 'Generate with Replicate', + 'score' => 5, 'tagline' => "Generate text, audio and images using Replicate's API.", 'permissions' => ['any'], 'events' => [], @@ -1460,6 +1487,7 @@ return [ 'icon' => 'icon-chip', 'id' => 'generate-with-together-ai', 'name' => 'Generate with Together AI', + 'score' => 5, 'tagline' => "Generate text and images using Together AI's API.", 'permissions' => ['any'], 'events' => [], @@ -1502,6 +1530,7 @@ return [ 'icon' => 'icon-chip', 'id' => 'chat-with-perplexity-ai', 'name' => 'Chat with Perplexity AI', + 'score' => 5, 'tagline' => 'Create a chatbot using the Perplexity AI API.', 'permissions' => ['any'], 'events' => [], @@ -1543,6 +1572,7 @@ return [ 'icon' => 'icon-chip', 'id' => 'generate-with-replicate', 'name' => 'Generate with Replicate', + 'score' => 5, 'tagline' => "Generate text, audio and images using Replicate's API.", 'permissions' => ['any'], 'events' => [], @@ -1578,6 +1608,7 @@ return [ 'icon' => 'icon-document-search', 'id' => 'sync-with-pinecone', 'name' => 'Sync with Pinecone', + 'score' => 4, 'tagline' => "Sync your Appwrite database with Pinecone's vector database.", 'permissions' => ['any'], 'events' => [], @@ -1641,6 +1672,7 @@ return [ 'icon' => 'icon-chip', 'id' => 'rag-with-langchain', 'name' => 'RAG with LangChain', + 'score' => 6, 'tagline' => 'Generate text using a LangChain RAG model', 'permissions' => ['any'], 'events' => [], @@ -1704,6 +1736,7 @@ return [ 'icon' => 'icon-chat', 'id' => 'speak-with-elevenlabs', 'name' => 'Speak with ElevenLabs', + 'score' => 5, 'tagline' => 'Convert text to speech using the ElevenLabs API.', 'permissions' => ['any'], 'cron' => '', @@ -1759,6 +1792,7 @@ return [ 'icon' => 'icon-chip', 'id' => 'speak-with-lmnt', 'name' => 'Speak with LMNT', + 'score' => 5, 'tagline' => 'Convert text to speech using the LMNT API.', 'permissions' => ['any'], 'cron' => '', @@ -1800,6 +1834,7 @@ return [ 'icon' => 'icon-chip', 'id' => 'chat-with-anyscale', 'name' => 'Chat with AnyScale', + 'score' => 5, 'tagline' => 'Create a chatbot using the AnyScale API.', 'permissions' => ['any'], 'cron' => '', @@ -1841,6 +1876,7 @@ return [ 'icon' => 'icon-music-note', 'id' => 'music-generation-with-huggingface', 'name' => 'Music generation', + 'score' => 4, 'tagline' => 'Generate music from a text prompt using the Hugging Face inference API.', 'permissions' => ['any'], 'events' => [], @@ -1883,6 +1919,7 @@ return [ 'icon' => 'icon-chip', 'id' => 'generate-with-fal-ai', 'name' => 'Generate with fal.ai', + 'score' => 5, 'tagline' => "Generate images using fal.ai's API.", 'permissions' => ['any'], 'events' => [], @@ -1918,6 +1955,7 @@ return [ 'icon' => 'icon-currency-dollar', 'id' => 'subscriptions-with-lemon-squeezy', 'name' => 'Subscriptions with Lemon Squeezy', + 'score' => 6, 'tagline' => 'Receive recurring card payments and grant subscribers extra permissions.', 'permissions' => ['any'], 'events' => [], @@ -1973,6 +2011,7 @@ return [ 'icon' => 'icon-currency-dollar', 'id' => 'payments-with-lemon-squeezy', 'name' => 'Payments with Lemon Squeezy', + 'score' => 6, 'tagline' => 'Receive card payments and store paid orders.', 'permissions' => ['any'], 'events' => [], diff --git a/app/config/templates/site.php b/app/config/templates/site.php index ba58940969..f5ffab0dad 100644 --- a/app/config/templates/site.php +++ b/app/config/templates/site.php @@ -87,15 +87,6 @@ const TEMPLATE_FRAMEWORKS = [ 'adapter' => 'static', 'fallbackFile' => '', ], - 'OTHER' => [ - 'key' => 'other', - 'name' => 'Other', - 'installCommand' => 'npm install', - 'buildCommand' => 'npm run build', - 'buildRuntime' => 'node-22', - 'adapter' => 'static', - 'fallbackFile' => 'index.html', - ], 'VITE' => [ 'key' => 'vite', 'name' => 'Vite', @@ -144,6 +135,16 @@ const TEMPLATE_FRAMEWORKS = [ 'adapter' => 'static', 'outputDirectory' => './', ], + 'LYNX' => [ + 'key' => 'lynx', + 'name' => 'Lynx', + 'installCommand' => 'npm install && cd web && npm install && cd ..', + 'buildCommand' => 'npm run build && cd web && npm run build && cd ..', + 'buildRuntime' => 'node-22', + 'adapter' => 'static', + 'outputDirectory' => './web/dist', + 'fallbackFile' => 'index.html', + ], ]; function getFramework(string $frameworkEnum, array $overrides) @@ -153,9 +154,30 @@ function getFramework(string $frameworkEnum, array $overrides) } return [ + [ + 'key' => 'lynx-starter', + 'name' => 'Lynx Starter', + 'tagline' => 'Sample application built with Lynx, a cross-platform framework focused on performance.', + 'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) + 'useCases' => [UseCases::STARTER], + 'screenshotDark' => $url . '/images/sites/templates/lynx-starter-dark.png', + 'screenshotLight' => $url . '/images/sites/templates/lynx-starter-light.png', + 'frameworks' => [ + getFramework('LYNX', [ + 'providerRootDirectory' => './lynx/starter', + ]), + ], + 'vcsProvider' => 'github', + 'providerRepositoryId' => 'templates-for-sites', + 'providerOwner' => 'appwrite', + 'providerVersion' => '0.3.*', + 'variables' => [] + ], [ 'key' => 'vitepress', 'name' => 'Vitepress', + 'tagline' => 'Platform for documentation and knowledge sharing powered by Vite.', + 'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::DOCUMENTATION], 'screenshotDark' => $url . '/images/sites/templates/vitepress-dark.png', 'screenshotLight' => $url . '/images/sites/templates/vitepress-light.png', @@ -177,6 +199,8 @@ return [ [ 'key' => 'vuepress', 'name' => 'Vuepress', + 'tagline' => 'Platform for documentation and knowledge sharing powered by Vue.', + 'score' => 4, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::DOCUMENTATION], 'screenshotDark' => $url . '/images/sites/templates/vuepress-dark.png', 'screenshotLight' => $url . '/images/sites/templates/vuepress-light.png', @@ -198,6 +222,8 @@ return [ [ 'key' => 'docusaurus', 'name' => 'Docusaurus', + 'tagline' => 'Platform for documentation and knowledge sharing powered by React.', + 'score' => 4, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::DOCUMENTATION], 'screenshotDark' => $url . '/images/sites/templates/docusaurus-dark.png', 'screenshotLight' => $url . '/images/sites/templates/docusaurus-light.png', @@ -219,6 +245,8 @@ return [ [ 'key' => 'nxt-lnk', 'name' => 'Nxt Lnk', + 'tagline' => 'Personal website for creators to merge all URLs to social profiles.', + 'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::PORTFOLIO], 'screenshotDark' => $url . '/images/sites/templates/nxt-lnk-dark.png', 'screenshotLight' => $url . '/images/sites/templates/nxt-lnk-light.png', @@ -236,6 +264,8 @@ return [ [ 'key' => 'magic-portfolio', 'name' => 'Magic Portfolio', + 'tagline' => 'Complex personal website to showcase your projects, articles, and more.', + 'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::PORTFOLIO], 'screenshotDark' => $url . '/images/sites/templates/magic-portfolio-dark.png', 'screenshotLight' => $url . '/images/sites/templates/magic-portfolio-light.png', @@ -253,6 +283,8 @@ return [ [ 'key' => 'littlelink', 'name' => 'LittleLink', + 'tagline' => 'Personal website for creators to merge all URLs to social profiles.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::PORTFOLIO], 'screenshotDark' => $url . '/images/sites/templates/littlelink-dark.png', 'screenshotLight' => $url . '/images/sites/templates/littlelink-light.png', @@ -270,6 +302,8 @@ return [ [ 'key' => 'logspot', 'name' => 'Logspot', + 'tagline' => 'Website to publish changelogs of your application.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::BLOG], 'screenshotDark' => $url . '/images/sites/templates/logspot-dark.png', 'screenshotLight' => $url . '/images/sites/templates/logspot-light.png', @@ -290,6 +324,8 @@ return [ [ 'key' => 'astro-nano', 'name' => 'Astro Nano', + 'tagline' => 'Minimal personal website to showcase your projects, articles, and more.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::PORTFOLIO], 'screenshotDark' => $url . '/images/sites/templates/astro-nano-dark.png', 'screenshotLight' => $url . '/images/sites/templates/astro-nano-light.png', @@ -309,6 +345,8 @@ return [ [ 'key' => 'astro-starlight', 'name' => 'Astro Starlight', + 'tagline' => 'Platform for documentation and knowledge sharing powered by Astro.', + 'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::DOCUMENTATION], 'screenshotDark' => $url . '/images/sites/templates/astro-starlight-dark.png', 'screenshotLight' => $url . '/images/sites/templates/astro-starlight-light.png', @@ -328,6 +366,8 @@ return [ [ 'key' => 'astro-sphere', 'name' => 'Astro Sphere', + 'tagline' => 'Modern personal website to showcase your projects, articles, and more.', + 'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::PORTFOLIO], 'screenshotDark' => $url . '/images/sites/templates/astro-sphere-dark.png', 'screenshotLight' => $url . '/images/sites/templates/astro-sphere-light.png', @@ -347,6 +387,8 @@ return [ [ 'key' => 'astro-starlog', 'name' => 'Astro Starlog', + 'tagline' => 'Platform for publishing written content and media powered by Astro.', + 'score' => 5, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::BLOG], 'screenshotDark' => $url . '/images/sites/templates/astro-starlog-dark.png', 'screenshotLight' => $url . '/images/sites/templates/astro-starlog-light.png', @@ -366,6 +408,8 @@ return [ [ 'key' => 'onelink', 'name' => 'Onelink', + 'tagline' => 'Personal website for creators to merge all URLs to social profiles.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::PORTFOLIO], 'screenshotDark' => $url . '/images/sites/templates/onelink-dark.png', 'screenshotLight' => $url . '/images/sites/templates/onelink-light.png', @@ -387,6 +431,8 @@ return [ 'key' => 'starter-for-flutter', 'name' => 'Flutter starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple Flutter application integrated with Appwrite SDK.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-flutter-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-flutter-light.png', 'frameworks' => [ @@ -430,6 +476,8 @@ return [ 'key' => 'starter-for-js', 'name' => 'JavaScript starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple JavaScript application integrated with Appwrite SDK.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-js-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-js-light.png', 'frameworks' => [ @@ -472,6 +520,8 @@ return [ 'key' => 'starter-for-angular', 'name' => 'Angular starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple Angular application integrated with Appwrite SDK.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-angular-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-angular-light.png', 'frameworks' => [ @@ -516,6 +566,8 @@ return [ 'key' => 'starter-for-svelte', 'name' => 'Svelte starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple Svelte application integrated with Appwrite SDK.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-svelte-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-svelte-light.png', 'frameworks' => [ @@ -558,6 +610,8 @@ return [ 'key' => 'starter-for-react', 'name' => 'React starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple React application integrated with Appwrite SDK.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-react-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-react-light.png', 'frameworks' => [ @@ -600,6 +654,8 @@ return [ 'key' => 'starter-for-vue', 'name' => 'Vue starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple Vue application integrated with Appwrite SDK.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-vue-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-vue-light.png', 'frameworks' => [ @@ -642,6 +698,8 @@ return [ 'key' => 'starter-for-react-native', 'name' => 'React Native starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple React Native application integrated with Appwrite SDK.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-react-native-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-react-native-light.png', 'frameworks' => [ @@ -685,6 +743,8 @@ return [ 'key' => 'starter-for-nextjs', 'name' => 'Next.js starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple Next.js application integrated with Appwrite SDK.', + 'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-nextjs-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-nextjs-light.png', 'frameworks' => [ @@ -727,6 +787,8 @@ return [ 'key' => 'starter-for-nuxt', 'name' => 'Nuxt starter', 'useCases' => [UseCases::STARTER], + 'tagline' => 'Simple Nuxt application integrated with Appwrite SDK.', + 'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'screenshotDark' => $url . '/images/sites/templates/starter-for-nuxt-dark.png', 'screenshotLight' => $url . '/images/sites/templates/starter-for-nuxt-light.png', 'frameworks' => [ @@ -768,6 +830,8 @@ return [ [ 'key' => 'template-for-event', 'name' => 'Event template', + 'tagline' => 'Hackathon landing page with support for project submissions.', + 'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::EVENTS], 'screenshotDark' => $url . '/images/sites/templates/template-for-event-dark.png', 'screenshotLight' => $url . '/images/sites/templates/template-for-event-light.png', @@ -804,6 +868,8 @@ return [ [ 'key' => 'template-for-portfolio', 'name' => 'Portfolio template', + 'tagline' => 'Simple personal website to showcase your projects, articles, and more.', + 'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::PORTFOLIO], 'screenshotDark' => $url . '/images/sites/templates/template-for-portfolio-dark.png', 'screenshotLight' => $url . '/images/sites/templates/template-for-portfolio-light.png', @@ -821,6 +887,8 @@ return [ [ 'key' => 'template-for-store', 'name' => 'Store template', + 'tagline' => 'E-commerce platform for selling products with Stripe integration.', + 'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::ECOMMERCE], 'screenshotDark' => $url . '/images/sites/templates/template-for-store-dark.png', 'screenshotLight' => $url . '/images/sites/templates/template-for-store-light.png', @@ -863,6 +931,8 @@ return [ [ 'key' => 'template-for-blog', 'name' => 'Blog template', + 'tagline' => 'Platform for publishing written content and media.', + 'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::BLOG], 'screenshotDark' => $url . '/images/sites/templates/template-for-blog-dark.png', 'screenshotLight' => $url . '/images/sites/templates/template-for-blog-light.png', @@ -880,6 +950,8 @@ return [ [ 'key' => 'astro-starter', 'name' => 'Astro starter', + 'tagline' => 'Sample application built with Astro, a content-driven web framework.', + 'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::STARTER], 'screenshotDark' => $url . '/images/sites/templates/astro-starter-dark.png', 'screenshotLight' => $url . '/images/sites/templates/astro-starter-light.png', @@ -897,6 +969,8 @@ return [ [ 'key' => 'remix-starter', 'name' => 'Remix starter', + 'tagline' => 'Sample application built with Remix, a React meta-framework.', + 'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible) 'useCases' => [UseCases::STARTER], 'screenshotDark' => $url . '/images/sites/templates/remix-starter-dark.png', 'screenshotLight' => $url . '/images/sites/templates/remix-starter-light.png', diff --git a/app/controllers/general.php b/app/controllers/general.php index 87a9c420c7..5ce0a03471 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -269,7 +269,8 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $resource->getAttribute('runtime', '') . '" is not supported'); } - if ($deployment->getAttribute('status') !== 'ready') { + $allowAnyStatus = !\is_null($apiKey) && $apiKey->isDeploymentStatusIgnored(); + if (!$allowAnyStatus && $deployment->getAttribute('status') !== 'ready') { if ($deployment->getAttribute('status') === 'failed') { throw new AppwriteException(AppwriteException::BUILD_FAILED); } else { diff --git a/app/views/general/404.phtml b/app/views/general/404.phtml index 24ce8c67b3..5e63344c8a 100644 --- a/app/views/general/404.phtml +++ b/app/views/general/404.phtml @@ -7,6 +7,8 @@ 404 Not Found