analyzer
Este pacote fornece uma biblioteca que realiza análise estática de código Dart.
Um motor de blog moderno e responsivo construído com Jaspr e Dart.
Este pacote fornece uma biblioteca que realiza análise estática de código Dart.
Um framework web moderno para criar sites em Dart que se sente como Flutter, mas com suporte a renderização do lado do servidor.
Um pacote para criar geradores de código compatíveis com o build_runner.
Implementações de Builder que envolvem os compiladores dart2js e DDC.
Construtores e utilitários de geração de código-fonte para o sistema de compilação do Dart
Uma biblioteca para realizar globbing de arquivos e diretórios no estilo Bash.
Uma coleção de utilitários para transformar e manipular fluxos.
Regras oficiais de análise de código do Dart. Define o conjunto 'core' e 'recomendado' de análises sugeridas pela equipe do Dart.
Integração do Tailwind para o Jaspr.
Utilitários para ajudar na geração de código-fonte do Dart. Inclui utilitários para gerar literais de string corretamente a partir de qualquer valor de string.
Um gerador de IDs de string pequeno, seguro, amigável a URLs e exclusivo, com uma API pura em Dart.
^0.17.1^0.6.1^0.3.7^7.3.0^1.9.0^3.1.2^1.11.0^1.18.0^0.6.7^0.19.0^1.5.0^2.1.2^3.0.3^2.1.0^2.0.1{"path":"plugins/writesync_lukehog"}^2.4.1^2.4.8^4.1.0^0.17.0^0.2.0^3.0.0^0.3.1^1.3.4^6.2.0Texto original em inglês. Visite o GitHub para a versão atual.
A modern, responsive blog engine built with Jaspr and Dart.
git clone https://github.com/tayormi/writesync.git
cd writesync
dart pub get
Configure plugins:
config/plugins/lukehog_analytics.yaml:name: lukehog_analytics
enabled: true
options:
projectId: 'your-lukehog-project-id'
debug: false
automaticPageviews: true
Run the development server:
jaspr serve
Responsive design optimized for mobile devices
WriteSync comes with built-in support for Lukehog Analytics, providing seamless event tracking and user analytics.
Configure analytics in config/plugins/lukehog_analytics.yaml:
name: lukehog_analytics
enabled: true
development_only: false
options:
projectId: '${LUKEHOG_PROJECT_ID}'
debug: false
automaticPageviews: true
automaticErrorTracking: true
sessionExpiration: 1800 # 30 minutes in seconds
events:
pageView:
enabled: true
properties:
- url
- title
- referrer
- deviceType
- browserInfo
error:
enabled: true
properties:
- message
- stackTrace
- errorType
- url
interaction:
enabled: true
properties:
- elementId
- elementType
- action
- value
retry:
maxAttempts: 3
initialDelay: 1000
maxDelay: 5000
batch:
enabled: true
maxSize: 10
flushInterval: 30000
storage:
prefix: 'lh_'
maxItems: 1000
maxAge: 604800
Track events in your components using the MonitoringMixin:
class MyComponent extends StatefulComponent {
@override
State<MyComponent> createState() => _MyComponentState();
}
class _MyComponentState extends State<MyComponent> with MonitoringMixin {
void _handleClick() {
trackComponentInteraction(
'button',
'click',
properties: {'action': 'submit'},
);
}
Future<void> _loadData() async {
await trackOperation(
'loadData',
() async {
// Your async operation here
},
);
}
}
WriteSync features a powerful plugin system that allows you to extend functionality. Here's how to install and configure plugins:
pubspec.yaml:dependencies:
writesync_lukehog:
path: plugins/writesync_lukehog # For local plugins
# or
git:
url: https://github.com/yourusername/writesync-lukehog.git # For git-hosted plugins
config/plugins/:# config/plugins/your_plugin.yaml
name: your_plugin
enabled: true
development_only: false # Set to true for development-only plugins
options:
# Plugin-specific options here
key: value
import 'package:writesync_plugin/writesync_plugin.dart';
void main() {
// Register the plugin
final registry = context.read(pluginRegistryProvider);
await registry.registerPlugin(YourPlugin());
// Run your app
runApp(const App());
}
WriteSync supports several types of plugins:
Analytics Plugins
class CustomAnalyticsPlugin extends AnalyticsPlugin {
@override
void trackEvent(String name, {Map<String, dynamic>? properties}) {
// Implementation
}
}
Content Processor Plugins
class CustomProcessorPlugin extends ContentProcessorPlugin {
@override
Future<String> processMarkdown(String content) async {
// Implementation
}
}
Asset Processor Plugins
class CustomAssetPlugin extends AssetProcessorPlugin {
@override
Future<List<int>> processAsset(String path, List<int> content) async {
// Implementation
}
}
Search Plugins
class CustomSearchPlugin extends SearchPlugin {
@override
Future<List<String>> search(String query) async {
// Implementation
}
}
Plugins are configured using YAML files in the config/plugins/ directory:
config/plugins.yaml):plugins:
my_plugin:
enabled: true
config_path: 'plugins/my_plugin.yaml'
options:
key: value
config/plugins/my_plugin.yaml):name: my_plugin
enabled: true
development_only: false
options:
# Plugin-specific options here
apiKey: 'your-api-key'
debug: false
customOption: 'value'
This configuration approach provides:
Plugins follow a lifecycle that you can hook into:
class MyPlugin extends WriteSyncPlugin {
@override
Future<void> initialize(PluginContext context) async {
// Called when the plugin is registered
}
@override
Future<void> onBeforeBuild() async {
// Called before the build process starts
}
@override
Future<void> onAfterBuild() async {
// Called after the build process completes
}
@override
Future<void> dispose() async {
// Called when the plugin is being disposed
}
}
Configuration Validation
class MyPluginSchema extends PluginSchema {
@override
List<PluginOptionSchema> get options => [
PluginOptionSchema(
name: 'apiKey',
type: String,
required: true,
validators: [
PatternValidator(
pattern: RegExp(r'^[A-Za-z0-9_-]+$'),
message: 'Invalid API key format',
),
],
),
];
}
Error Handling
try {
// Plugin operations
} catch (e) {
throw PluginException('Operation failed', e);
}
Resource Management
@override
Future<void> dispose() async {
// Clean up resources
await _client?.close();
_cache.clear();
}
All site-wide configurations are managed in a single file: lib/config/site_config.dart. Here are the key configuration areas:
class SiteConfig {
// Site Information
static const String siteName = 'WriteSync';
static const String siteDescription = 'WriteSync is a platform for writing and sharing your thoughts.';
static const String siteAuthor = 'Your Name';
// Blog Display Configuration
static const Map<String, bool> blogDisplay = {
'showAuthor': false,
'showAuthorImage': true,
'showDate': true,
'showTags': true,
};
}
static const Map<String, dynamic> featuredPost = {
'strategy': 'tag', // Options: 'tag', 'latest', 'manual'
'tag': 'featured', // Tag to use when strategy is 'tag'
'manualSlug': '', // Slug to use when strategy is 'manual'
'fallbackToLatest': true, // Use latest post if no featured post found
};
Featured post strategies:
// Blog Configuration
static const int postsPerPage = 6; // Number of posts per page
static const bool enablePagination = true;
The pagination system:
static const Map<String, dynamic> analytics = {
'enabled': true, // Master switch for analytics
'googleAnalytics': {
'enabled': true, // GA-specific switch
'measurementId': 'G-XXXXXXXXXX', // Your GA4 measurement ID
'sendPerformanceMetrics': true, // Send Web Vitals data
'debugMode': false, // Enable debug logging
'customEvents': {
'enabled': true, // Enable custom event tracking
'trackPageViews': true, // Track page views
'trackClicks': true, // Track user interactions
'trackErrors': true, // Track errors
'trackNavigation': true, // Track navigation events
'trackSearch': true, // Track search events
},
'customDimensions': {
'environment': 'production', // Custom dimensions for all events
'version': '1.0.0',
'theme': 'auto',
},
},
};
The analytics system provides:
Web Vitals Tracking:
Custom Event Tracking:
final monitor = context.read(performanceMonitorProvider);
// Track custom events
monitor.trackEvent(
'button_click',
category: 'UI',
label: 'Submit Form',
properties: {'form_id': 'contact'},
);
// Track page views
monitor.trackPageView(
title: 'Home Page',
properties: {'section': 'blog'},
);
// Track user interactions
monitor.trackInteraction(
'button',
'click',
category: 'Navigation',
);
// Track search events
monitor.trackSearch(
'dart patterns',
resultsCount: 5,
);
// Track errors
monitor.trackError(
'Failed to load post',
type: 'NetworkError',
stackTrace: stackTrace,
);
Enhanced Properties:
Debug Mode:
Configuration:
measurementId with your GA4 IDCustom Event Tracking:
final monitor = context.read(performanceMonitorProvider);
// Basic event
monitor.trackEvent('event_name');
// Event with properties
monitor.trackEvent(
'event_name',
properties: {'key': 'value'},
category: 'category',
label: 'label',
value: 1.0,
);
Automatic Tracking:
Debug Mode: Enable debug mode in configuration:
'debugMode': true,
This will log all events to the console with detailed information.
Create a new markdown file in lib/posts/ directory
Add front matter at the top of your markdown file:
---
title: Your Post Title
slug: your-post-slug
date: 2024-02-25
tags: [tag1, tag2, tag3]
description: A brief description of your post
author: Your Name
image: https://url-to-your-header-image.jpg
author_image: https://url-to-your-profile-image.jpg
metadata:
readTime: 5 min
title: Custom SEO Title (optional)
description: Custom SEO Description (optional)
keywords: custom, seo, keywords (optional)
ogImage: Custom social share image URL (optional)
---
Your post content here...
dart run build_runner build
Update the theme colors in lib/config/site_config.dart:
static const Map<String, String> colors = {
'primary': 'indigo-600',
'primary-light': 'indigo-400',
'primary-dark': 'indigo-700',
};
Customize layout settings:
static const Map<String, String> layout = {
'maxWidth': 'max-w-7xl',
'containerPadding': 'px-4 sm:px-6 lg:px-8',
'sectionPadding': 'py-12',
'headerHeight': 'h-16',
};
Enable/disable features:
static const bool enableDarkMode = true;
static const bool enableSearch = true;
static const bool enableTags = true;
static const bool enablePagination = true;
static const bool enableSocialSharing = true;
jaspr build
build directory. Deploy these files to your web server.WriteSync comes with built-in SEO optimization:
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
If you find WriteSync helpful, please consider giving it a star ⭐️
For issues and feature requests, please use the GitHub issue tracker.